UserControl到ObservableCollection的DataBinding Text属性不会更新

时间:2011-08-25 04:52:41

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

我创建了一个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}" />

3 个答案:

答案 0 :(得分:1)

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

修改
在您的评论之后,即使您将其设置为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事件,并且初始更新发生是因为它不是基于更新事件。

答案 1 :(得分:1)

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

答案 2 :(得分:0)

感谢提示家伙。

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

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

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