DynamicData - 如何绑定到分组数据
DynamicData - How to bind to grouped data
我正在使用 Roland Pheasant 的 DynamicData。
我想将我的普通 C# 集合转换为 Rx。
来自
ObservableCollection<Grouping<string, DisplayItem>>
到动态数据格式
ReadOnlyObservableCollection<IGroup<DisplayItem, string>>
或
ReadOnlyObservableCollection<IGroup<DisplayItem, string, string>>
用于缓存源。
目前我的 xaml 将如下所示以正常绑定 ObservableCollection<Grouping<string, DisplayItem>>
<CollectionViewSource
x:Name="GroupedDataCollection"
Source="{x:Bind ViewModel.bindingData_grouped, Mode=OneWay}"
IsSourceGrouped="True" />
<ListView
Margin="16,0"
ItemsSource="{x:Bind GroupedDataCollection.View , Mode=OneWay}"
SelectionMode="None">
<ListView.GroupStyle>
<GroupStyle HidesIfEmpty="False">
<GroupStyle.HeaderTemplate>
<DataTemplate>
<TextBlock FontSize="14"
FontWeight="SemiBold"
Text="{Binding Key }" />
</DataTemplate>
</GroupStyle.HeaderTemplate>
</GroupStyle>
</ListView.GroupStyle>
<ListView.ItemTemplate >
<DataTemplate x:DataType="viewmodels:DisplayItem">
<StackPanel>
<TextBlock FontSize="14"
FontWeight="SemiBold"
Text="{x:Bind Description }" />
</StackPanel>
</DataTemplate>
</ListView.ItemTemplate>
</ListView>
型号:
public class DisplayItem {
public string ID { get; set; } = Guid.NewGuid().ToString();
public string Type { get; set; } = string.Empty;
public string Description { get; set; } = string.Empty;
public double? Price { get; set; } = 0; }
现有的 c# Observable 集合结果:
动态数据代码:
public ReadOnlyObservableCollection<IGroup<DisplayItem, string>> bindingData_grouped;
var myBindingOperation_grouped = Data.ToObservableChangeSet()
.GroupOn(x => x.Type)
.ObserveOn(RxApp.MainThreadScheduler)
.Bind(out bindingData_grouped)
.Subscribe();
如果我绑定到 ReadOnlyObservableCollection<IGroup<DisplayItem, string>>
或 ReadOnlyObservableCollection<IGroup<DisplayItem, string, string>>
,则使用上面的代码我的列表视图不显示任何内容。
如何使用 "CollectionViewSource" 从 xaml 列表视图绑定到
ReadOnlyObservableCollection<IGroup<DisplayItem, string>>
或
ReadOnlyObservableCollection<IGroup<DisplayItem, string, string>>
提前致谢。
我是 DynamicData 的新手,所以我可能会重新实现库中已经存在的东西,但这是我想出的:
// custom IGrouping implementation which is required by ListView
public class Grouping<TKey, TElement> : ObservableCollectionExtended<TElement>, IGrouping<TKey, TElement>
{
public Grouping(IGroup<TElement, TKey> group)
{
if (group == null)
{
throw new ArgumentNullException(nameof(group));
}
Key = group.GroupKey;
group.List.Connect().Bind(this).Subscribe();
}
public TKey Key { get; private set; }
}
// this.Ints is an ObservableCollection<int> which I manipulate thru UI
this.Ints
.ToObservableChangeSet()
.GroupOn(i => (int)(i / 10)) // group by 10s
.Transform(group => new Grouping<int, int>(group)) // transform DynamicData IGroup into our IGrouping implementation
.Sort(SortExpressionComparer<Grouping<int, int>>.Ascending(t => t.Key)) // sort by keys
.ObserveOnDispatcher()
.Bind(this.GroupedInts) // this.GroupedInts is used as binding source for CollectionViewSource in UI
.Subscribe();
private ObservableCollectionExtended<Grouping<int, int>> GroupedInts { get; } = new ObservableCollectionExtended<Grouping<int, int>>();
基本上,您需要 ListView (CollectionViewSource) 的分组机制所需的 IGrouping 接口的自定义实现。您向它传递一个 IGroup 实例(来自 DynamicData 的 GroupOn
方法)。在构造函数中,您将 Connect() 连接到组的 ReactiveList 并将其绑定到 Grouping
本身。
我正在使用 Roland Pheasant 的 DynamicData。
我想将我的普通 C# 集合转换为 Rx。
来自
ObservableCollection<Grouping<string, DisplayItem>>
到动态数据格式
ReadOnlyObservableCollection<IGroup<DisplayItem, string>>
或
ReadOnlyObservableCollection<IGroup<DisplayItem, string, string>>
用于缓存源。
目前我的 xaml 将如下所示以正常绑定 ObservableCollection<Grouping<string, DisplayItem>>
<CollectionViewSource
x:Name="GroupedDataCollection"
Source="{x:Bind ViewModel.bindingData_grouped, Mode=OneWay}"
IsSourceGrouped="True" />
<ListView
Margin="16,0"
ItemsSource="{x:Bind GroupedDataCollection.View , Mode=OneWay}"
SelectionMode="None">
<ListView.GroupStyle>
<GroupStyle HidesIfEmpty="False">
<GroupStyle.HeaderTemplate>
<DataTemplate>
<TextBlock FontSize="14"
FontWeight="SemiBold"
Text="{Binding Key }" />
</DataTemplate>
</GroupStyle.HeaderTemplate>
</GroupStyle>
</ListView.GroupStyle>
<ListView.ItemTemplate >
<DataTemplate x:DataType="viewmodels:DisplayItem">
<StackPanel>
<TextBlock FontSize="14"
FontWeight="SemiBold"
Text="{x:Bind Description }" />
</StackPanel>
</DataTemplate>
</ListView.ItemTemplate>
</ListView>
型号:
public class DisplayItem {
public string ID { get; set; } = Guid.NewGuid().ToString();
public string Type { get; set; } = string.Empty;
public string Description { get; set; } = string.Empty;
public double? Price { get; set; } = 0; }
现有的 c# Observable 集合结果:
动态数据代码:
public ReadOnlyObservableCollection<IGroup<DisplayItem, string>> bindingData_grouped;
var myBindingOperation_grouped = Data.ToObservableChangeSet()
.GroupOn(x => x.Type)
.ObserveOn(RxApp.MainThreadScheduler)
.Bind(out bindingData_grouped)
.Subscribe();
如果我绑定到 ReadOnlyObservableCollection<IGroup<DisplayItem, string>>
或 ReadOnlyObservableCollection<IGroup<DisplayItem, string, string>>
,则使用上面的代码我的列表视图不显示任何内容。
如何使用 "CollectionViewSource" 从 xaml 列表视图绑定到
ReadOnlyObservableCollection<IGroup<DisplayItem, string>>
或
ReadOnlyObservableCollection<IGroup<DisplayItem, string, string>>
提前致谢。
我是 DynamicData 的新手,所以我可能会重新实现库中已经存在的东西,但这是我想出的:
// custom IGrouping implementation which is required by ListView
public class Grouping<TKey, TElement> : ObservableCollectionExtended<TElement>, IGrouping<TKey, TElement>
{
public Grouping(IGroup<TElement, TKey> group)
{
if (group == null)
{
throw new ArgumentNullException(nameof(group));
}
Key = group.GroupKey;
group.List.Connect().Bind(this).Subscribe();
}
public TKey Key { get; private set; }
}
// this.Ints is an ObservableCollection<int> which I manipulate thru UI
this.Ints
.ToObservableChangeSet()
.GroupOn(i => (int)(i / 10)) // group by 10s
.Transform(group => new Grouping<int, int>(group)) // transform DynamicData IGroup into our IGrouping implementation
.Sort(SortExpressionComparer<Grouping<int, int>>.Ascending(t => t.Key)) // sort by keys
.ObserveOnDispatcher()
.Bind(this.GroupedInts) // this.GroupedInts is used as binding source for CollectionViewSource in UI
.Subscribe();
private ObservableCollectionExtended<Grouping<int, int>> GroupedInts { get; } = new ObservableCollectionExtended<Grouping<int, int>>();
基本上,您需要 ListView (CollectionViewSource) 的分组机制所需的 IGrouping 接口的自定义实现。您向它传递一个 IGroup 实例(来自 DynamicData 的 GroupOn
方法)。在构造函数中,您将 Connect() 连接到组的 ReactiveList 并将其绑定到 Grouping
本身。