我已成功创建了许多具有各种功能的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控件中处理......所以问题就出现了。
答案 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,这就是除了GetValue
和SetValue
之外不应该有任何其他逻辑的原因。注册属性时可以指定PropertyChangedCallback,以便在属性更改时添加一些逻辑。