0

I have list which loading some long loading date. I can not use ObservableCollection because it can not be updated from another thread. What i need to do, because when I am using list nothing happens on UI * *

public class ListViewModel : ViewModelBase
{
    /// <summary>
    /// Initializes a new instance of the ListViewModel class.
    /// </summary>
    /// 
    private List<StructOfList> items;

    public List<StructOfList> Items 
    {
        get { return items; }
        set
        {
            items = value; 
            RaisePropertyChanged("Items");
        }
    }

    public ListViewModel()
    {
        Items = new List<StructOfList>();
        Items.Add(new StructOfList { Amount = 10, FirstName = "Test", SecondName = "Test" });
        AsyncDataLoad();
    }

    public void AsyncDataLoad()
    {
        Action<List<StructOfList>> LoadData = new Action<List<StructOfList>>(AddItemToList);
        IAsyncResult result = LoadData.BeginInvoke(Items, null, null);
    }

    public void AddItemToList(List<StructOfList> items)
    {
        for (int i = 0; i < 10; i++)
        {
            System.Threading.Thread.Sleep(300);
            items.Add(new StructOfList {FirstName = "First" , SecondName = "Second" , Amount = i});
            RaisePropertyChanged("Items");
        }
    }
}

Xaml code goes gere

<Grid>
    <ListView ItemsSource="{Binding Items}">
        <ListView.ItemTemplate>
            <DataTemplate>
                <Grid>
                    <Grid.ColumnDefinitions>
                        <ColumnDefinition></ColumnDefinition>
                        <ColumnDefinition></ColumnDefinition>
                    </Grid.ColumnDefinitions>
                    <Label Content="{Binding FirstName}" Grid.Column="0"></Label>
                    <Label Content="{Binding SecondName}" Grid.Column="1"></Label>
                </Grid>
            </DataTemplate>
        </ListView.ItemTemplate>
    </ListView>
</Grid>
2
  • This answer may be helpful. Commented Jul 24, 2015 at 15:28
  • Do your long operation, then update the UI on the UI thread. The UI can't observe a List, hence nothing works. Calling RaisePropertyChange("Items") won't help as the ListView will see the object hasn't actually changed and ignore it. Commented Jul 24, 2015 at 15:44

2 Answers 2

3

You can use an ObservableCollection as long as the update happens on the UI thread. Since all you have is an async function doing only non-conflicting transactions such as sequential adding, there should be no problem using Dispatcher to apply changes as they happen to the ObservableCollection:

public void AddItemToList()
{
    for (int i = 0; i < 10; i++)
    {
        System.Threading.Thread.Sleep(300);

        var AddItem = new Action(() => items.Add(new StructOfList { FirstName = "First", SecondName = "Second", Amount = i });
        Application.Current.Dispatcher.Invoke(DispatcherPriority.Background, AddItem);
    }
}
Sign up to request clarification or add additional context in comments.

Comments

0

A few things:

You do not need to have RaisePropertyChanged on your Items property since the Items object only gets updated once (in the CTOR).

You should be using async/await to perform the async data load.

You should also be using an OverservableCollection since your list will be updating items.

For example:

public class ListViewModel : ViewModelBase
{
    public ObservableCollection<StructOfList> Items 
    {
        get; private set;
    }

    public ListViewModel()
    {
        Items = new ObservableCollection<StructOfList>();
        Items.Add(new StructOfList { Amount = 10, FirstName = "Test", SecondName = "Test" });
        AsyncDataLoad();
    }

    public void async AsyncDataLoad()
    {
        await Task.Run(()=> AddItemsToList());
    }

    public void AddItemsToList()
    {
        for (int i = 0; i < 10; i++)
        {
            Application.Current.Dispatcher.Invoke(() => Items.Add(new StructOfList {FirstName = "First" , SecondName = "Second" , Amount = i}));
        }
    }
}

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.