【问题标题】:WPF - ObservableCollection<object> DPWPF - ObservableCollection<object> DP
【发布时间】: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 作为后台逻辑。

标签: c# wpf mvvm


【解决方案1】:

经过 3 天的搜索和这篇 StackOverflow 帖子,我终于找到了错误。我的 PageControl 有他自己的 ViewModel (DataContext),因此 MainWindow.xaml(或任何包含 PageControl 的控件)中的绑定无法正确绑定 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}}" />

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2011-04-10
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多