WPF:用户控件的依赖项 属性

WPF: Dependency property for usercontrol

好吧,我不明白,我知道,这个问题已经被问到并回答了至少 10000 次....但也许我这里有某种特殊情况,或者我只是不明白.

我有一个名为 Statisticspopup 的用户控件,它有一个 DependencyProperty,如下所示:

public static readonly DependencyProperty XValueProperty = DependencyProperty.Register(
    "XValue", typeof(double), typeof(Statisticspopup),
    new FrameworkPropertyMetadata(XValueChanged));

public double XValue
{
    get
    {
        var x = GetValue(XProperty);
        return (double)x;
    }
    set
    {
        SetValue(XProperty, value);
    }
}

private static void XValueChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
{
    var control = (Statisticspopup)d;
    control.XValue = double.Parse(e.NewValue.ToString());
    System.Diagnostics.Debug.WriteLine("XValueChanged");
}

我在我的 xaml 代码中这样使用它:

<controls:Statisticspopup XValue="42" />

这有效,一切都很好...现在我想为 属性 使用绑定,如下所示:

<controls:Statisticspopup XValue="{Binding DataPoint.X,PresentationTraceSources.TraceLevel=High}" />

DataPoint.X 值来自另一个控件(OxyPlot 对象),因此整个代码如下所示:

<oxy:Plot x:Name="PlotThing" Title="{Binding Title}"  Style="{DynamicResource PlotStyle}" >
    <oxy:Plot.TrackerDefinitions>
        <oxy:TrackerDefinition TrackerKey="someKey" >
            <oxy:TrackerDefinition.TrackerTemplate>
                <ControlTemplate>
                    <oxy:TrackerControl Name="TrackerControl" DataContext="{Binding }" Position="{Binding Position}" LineExtents="{Binding PlotModel.PlotArea}">
                        <oxy:TrackerControl.Content>     

<controls:Statisticspopup XValue="{Binding DataPoint.X,PresentationTraceSources.TraceLevel=High}" />
<TextBlock Foreground="Aquamarine" Text="{Binding DataPoint.X, PresentationTraceSources.TraceLevel=High}"></TextBlock>
....

如您所见,我还在 TrackerControl.Content 标签中添加了一个 TextBlock。不幸的是,TextBlock 显示了正确的值,但我没有在我的用户控件中收到绑定。

我得到这个输出错误:

BindingExpression path error: 'DataPoint' property not found on 'object' ''StatisticspopupViewModel' (HashCode=3740464)'.
BindingExpression:Path=DataPoint.X; DataItem='StatisticspopupViewModel' (HashCode=3740464); target element is 'Statisticspopup' (Name=''); target property is 'XValue' (type 'Double')

如果我查看 TextBox,一切正常。

我认为它与 Binding.Path 属性 有某种关系,因为它试图访问 StatisticspopupViewModel,这肯定是错误的。文本框的输出:

最后显示值...

对这个问题有什么想法吗?

您的 PropertyChangedCallback 已损坏。它不能包含行

control.XValue = double.Parse(e.NewValue.ToString());

顺便说一句。应该看起来像 control.XValue = (double)e.NewValue;

该方法是 XValue 属性 的 "changed" 回调,因此在 属性 值已经更改时调用。它不应该(也不能)再次设置该值,因为这有效地从 属性.

中删除了 Binding
private static void XValueChanged(
    DependencyObject d, DependencyPropertyChangedEventArgs e)
{
    var control = (Statisticspopup)d;

    // here control.XValue is already identical to (double)e.NewValue;

    Debug.WriteLine("XValueChanged: {0}, {1}", e.NewValue, control.XValue);
}

好的,我成功了。如果我删除 ViewModel 绑定,代码就能够设置依赖属性并以正确的方式使用它们。 This post here 说明如何操作。