1
votes

My grid:

<dxg:GridControl x:Name="StatisticsGridLevel1"
                 dx:ThemeManager.ThemeName="Office2013"
                 DataContext="{Binding FooViewModel}"
                 ItemsSource="{Binding FooCollection}">

ViewModel:

private List<FooDto> fooCollection = new List<FooDto>();
public List<FooDto> FooCollection
{
    get
    {
        return this.fooCollection;
    }

    private set
    {
        this.fooCollection = value;
        this.NotifyPropertyChanged();
    }
}

And example method:

private void Foo()
{
    foreach (var element in collection)
    {
        this.fooCollection.Add(new FooDto()
        {
            X = element.Foo1,
            Y = element.Foo2,
            Z = element.Foo3
        });
    }
    this.NotifyPropertyChanged("FooCollection");
}

When I use ObservableCollection, everything works fine. But I want to use the List (that's not to notify in the loop).

The view refreshes after the start scroll on the grid. What is the problem?

1
Why can't you stick with ObservableCollection? The grid is not going to update automatically when the collection is modified unless the collection implements INotifyCollectionChanged. ObservableCollection implements that interface List does not. - Jason Boyd
Because I add to the collection a lot of items. I want to refresh the grid (manually invoke Notify) after finishing the loop. - WymyslonyNick
Okay, so I get that but I don't really understand your question. What does this mean: 'The view refreshes after the start scroll wheel on the grid'? What is the start scroll wheel? Are you referring to the mouse wheel? Are you handling the mouse wheel event. If so then that sounds like it may be pertinent to the question and you should show the code. It sounds like you are saying the view is still refreshing in Foo despite the fact that you are using a List instead of an ObservableCollection? Is that right? - Jason Boyd
No :) In the first step - I create List<FooDto> FooCollection with default values. The values are displayed correctly in the grid. In the second step - I call Update() method. Update cleaning collection and adding new items. FooCollection.Clear(); FooCollection.Add(...) // Element 1 ... FooCollection.Add(...) // Element 50000 this.NotifyPropertyChanged("FooCollection"); Grid displays the old values. I click on the scroll in the grid (with old values) or click on the column (sort) - grid is already showing correct data. - WymyslonyNick

1 Answers

0
votes

I think a CollectionViewSource would work in your case. There are a lot of ways to go about creating one, in XAML, in your ViewModel, in your View's code-behind. I will throw together the easiest one for demonstration purposes which is creating a CollectionViewSource property on your ViewModel. I think some people might not necessarily like this approach - it kind of has the feel of mixing concerns. I am not sure I agree, though. If you take the position that a CollectionViewSource is an object model for a collection's view then I don't see anything wrong with having it in your ViewModel. But I think because it inherits from DependencyObject it gets stigmatized as being more of a view concern. Anyway, something like this would do what you want:

// Assuming this is your constructor
public ViewModel()
{
    this.FooViewSource.Source = this.fooCollection;
}

private readonly List<FooDto> fooCollection = new List<FooDto>();

private readonly CollectionViewSource fooViewSource;
public CollectionViewSource FooViewSource
{
    get { return this.fooViewSource; }
}

private void Foo()
{
    foreach (var element in collection)
    {
        this.fooCollection.Add(new FooDto()
        {
            X = element.Foo1,
            Y = element.Foo2,
            Z = element.Foo3
        });
    }
    this.FooViewSource.View.Refresh();
}

Then you would bind your ItemsSource property to the FooViewSource property of your ViewModel. A CollectionViewSource is pretty handy for other things as well. It supports sorting, filtering, selected items, maybe some other things I am forgetting.