WPF - ObservableCollection 绑定失败 - .NET 4.0

发布于 2024-10-04 05:18:43 字数 4053 浏览 4 评论 0原文

快速摘要

  • 在我的应用程序 GUI 中的网格中没有显示项目
  • 启动时,网格中会列出正确的列(拾取的集合类型)
  • CollectionChanged 事件在网格绑定到的 ObservableCollection 上触发
  • 输出窗口中没有绑定错误(绑定成功,但未注册委托)

MyView.xaml

 .
 .
 .
<UserControl.Resources>
        <xcdg:DataGridCollectionViewSource
                x:Key="items"
                Source="{Binding Path=Items}"
                AutoFilterMode="And" >
        </xcdg:DataGridCollectionViewSource>
</UserControl.Resources>
<xcdg:DataGridControl 
        Name="dataGrid" 
        ReadOnly="True"
        ItemsSource="{Binding Source={StaticResource items}}"
     .
     .
     .

MyView.xaml.cs 构造函数

    public MyView()
    {
        if (!DesignerProperties.GetIsInDesignMode(this))
            DataContext = new MyViewModel().Tree;
        initializeComponent();
    }

MyViewModel.cs 关键部分

 public MyTree Tree { get; set; }

 public MyViewModel()
 {    
         Tree = new MyTree();            
 }

MyTree.cs关键部分

 public ObservableCollection<Item> Items{ get; private set; }

 public MyTree()
 {
    Items= new ObservableCollection<Item>();
    Items.CollectionChanged += delegate { Console.WriteLine("Trigger"); };
 }

每次添加和删除时都会打印触发器,但 UI 仍然认为集合是空的并且不知道更新。如果没有我的额外委托 Items.CollectionChangednull (即解析的 Xaml 不会导致侦听器添加到集合中)

  • 我在尝试时做错了什么 绑定我的 DataGridCollectionViewSource 到 可观察集合?

我很高兴提供更多细节,并尝试从我的用例中抽象出问题的核心内容。集合的嵌套可能看起来很荒谬,但它基本上是树中节点的集合,以便更快地访问。

提前致谢!

编辑

通过将 PresentationTraceSources.TraceLevel=High 添加到我的 Xaml,我得到了一些更详细的输出。

 ItemsSource="{Binding Source={StaticResource orders}, PresentationTraceSources.TraceLevel=High}"

在这里,我认为问题在于默认更新触发器解析为PropertyChanged,而我希望默认值是CollectionChanged。但我仍然不知道该怎么办。

BindingExpression (hash=43320496): Default mode resolved to OneWay
BindingExpression (hash=43320496): Default update trigger resolved to PropertyChanged
BindingExpression (hash=43320496): Attach to Xceed.Wpf.DataGrid.DataGridControl.ItemsSource (hash=9150720)
BindingExpression (hash=43320496): Resolving source 
BindingExpression (hash=43320496): Found data context element: <null> (OK)
BindingExpression (hash=43320496): Use View from DataGridCollectionViewSource (hash=9026257)
BindingExpression (hash=43320496): Activate with root item <null>
 BindingExpression (hash=43320496): Replace item at level 0 with <null>, using accessor {DependencyProperty.UnsetValue}
BindingExpression (hash=43320496): GetValue at level 0 from <null> using <null>: <null>
BindingExpression (hash=43320496): TransferValue - got raw value <null>
BindingExpression (hash=43320496): TransferValue - using final value <null>
BindingExpression (hash=43320496): Got PropertyChanged event from DataGridCollectionViewSource (hash=9026257) for View
BindingExpression (hash=43320496): Deactivate
BindingExpression (hash=43320496): Replace item at level 0 with {NullDataItem}
BindingExpression (hash=43320496): Use View from DataGridCollectionViewSource (hash=9026257)
BindingExpression (hash=43320496): Activate with root item DataGridCollectionView (hash=54545236 Count=0)
BindingExpression (hash=43320496): Replace item at level 0 with DataGridCollectionView (hash=54545236 Count=0), using accessor {DependencyProperty.UnsetValue}
BindingExpression (hash=43320496): GetValue at level 0 from DataGridCollectionView (hash=54545236 Count=0) using <null>: DataGridCollectionView (hash=54545236 Count=0)
BindingExpression (hash=43320496): TransferValue - got raw value DataGridCollectionView (hash=54545236 Count=0)
BindingExpression (hash=43320496): TransferValue - using final value DataGridCollectionView (hash=54545236 Count=0)

Quick summary

  • No items show up in my Grid in the GUI of my Application
  • Correct columns are listed in grid when it fires up (Picked up collection type)
  • CollectionChanged event fires on the ObservableCollection the grid is bound to
  • No binding error in the output window (Binds successfully but doesn't register delegate)

MyView.xaml

 .
 .
 .
<UserControl.Resources>
        <xcdg:DataGridCollectionViewSource
                x:Key="items"
                Source="{Binding Path=Items}"
                AutoFilterMode="And" >
        </xcdg:DataGridCollectionViewSource>
</UserControl.Resources>
<xcdg:DataGridControl 
        Name="dataGrid" 
        ReadOnly="True"
        ItemsSource="{Binding Source={StaticResource items}}"
     .
     .
     .

MyView.xaml.cs Constructor

    public MyView()
    {
        if (!DesignerProperties.GetIsInDesignMode(this))
            DataContext = new MyViewModel().Tree;
        initializeComponent();
    }

MyViewModel.cs key parts

 public MyTree Tree { get; set; }

 public MyViewModel()
 {    
         Tree = new MyTree();            
 }

MyTree.cs key parts

 public ObservableCollection<Item> Items{ get; private set; }

 public MyTree()
 {
    Items= new ObservableCollection<Item>();
    Items.CollectionChanged += delegate { Console.WriteLine("Trigger"); };
 }

Trigger gets printed on every addition and deletion but the UI still thinks the collection is empty and isn't aware of the updates. Without my extra delegate Items.CollectionChanged is null (ie the parsed Xaml doesn't cause a listener to be added to the collection)

  • What am I doing wrong in trying to
    bind my
    DataGridCollectionViewSource to an
    ObservableCollection?

Happy to give more detail, I've tried to abstract away from my use case to the bare bones of the issue. The nesting of the collection may seem ridiculous but it's basically a collection of the nodes in the tree for faster access.

Thanks in advance!

EDIT

By adding PresentationTraceSources.TraceLevel=High to my Xaml I got some more detailed output.

 ItemsSource="{Binding Source={StaticResource orders}, PresentationTraceSources.TraceLevel=High}"

Here I think the problem is that Default update trigger resolved to PropertyChanged where I would expect the default to be CollectionChanged. I'm still not sure what to do about this though.

BindingExpression (hash=43320496): Default mode resolved to OneWay
BindingExpression (hash=43320496): Default update trigger resolved to PropertyChanged
BindingExpression (hash=43320496): Attach to Xceed.Wpf.DataGrid.DataGridControl.ItemsSource (hash=9150720)
BindingExpression (hash=43320496): Resolving source 
BindingExpression (hash=43320496): Found data context element: <null> (OK)
BindingExpression (hash=43320496): Use View from DataGridCollectionViewSource (hash=9026257)
BindingExpression (hash=43320496): Activate with root item <null>
 BindingExpression (hash=43320496): Replace item at level 0 with <null>, using accessor {DependencyProperty.UnsetValue}
BindingExpression (hash=43320496): GetValue at level 0 from <null> using <null>: <null>
BindingExpression (hash=43320496): TransferValue - got raw value <null>
BindingExpression (hash=43320496): TransferValue - using final value <null>
BindingExpression (hash=43320496): Got PropertyChanged event from DataGridCollectionViewSource (hash=9026257) for View
BindingExpression (hash=43320496): Deactivate
BindingExpression (hash=43320496): Replace item at level 0 with {NullDataItem}
BindingExpression (hash=43320496): Use View from DataGridCollectionViewSource (hash=9026257)
BindingExpression (hash=43320496): Activate with root item DataGridCollectionView (hash=54545236 Count=0)
BindingExpression (hash=43320496): Replace item at level 0 with DataGridCollectionView (hash=54545236 Count=0), using accessor {DependencyProperty.UnsetValue}
BindingExpression (hash=43320496): GetValue at level 0 from DataGridCollectionView (hash=54545236 Count=0) using <null>: DataGridCollectionView (hash=54545236 Count=0)
BindingExpression (hash=43320496): TransferValue - got raw value DataGridCollectionView (hash=54545236 Count=0)
BindingExpression (hash=43320496): TransferValue - using final value DataGridCollectionView (hash=54545236 Count=0)

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(4

晨曦÷微暖 2024-10-11 05:18:43

如果您直接绑定到项目而不是使用静态源,它会起作用吗?

我对静态项目源没有太多经验,但静态这个词让我认为它是一次性绑定

Does it work if you bind directly to your Items instead of using a Static source?

<xcdg:DataGridControl Name="dataGrid" ItemsSource="{Binding Path=Items}" />

I don't have much experience with static item sources, but the word static makes me think its a one-time binding

羁客 2024-10-11 05:18:43

如果您尝试将 Grid 直接绑定到 Items 属性,而不是绑定到 CollectionViewSource 会怎样?如果有效,则问题出在 CollectionViewSource 到集合的绑定上,而不是 Grid 到 CollectionViewSource 的绑定上。

What if you try binding the Grid directly to the Items property, rather than to the CollectionViewSource? If that works, then the problem is with the binding of the CollectionViewSource to your collection, rather than the Grid's binding to the CollectionViewSource.

清眉祭 2024-10-11 05:18:43

您必须设置 CollectionViewSourceSource 属性:

    private void Window_Loaded(object sender, RoutedEventArgs e)
    {
       var items = (CollectionViewSource) FindResource("items");
       items.Source = new MyViewModel().Tree;
    }

You have to set the Source property of the CollectionViewSource:

    private void Window_Loaded(object sender, RoutedEventArgs e)
    {
       var items = (CollectionViewSource) FindResource("items");
       items.Source = new MyViewModel().Tree;
    }
陌上青苔 2024-10-11 05:18:43

您可以尝试为 CollectionViewSource 指定一个名称,然后在加载数据后在后面的代码中调用 CollectionViewSource.View.Refresh() 方法。

很多时候,问题是即使您将视图设置为 ObservableCollection,CollectionViewSource 也不会自动更新。

网上有人发布了一个很好的 AutoRefreshingObservableCollection 类,我一直在使用它并且运行良好。

尝试一下,如果它能解决您的问题,请告诉我。我也有该 AutoRefreshingObservableCollection 的代码,如果您需要,请回复,我可以将其放在我的网站或其他地方。

Something you can try is give the CollectionViewSource a name and then in the code behind call the CollectionViewSource.View.Refresh() method on it after you have loaded it with data.

Many times the problem is that the CollectionViewSource doesn't automatically update even if you make the view an ObservableCollection.

Someone on the web posted a nice class for an AutoRefreshingObservableCollection which I've been using and works well.

Give this a try and let me know if it solves your issue. I have the code for that AutoRefreshingObservableCollection too if you need, reply and I can drop it on my website or something.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文