Search code examples
c#wpfgroupingobservablecollectionicollectionview

Is it possible to add grouping on the index's of array column in an Observable Collection?


I have an ObservableCollection with a predefined class, Currently the ObservableCollection is displayed in a DataGrid using ICollectionView and grouped by columns sl_Id, sl_Name, sl_Date.

However i would like to know if its possible to group by the index's of sl_struct, the length of the array is determined at runtime.

public class SyncLog
{
    public string sl_ID { get; set; }
    public string sl_Name { get; set; }
    public string sl_Date { get; set; }
    public string sl_Type { get; set; }
    public string[] sl_Struct { get; set; }
    public string sl_SourceMachine { get; set; }
    public string sl_Source { get; set; }
    public string sl_DestMachine { get; set; }
    public string sl_Dest { get; set; }
    public bool sl_Success { get; set; }
    public string sl_Time { get; set; }
    public string sl_Size { get; set; }
}

current code for grouping

ICollectionView backupLogView = CollectionViewSource.GetDefaultView(Synclog);

PropertyGroupDescription group1 = new PropertyGroupDescription("sl_Id");
PropertyGroupDescription group2 = new PropertyGroupDescription("sl_Name");
PropertyGroupDescription group3 = new PropertyGroupDescription("sl_Date");

backupLogView.GroupDescriptions.Add(group1);
backupLogView.GroupDescriptions.Add(group2);
backupLogView.GroupDescriptions.Add(group3);

backupLogView.SortDescriptions.Add(new SortDescription("sl_Id", ListSortDirection.Ascending));
backupLogView.SortDescriptions.Add(new SortDescription("sl_Name", ListSortDirection.Ascending));
backupLogView.SortDescriptions.Add(new SortDescription("sl_Date", ListSortDirection.Ascending));
backupLogView.SortDescriptions.Add(new SortDescription("sl_Time", ListSortDirection.Ascending));

backupLogView.Refresh();

Solution

  • If new PropertyGroupDescription("sl_Struct.Length") doesn't work, though it probably should, you can just add another property to your SyncLog class that returns sl_Struct.Length

    public class SyncLog
    {
        public string[] sl_Struct { get; set; }
        public int sl_StructLength => sl_Struct?.Length ?? 0;
    }
    ...
    PropertyGroupDescription group = new PropertyGroupDescription("sl_StructLength ");
    

    If you can't add a property to the SyncLog class(for example, if it is some external DTO), then you should probably create a specialized SyncLogViewModel that wraps the regular SyncLog and adds the sl_StructLength

    public class SyncLogViewModel
    {
        private readonly SyncLog _syncLog;
        public SyncLogViewModel(SyncLog syncLog) =>
             _syncLog = syncLog ?? throw new ArgumentNullException(nameof(syncLog));
        public int sl_StructLength => _syncLog.sl_Struct?.Length ?? 0;
        public int sl_Struct 
        {
             get => _syncLog.sl_Struct;
             set => _syncLog.sl_Struct = value;
        }
        // Other properties...
    }