【发布时间】:2017-09-10 14:09:38
【问题描述】:
我打算创建一个寻呼机控件来将 ObservableCollection(具有各种类型)限制为定义的数量。因此,我使用以下 DP 创建了一个 UserControl:
public static readonly DependencyProperty ItemSourceProperty = DependencyProperty.Register("ItemSource", typeof(ObservableCollection<object>), typeof(PagerControl),new PropertyMetadata(null, ItemSourceChanged));
private static void ItemSourceChanged(DependencyObject sender, DependencyPropertyChangedEventArgs e)
{
PageControl pageControl = (PageControl)sender;
PageControlViewModel viewModel = ((PageControlViewModel)pageControl.DataContext;
viewModel.SetItemSource(e.NewValue);
}
public ObservableCollection<object> ItemSource
{
get => (cast..)GetValue(ItemSourceProperty);
set => SetValue(ItemSourceProperty, value);
}
我的想法是,在 ItemSource 更改后,我的 viewModel 收到新的 Collection 并能够注册以下事件
public void SetItemSource(ObservableCollection<object> itemSource)
{
this.ItemSource = itemSource;
this.ItemSource.CollectionChanged += doStuff;
}
doStuff 执行以下操作:ItemSource.Skip().Take() 并将其绑定到其他 ObservableCollection,DataGrids 可以使用哪个。
到目前为止一切顺利,但我遇到了以下问题。 ItemSourceChanged 总是被调用(只要我绑定它),并且 ItemSource DP 已经有一个实例,而不是定义的默认值 null。它总是有一个实例。如果我将 PagerControl 的 ItemSource 绑定到具有某些值的 ObservableCollection,则 ItemSourceChanged 根本没有条目,此外,它与我绑定的对象不同。因此,当原始 ObservableCollection 收到一些新条目时,永远不会调用 CollectionChanged。
PagerControl 在 XAML 中的用法
<DataGrid ItemSource={Binding ElementName=Pager, Path=RestrictedItemSource} />
<Pager x:Name="Pager" ItemSource={Binding Collection} />
XAML 视图模型
public ObservableCollection<Class> Collection { get; set; } = new ...();
public ViewModel()
{
Collection.Add(x);
Collection.Add(y);
Collection.Add(z);
}
注意:代码 sn-ps 来自我的头顶。
【问题讨论】:
-
通常分页的实现不涉及更改原始项目源。它只是一种显示机制。因此,我建议您像使用任何其他控件一样使用您的 itemsource,并且只实现值的分页显示。这是我通过快速谷歌搜索找到的示例powerobjects.com/2013/02/19/wpf-paging-control-wpf-applications
-
是的,这也是我正在考虑的事情。但这并不能解决我的问题 :) 即使采用这种方法,我也面临同样的问题。
-
也许我只是看错了,但在我看来你创建了一个循环。更改
ItemsSource最终会再次设置ItemsSource属性。可以将SetItemSource中的代码包装在if中,因此只有在指定的itemSource实例与当前实例不同 时才会这样做。 -
SetItemSource 在 PagerControl 的 ViewModel 中。所以与 ItemSource DP 无关。我使用 ViewModel 作为后台逻辑。