我创建了一个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}" />
答案 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
个事件,但这个解决方案可以解决问题。