【问题标题】:DataBinding Text Property of UserControl to ObservableCollection does not updateUserControl 到 ObservableCollection 的 DataBinding 文本属性不更新
【发布时间】:2011-11-03 08:37:38
【问题描述】:

我创建了一个 UserControl,它是根据绑定的 ObservableCollection 的内容显示转换后的字符串值。应用程序加载时一切正常;我的 IValueConverter 被调用并产生正确的字符串结果,该结果在我的 UserControl 中正确显示。但是,如果 ObservableCollection 内容发生更改,我的控件不会更新。

另外,在创建此控件之前,我有相同的行为,但绑定了常规 Button 控件的 Content 属性,这也正常工作并按预期更新。

任何想法我想用我的 UserControl 获得同样的东西吗?

控件属性的样子;

public static readonly DependencyProperty TextProperty =
        DependencyProperty.Register("Text", typeof(string), typeof(MyUserControl));

public string Text
{
    get { return GetValue(TextProperty) as string; }
    set { SetValue(TextProperty, value);
}

UserControl XAML(显示转换后的字符串值)中的相关部分是;

<TextBlock Text="{Binding RelativeSource={RelativeSource AncestorType={x:Type Controls:MyUserControl}}, Path=Text}" />

并且控件像这样在单独的窗口中创建;

<CoreControls:MyUserControl 
    Name="myControl" 
    Text="{Binding Path=ObservableCollectionInstance, Converter={StaticResource MyValueConverter}, Mode=OneWay}" />

【问题讨论】:

    标签: wpf data-binding user-controls dependency-properties


    【解决方案1】:

    我会在你的绑定中使用ElementName 而不是RelativeSource,因为你已经命名了你的用户控件。此外,您正在尝试将集合绑定到&lt;Textbox&gt;&lt;Textbox&gt; 旨在显示单个项目。这可能是它不起作用的原因。 ObservableCollection 触发 CollectionChanged 事件,而不是 PropertyChanged。即使它确实响应了,您仍然会遇到问题,因为 ObservableCollection 不会通知其中包含的项目何时具有属性更改 - 仅在添加/删除项目等时(想想,集合本身更改)。如果这是您想要的行为,您将不得不编写一些代码。

    编辑
    在您的 cmets 之后,在我看来,即使您将其设置为 OneWay 绑定模式,它的行为就像 OneTime 绑定模式一样。
    我会尝试这个来帮助你调试它:

    添加这个xmlns:

    xmlns:diagnostics="clr-namespace:System.Diagnostics;assembly=WindowsBase"
    

    然后,在您的绑定中添加:

    diagnostics:PresentationTraceSources.TraceLevel=High
    

    here is an article on debugging bindings

    您可以做的另一件事是在转换器中设置断点。当您在收藏中添加/删除东西时,看看它是否真的在更新。我愿意打赌它的 bc ObservableCollection 没有触发 PropertyChanged 事件并且初始更新发生是因为它不是基于更新事件。

    【讨论】:

    • RelativeSource 绑定在 UserControl 内的 TextBlock 上;那时没有命名 UserControl。无论如何,这并不能解决这个问题。
    • 我有意绑定到一个集合,以便当集合为空时文本框可以显示“NONE”“Item[0].SomeValue”当集合中有单个项目和“MULTIPLE”时超过 1 项时。我的 IValueConverter 处理这种转换,并且在窗口上设置初始 DataContext 时正确执行此操作,但在 ObservableCollection 更改时不会这样做。
    【解决方案2】:

    ObservableCollection 仅在添加或删除项目时通知。它用于观察集合。它们更适合内容控件。阅读它here。您正在谈论观察需要INotifyPropertyChanged 的属性。发布更多代码可能会有所帮助,例如您如何更改集合的值。

    【讨论】:

    • 那么有没有办法刷新基于 INotifyCollectionChanged 的​​绑定?
    • 还有; ObservableCollection 由 .Clear() 和 .Add(...) 调用修改。
    • 您能检查一下是不是每次更改集合时都会调用转换器?
    【解决方案3】:

    感谢您的提示。

    我设法找到了解决方案;我可以处理ObservableCollection 上的CollectionChanged 事件,然后用类似的东西显式更新目标;

    BindingExpression exp = myControl.GetBindingExpression(MyUserControl.TextProperty);
    if (null != exp) exp.UpdateTarget();
    

    如前所述,绑定 Text 属性很可能只监听 PropertyChanged 事件,而不是 NotifyCollectionChanged 事件,但此解决方案可以解决问题。

    【讨论】:

      猜你喜欢
      • 2014-03-31
      • 1970-01-01
      • 2018-06-13
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2011-11-15
      • 1970-01-01
      相关资源
      最近更新 更多