Search code examples
c#wpfmvvm-lightobservablecollectionxamdatagrid

Get sorted observable collection in mvvm light


I have bound an Observable Collection to a xamDataGrid of infragistics in my MVVM-light VM. In the UI I have my grid and a button and when I click on the button I want to perform an action that updates information. This action takes quite a while and I want the data to be updated in the order displayed on the GUI. However the Observable collection is not sorted and instead, it always updates on the unsorted list. Is there a way to get the sorted list in my VM?

VM:

 public class SystemInformation : ViewModelBase
 {
    private ObservableCollection<Site> _activeSites;

    private RelayCommand _updateAllCommand;

    /// <summary>
    /// Initializes a new instance of the SystemInformation class.
    /// </summary>
    public SystemInformation() : base()
    {
        ActiveSites = new ObservableCollection<Site>();
    }


    public ObservableCollection<Site> ActiveSites
    {
        get
        {
            return _activeSites;
        }
        set
        {
            Set("ActiveSites", ref _activeSites, value);
        }
    }

    public RelayCommand UpdateAllCommand
    {
        get
        {
            return _updateAllCommand
              ?? (_updateAllCommand= new RelayCommand(
                () =>
                {
                        try
                        {
                            foreach (var site in ActiveSites)
                            {
                             // Update data
                            }
                        }
                        catch (Exception ex)
                        {
                           //Exception handling
                        }
                    });
                }
             ));
        }
    }
}

}

View:

<Grid>
    <Grid.RowDefinitions>
        <RowDefinition Height="5"/>
        <RowDefinition Height="*"/>
        <RowDefinition Height="5"/>
        <RowDefinition Height="auto"/>
        <RowDefinition Height="5"/>
    </Grid.RowDefinitions>

    <Grid.ColumnDefinitions>
        <ColumnDefinition Width="5"/>
        <ColumnDefinition Width="auto"/>
        <ColumnDefinition Width="5"/>
        <ColumnDefinition Width="*"/>
        <ColumnDefinition Width="5"/>
    </Grid.ColumnDefinitions>

    <igDP:XamDataGrid  x:Name="grdSysinfo" Grid.Row="1" Grid.Column="3"  DataSource="{Binding ActiveSites, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged }" />
     <Button Command="{Binding UpdateAllCommand}" CommandParameter="All" Grid.Row="3" Grid.Column="1">Load All</Button>
</Grid>

Solution

  • The grid doesn't sort the actual source collection, it sorts a view of it.

    If you want to be able to get the items in the order that they appear in the UI, you could bind to an ICollectionView property:

    public class SystemInformation : ViewModelBase
    {
        private ObservableCollection<Site> _activeSites;
        private RelayCommand _updateAllCommand;
    
        public SystemInformation() : base()
        {
            ActiveSites = new ObservableCollection<Site>();
            View = CollectionViewSource.GetDefaultView(ActiveSites);
        }
    
        public System.ComponentModel.ICollectionView View { get; private set; } //<-- bind to this one
    
        public ObservableCollection<Site> ActiveSites
        {
            get
            {
                return _activeSites;
            }
            set
            {
                Set("ActiveSites", ref _activeSites, value);
            }
        }
    
        public RelayCommand UpdateAllCommand
        {
            get
            {
                return _updateAllCommand
                  ?? (_updateAllCommand = new RelayCommand(() => 
                  {
                      foreach (var site in View.OfType<Site>())
                      {
                          //---
                      }
                  }));
            }
        }
    }
    

    <igDP:XamDataGrid ... DataSource="{Binding View}" />