未设置DataContext时WPF绑定问题

未设置DataContext时WPF绑定问题,wpf,data-binding,user-controls,Wpf,Data Binding,User Controls,我已经成功地创建了许多UserControls,并使用各种功能将每个控件上的DataContext设置为“this”。当我试图将它们分割成更小的、更有用的“内部”用户控件时,我总是遇到问题。问题是: 当DataContext设置为“this”时,我可以绑定到代码隐藏中的属性-它们不必是DependencyProperties。当绑定到普通属性时,程序执行会进入后台代码,在那里我可以做一些事情,比如开关列表框项或其他我在xaml中不能做的事情 但是,当我创建一个新的托管在原始控件中的“内部”Use

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

当DataContext设置为“this”时,我可以绑定到代码隐藏中的属性-它们不必是DependencyProperties。当绑定到普通属性时,程序执行会进入后台代码,在那里我可以做一些事情,比如开关列表框项或其他我在xaml中不能做的事情

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

我知道我可以向DependencyProperty添加ValidateValueCallbackHandler,以便在绑定值更改时访问隐藏的代码,但它必须是静态方法,因此我无法访问任何非静态成员(即我的整个类)

例如,我有一个DurationPicker控件,它在列表框中显示TimeSegments对象。TimeSegments对象基本上是TimeSegment对象的可观察集合,TimeSegment具有StartDate、EndDate和Duration属性。我在DurationPicker控件中有一个MinutesPerSegment属性,该属性绑定到组合框中的值。它工作得很好。我可以更改ComboBox值,后面的代码会将正确数量的TimeSegment对象和正确的新值放入列表框中

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

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

正确的方法是什么?非常感谢


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

首先,您不需要将
DataContext
设置为
this
,仅仅是为了启用对自定义控件属性的绑定。如果有人决定为您的控件设置另一个datacontext,这是一个坏主意。您可以改用相对绑定

{Binding Path=PathToProperty, 
         RelativeSource={RelativeSource AncestorType=
                         {x:Type namespaceAlias:typeOfYourControl}}}
并在xaml中声明自定义控件的命名空间别名

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

其次,这就是为什么除了
GetValue
SetValue
之外不应该有任何附加逻辑。您可以在注册属性时指定,以便在属性更改时添加一些逻辑。

感谢您提供有关DataContext=这一点的提示,但这与命名UserControl根元素和使用ElementName不一样吗?此外,PropertyChangedCallback委托与ValidateValueCallback一样是静态的,因此我无法从那里访问类成员。您是说当不相关的数据绑定属性更改时,无法调用非静态方法吗?
PropertyChangedCallback
static方法在第一个参数中接收
DependencyObject
。这个
DependencyObject
是你的控件,因此你可以将它转换为你的控件类型并使用所有成员。这就是我想要的!非常感谢!:)