Как сгруппировать данные в Observalble Collection и привязать их к DataGrid (C# + WPF)?

Имеется ObservableCollection, в которой хранятся следующие данные:
public class StatisticsModel : ObservableObject
{
	private long incomingTraffic;
	private long outcomingTraffic;
	private string time;
	
	public string Time
	{
		get { return this.time; }
		set { this.Set("Time", ref this.time, value); }
	}

	public long IncomingTraffic
	{
		get { return this.incomingTraffic; }
		set { this.Set("IncomingTraffic", ref this.incomingTraffic, value); }
	}

	public long OutcomingTraffic
	{
		get { return this.outcomingTraffic; }
		set { this.Set("OutcomingTraffic", ref this.outcomingTraffic, value); }
	}
}

Есть ViewModel, где DispatchingObservableCollection есть ничто иное, как потоко-безопасный ObservableCollection. а network.Statistics это по сути часть реализации паттерна Наблюдатель:
public class StatisticsViewModel : ViewModelBase
{
	private DispatchingObservableCollection<StatisticsModel> statisticsCollection;

	public StatisticsViewModel(INetwork network)
	{
		this.statisticsCollection = new DispatchingObservableCollection<StatisticsModel>();

		network.Service.Statistics += stats => this.StatisticsCollection.Add(Mapper.Map<StatisticsModel>(stats));
	}

	public DispatchingObservableCollection<StatisticsModel> StatisticsCollection
	{
		get { return this.statisticsCollection; }
		set { this.Set("StatisticsCollection", ref this.statisticsCollection, value); }
	}
}

А так же есть View:
<Window DataContext="{Binding Statistics, Source={StaticResource Locator}}"	...>
    <Grid>
		...
        <DataGrid ItemsSource="{Binding StatisticsCollection}">
            <DataGrid.Columns>
                <DataGridTextColumn Binding="{Binding Time}" Header="Время"/>
                <DataGridTextColumn Binding="{Binding IncomingTraffic}" Header="Входящий траффик"/>
                <DataGridTextColumn Binding="{Binding OutcomingTraffic}" Header="Исходящий траффик"/>
            </DataGrid.Columns>
        </DataGrid>
    </Grid>
</Window>

Данные с сервера приходят примерно такие:
{ Time: "00:00:01", IncomingTraffic: 100, OutcomingTraffic: 0 },
{ Time: "00:00:01", IncomingTraffic: 0, OutcomingTraffic: 100 },
{ Time: "00:00:01", IncomingTraffic: 100, OutcomingTraffic: 0 },
{ Time: "00:00:02", IncomingTraffic: 100, OutcomingTraffic: 0 },
{ Time: "00:00:02", IncomingTraffic: 0, OutcomingTraffic: 100 }

По сути, все это дело отлично группируется:
this.statisticsCollection.GroupBy(x => x.Time)
	.Select(
		y =>
		new StatisticsModel
			{
				Time = y.First().Time,
				IncomingTraffic = y.Sum(z => z.IncomingTraffic),
				OutcomingTraffic = y.Sum(z => z.OutcomingTraffic)
			});

Остается только вопрос, как эти сгруппированные данные использовать. У меня не получилось их забиндить к DataGrid. Или для данных, получаемых во время выполнения программы нужно использовать другие средства?
  • Вопрос задан
  • 3137 просмотров
Решения вопроса 1
@Sumor
Если вам нужно сгруппировать исходные данные (показать по группам). То для этого есть механизм группировки, встроенной в WPF. Пример его использования описан в MSDN. Основная суть - вы описываете описываете CollectionViewSource, который в качестве источника берёт исходные данные, а затем в CollectionViewSource указываете свойство, по которому группировать. В DataGrid на входе указывается созданный CollectionViewSource. Дополнительно можно описать шаблон представления именно группированных данных.

Если же вы хотите отображать именно список StatisticsModel. То для этого всего лишь надо в динамике присвоить свойству Source объекта DataGrid результат вашей последней конструкции this.statisticsCollection.GroupBy(...).Select(...)
Ответ написан
Пригласить эксперта
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Похожие вопросы