WPF - ObservableCollection <object> DP

时间:2017-09-10 14:09:39

标签: c# wpf mvvm

我打算创建一个Pager Control来将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

XAML中的PagerControl用法

<DataGrid ItemSource={Binding ElementName=Pager, Path=RestrictedItemSource} />
<Pager x:Name="Pager" ItemSource={Binding Collection} />

XAML viewModel

public ObservableCollection<Class> Collection { get; set; } = new ...();

public ViewModel()
{
    Collection.Add(x);
    Collection.Add(y);
    Collection.Add(z);
}

注意:代码片段来自我的头脑。

1 个答案:

答案 0 :(得分:-1)

经过3天的搜索和StackOverflow帖子后,我终于找到了错误。我的PageControl有自己的ViewModel(DataContext),因此,MainWindow.xaml中的绑定(或包含PageControl的Control中的绑定)无法正确绑定ItemSource,因为PageControl的DataContext是他自己的。

通过以下更改完美运行

<DataGrid ItemSource={Binding ElementName=Pager, Path=RestrictedItemSource} />
<Pager x:Name="Pager" ItemSource={Binding Path=DataContext.Collection, RelativeSource={RelativeSource Mode=Find, AncestorType=UserControl}}" />