不设置DataContext时WPF绑定问题

时间:2010-11-28 18:11:06

标签: wpf data-binding user-controls

我已成功创建了许多具有各种功能的UserControl,将每个控件上的DataContext设置为'this'。当我试图将它们分成更小的“内部”UserControls时,我总是遇到问题。问题是:

当DataContext设置为'this'时,我可以在后面的代码中绑定到Properties - 它们不必是DependencyProperties。当绑定到普通属性时,程序执行会进入后面的代码,在那里我可以执行诸如切换ListBox项目或其他我无法在xaml中执行的操作。

但是当我创建一个托管在原始控件中的新“内部”UserControl并将这些属性移动到内部控件时,我现在必须将它们升级为DependencyProperties,以便我可以从原始控件绑定它们。当绑定到DependencyProperties时,程序执行永远不会输入代码,对我而言,这就是问题所在。顺便说一句,我不在内部控件中设置DataContext,而是设置根元素的Name属性,并在内部控件属性的绑定中使用ElementName = UserControlName语法。

我知道我可以将一个ValidateValueCallbackHandler添加到DependencyProperty以获取对绑定值更改后面的代码的访问权限,但它必须是一个静态方法,所以我无法访问任何非静态成员(即我的全班)。

一个例子是我有一个在ListBoxes中显示TimeSegments对象的DurationPicker控件。 TimeSegments对象基本上是TimeSegment对象的ObservableCollection,TimeSegment具有StartDate,EndDate和Duration属性。我在DurationPicker控件中有一个MinutesPerSegment属性,该属性绑定到ComboBox的值。它工作得很好。我可以更改ComboBox值,后面的代码会将正确数量的TimeSegment对象与ListBox中的正确新值放在一起。

然后我创建了包含TimeSegments对象和ListBox的内部控件来显示它。现在MinutesPerSegment属性必须成为DependencyProperty,以便我可以从外部控件绑定它,程序执行永远不会进入后面的代码,所以现在我不能改变集合中TimeSegmentobjects的数量。

还有一点需要注意。我可以从外部控件成功绑定到内部控件的DependencyProperties - 我可以看到UI中显示的更改。问题在于,当某些绑定属性更新时,我需要程序执行来输入代码。

这样做的正确方法是什么?非常感谢。

编辑 - 在示例中,如果我在外部控件中创建TimeSegments对象并将它们绑定到内部控件,那么它仍然有效。这是因为外部控件中的MinutesPerSegment属性是普通属性...但是,我希望每个TimeSegments对象都在其自己的内部TimeSegmentsRow控件中处理......所以问题就出现了。

1 个答案:

答案 0 :(得分:0)

首先,您无需将DataContext设置为this,只需启用与自定义控件属性的绑定即可。如果有人决定为你的控件设置另一个datacontext,这是一个坏主意。您可以使用相对绑定。

{Binding Path=PathToProperty, 
         RelativeSource={RelativeSource AncestorType=
                         {x:Type namespaceAlias:typeOfYourControl}}}

并在xaml中为自定义控件声明名称空间别名

xmlns:namespaceAlias="clr-namespace:YourLibraryNamespace;assembly=YourLibraryAssemblyName"

其次,wpf will not use your property getter and setter to access your dependency properties,这就是除了GetValueSetValue之外不应该有任何其他逻辑的原因。注册属性时可以指定PropertyChangedCallback,以便在属性更改时添加一些逻辑。