Home > Mobile >  How to refresh XAML view in MAUI?
How to refresh XAML view in MAUI?

Time:12-28

I'm making an app where I have layouts generate dynamically based on a list.

<StackLayout>
        <CollectionView x:Name="taskList">
            <CollectionView.ItemTemplate>
                <DataTemplate x:DataType="models:Task">
                    <VerticalStackLayout Margin="15">
                        <Entry Text="{Binding name}" IsReadOnly="True" />
                        <Entry Text="{Binding departmentsString}" IsReadOnly="True"/>
                        <HorizontalStackLayout>
                            <Entry Text="{Binding status}" IsReadOnly="True"/>
                            <Entry Text="{Binding deadline}" IsReadOnly="True" />
                            <Entry Text="{Binding author.fullName}" IsReadOnly="True"/>
                        </HorizontalStackLayout>
                        <Entry Text="{Binding description}" IsReadOnly="True" />
                    </VerticalStackLayout>
                </DataTemplate>
            </CollectionView.ItemTemplate>
        </CollectionView>
    </StackLayout>

The list is bonded like this:

taskList.ItemsSource = company.tasks;

I want to refresh this whenever I add new items to the list.

I tried rebinding the list to the ItemsSource but it just didn't work:

taskList.ItemsSource = company.tasks;

How should I do it? Can I just refresh the view so it generates everything again?

CodePudding user response:

You should use an IEnumerable collection that sends property change notifications(such as ObservableCollection) for the ItemsSource, then simply add to the underlying collection. Here's an example:

ObservableCollection<string> tasks = new();
taskList.ItemsSource = tasks;
tasks.Add("Do something");

Microsoft Reference

CodePudding user response:

Instead of assigning the ItemsSource from code-behind, you should bind a custom collection, which makes it much easier and decouples the UI and logic. Read more over the MVVM pattern.

(I don't have a IDE here, so it's not tested)

You could do something like:

// data class
public class TaskInfo
{
    public string name {get; set;}
    public string departmentsString {get;set;}
}

// you page/view whatever code behind the xaml
public class YourPage : // insert the class which it is derived from.
{
   // create a collection property, which generates events when changed. The UI react on these events.
   public ObservableCollection<TaskInfo> Tasks {get;} = new();

   public YourPage()
   {
      InitComponentsOrSomething();
      // assign the datacontext (which the view binds to)
      this.DataContext = this;
   }
}

And your xaml would be something like this: (mind the Binding instead of the name)

<StackLayout>
    <CollectionView ItemsSource="{Binding Tasks}">
        <CollectionView.ItemTemplate>
            <DataTemplate x:DataType="models:Task">
                <VerticalStackLayout Margin="15">
                    <Entry Text="{Binding name}" IsReadOnly="True" />
                    <Entry Text="{Binding departmentsString}" IsReadOnly="True"/>
                    <HorizontalStackLayout>
                        <Entry Text="{Binding status}" IsReadOnly="True"/>
                        <Entry Text="{Binding deadline}" IsReadOnly="True" />
                        <Entry Text="{Binding author.fullName}" IsReadOnly="True"/>
                    </HorizontalStackLayout>
                    <Entry Text="{Binding description}" IsReadOnly="True" />
                </VerticalStackLayout>
            </DataTemplate>
        </CollectionView.ItemTemplate>
    </CollectionView>
</StackLayout>

If you want to add items to the collection, just use the Tasks property:

Tasks.Add(new TaskInfo { name = "some name", departmentsString = "Enter here" });

ps: I would not call a data object 'Task', either give it a better description. TaskInfo/CompanyTask.

  • Related