C# 绑定到TreeView SelectedItem作为ItemsSource工作,但不用于自定义DependencyProperty

C# 绑定到TreeView SelectedItem作为ItemsSource工作,但不用于自定义DependencyProperty,c#,wpf,xaml,data-binding,C#,Wpf,Xaml,Data Binding,我有一个树状视图,其中有一个ICollection作为它的ItemsSource。现在我尝试在其他一些控件中使用SelectedItem。出于某种原因,我可以使用ElementName为ListView正确设置绑定,但当我尝试为自定义DependencyProperty实现相同的绑定时,它永远不会得到更新 以下是XAML(ListView工作,MyControl不工作): 我怀疑DependencyProperty的实现有什么问题,但我不知道是什么问题。我不认为dependency属性在技术上有

我有一个树状视图,其中有一个ICollection作为它的ItemsSource。现在我尝试在其他一些控件中使用SelectedItem。出于某种原因,我可以使用ElementName为ListView正确设置绑定,但当我尝试为自定义DependencyProperty实现相同的绑定时,它永远不会得到更新

以下是XAML(ListView工作,MyControl不工作):


我怀疑DependencyProperty的实现有什么问题,但我不知道是什么问题。

我不认为dependency属性在技术上有什么问题,但它的实现方式看起来也不是特别有用。通常,在实现依赖项属性时,您希望在它接收到新值时发生一些事情。最基本的方法是使用值更改回调。例如:

public static readonly DependencyProperty BlubbiProperty = DependencyProperty.Register(
    nameof(Blubbi), typeof(object), typeof(MyControl),
    new PropertyMetadata(default(object), (d, e) => ((MyControl)d).OnBlubbiChanged(e.oldValue, e,newValue)));

private void OnBlubbiChanged(object oldValue, object newValue)
{
    // Do something here
}
您还可以针对新的传入值执行更高级的操作,但通常不需要这样做。如果你想读更多,这里有一个例子

现在,所有这些对于任何
DependencyObject
都很好,但是如果您是从
FrameworkElement
扩展而来的元素,大多数元素都是这样做的,那么您可以使用
PropertyMetadata
,它以

因此,假设您在元素的
OnRender
覆盖中使用此属性,那么您可以确保每当属性值更改时,render会自动失效,以便再次调用
OnRender

public static readonly DependencyProperty BlubbiProperty = DependencyProperty.Register(
    nameof(Blubbi), typeof(object), typeof(MyControl),
    new FrameworkPropertyMetadata(default(object), FrameworkPropertyMetadataOptions.AffectsRender));
此外,如果元素是使用XAML定义的模板来表示自身的
控件
,则可以保持依赖项属性不变,并通过
TemplateBinding在控件模板中使用它

<ControlTemplate TargetType="{x:Type myNamespace:MyControl}">
    <TextBlock Text="{TemplateBinding Blubbi}" />
</ControlTemplate>

谢谢你的回答!实际上我不知道二传中的断点不会命中。但是,当我知道SelectedItem正在更改时,我也没有在DependencyProperty的OnPropertyChanged或自定义PropertyChangedCallback的重写中达到Blubbi的断点。我在这个答案中添加了一些关于如何调试绑定以查看它在做什么的更多信息。
public static readonly DependencyProperty BlubbiProperty = DependencyProperty.Register(
    nameof(Blubbi), typeof(object), typeof(MyControl),
    new FrameworkPropertyMetadata(default(object), FrameworkPropertyMetadataOptions.AffectsRender));
<ControlTemplate TargetType="{x:Type myNamespace:MyControl}">
    <TextBlock Text="{TemplateBinding Blubbi}" />
</ControlTemplate>
<modules:MyControl
    xmlns:diag="clr-namespace:System.Diagnostics;assembly=WindowsBase"
    Blubbi="{Binding ElementName=myTreeView, Path=SelectedItem, diag:PresentationTraceSources.TraceLevel=High}" />