使用嵌套集合进行WPF数据绑定不会更新控件

使用嵌套集合进行WPF数据绑定不会更新控件,wpf,data-binding,collections,Wpf,Data Binding,Collections,我有一个带有一些嵌套集合的Objectmodel: public class MainViewModel : BaseViewModel { private Dictionary<String, Diagram> _diagrams; public Dictionary<String, Diagram> Diagrams { get { return _diagrams; } set {

我有一个带有一些嵌套集合的
Objectmodel

public class MainViewModel :  BaseViewModel
{
    private Dictionary<String, Diagram> _diagrams;

    public Dictionary<String, Diagram> Diagrams
    {
        get { return _diagrams; }
        set
        {
            _diagrams = value;
            OnPropertyChanged("Diagrams");
        }
    }
我在Xaml中绑定到
DiagramCanvas
的一个实例,如下所示:

    <wd:DiagramCanvas x:Name="diagramCanvas" 
                          Diagram ="{Binding Diagrams[Diagram1]}"  
                          Grid.Row="2" Grid.Column="1" 
                          Height="auto" Width="Auto"  
                          HorizontalAlignment="Stretch"  
                          VerticalAlignment="Stretch" 
                          Margin="10"   
                          Background="{StaticResource DiagrambackgroundBrush }" />


如果我将
MainView
的Diagrams属性指定为一个全新的Diagrams集合,那么这项功能可以正常工作。但我需要的是,
DiagramCanvas
控件在曲线集合更改时得到更新。但这不会发生。

您的绑定位于
MainViewModel
Diagrams
属性上,并选择与“Diagram1”字符串对应的图表。在绑定路径中,没有提到
Curves
属性,因此当曲线抛出
CollectionChanged
事件时,绑定不会更新。为了防止这种情况发生,您可以在
MainViewModel
中注册此事件,并在出现此事件时在字典中抛出良好图表的
PropertyChanged
事件

但是。。。如果我没有弄错的话,.Net字典没有实现
INotifyCollectionChanged
,我也不确定绑定是否会更新。你应该试着通知我

快乐编码


Antoine

我试图从一个“可观察的集合”继承
图表,但即使这样也没有帮助

由于my CustomControl
DiagramCanvas
的DependencyProperty绑定到Dictionary
MainViewModel.Diagrams
的值项,而不是
Diagram
实例的属性,因此不会触发
DiagramCanvas
DependencyProperty的
事件,当
关系图
实例的属性更改时

仅当为字典
MainViewModel.Diagrams
中的值项分配了新值时,才会触发此事件,因为这将为
DiagramCanvas
dependencProperty
分配一个新值

因此,我必须手动订阅集合的事件:

public class DiagramCanvas : Canvas
{
  // Is called only when new Items get inserted info the Dictionary
  static void OnDiagramPropertyChanged(DependencyObject obj, 
                                     DependencyPropertyChangedEventArgs args)
  {
      DiagramCanvas THIS = (DiagramCanvas)obj;

      Diagram new_diagram = (Diagram)args.NewValue;
      Diagram old_diagram = (Diagram)args.NewValue;

      if (old_diagram != null)
      {
        // Unsubscribe from CollectionChanged on the old collection
        old_diagram.Curves.CollectionChanged -= THIS.OnCollectionChanged;
      }

      if (new_diagram != null)
      {
        // Subscribe to CollectionChanged on the new collection
        new_diagram.Curves.CollectionChanged += THIS.OnCollectionChanged;
      }
  }

  //Is called everytime the Curves collecion changes
  void OnCollectionChanged(object sender, NotifyCollectionChangedEventArgs e)
  {

  }
}

如何在“MainViewModel”中注册事件?我已经尝试为Diagrams集合使用ObservableDictionary类,但这没有帮助,因为我没有更改此集合。是的,在这种情况下,您不应注册到Diagrams集合更改事件,而应注册到Curves集合更改事件。第二个想法:由于您还创建了自己的名为DiagramCanvas的控件,因此该控件可能是在收到图表时注册到Curvers.CollectionChanged的控件。如果之后关系图发生了更改,或者为了避免内存丢失而卸载了视图,请不要忘记注销事件。您还可以更改DiagramCanvas以提供依赖于曲线的属性,而不是图表。这样,所有事件注册都将是自动的。实际上,正如您在我自己的答案DiagramCanvas中所看到的,现在注册到Curves.onCollectionChanged事件。我需要绑定到DiagrampProperty,因为我的控件只需要曲线,所以需要从图表中获取更多数据。
public class DiagramCanvas : Canvas
{
  // Is called only when new Items get inserted info the Dictionary
  static void OnDiagramPropertyChanged(DependencyObject obj, 
                                     DependencyPropertyChangedEventArgs args)
  {
      DiagramCanvas THIS = (DiagramCanvas)obj;

      Diagram new_diagram = (Diagram)args.NewValue;
      Diagram old_diagram = (Diagram)args.NewValue;

      if (old_diagram != null)
      {
        // Unsubscribe from CollectionChanged on the old collection
        old_diagram.Curves.CollectionChanged -= THIS.OnCollectionChanged;
      }

      if (new_diagram != null)
      {
        // Subscribe to CollectionChanged on the new collection
        new_diagram.Curves.CollectionChanged += THIS.OnCollectionChanged;
      }
  }

  //Is called everytime the Curves collecion changes
  void OnCollectionChanged(object sender, NotifyCollectionChangedEventArgs e)
  {

  }
}