簡體   English   中英

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路徑錯誤:在“對象”“ StatisticspopupViewModel”(HashCode = 3740464)”上找不到“ DataPoint”屬性。
BindingExpression:路徑= DataPoint.X; DataItem ='StatisticspopupViewModel'(HashCode = 3740464); 目標元素是'Statisticspopup'(Name =''); 目標屬性為“ XValue”(類型為“ Double”)

如果我看看TextBox,一切都很好。

我認為這與Binding.Path屬性有關,因為它嘗試訪問StatisticspopupViewModel ,這肯定是錯誤的。 TextBox的輸出:

  • 在級別0處-為TrackerHitResult.DataPoint找到了訪問者ReflectPropertyDescriptor(DataPoint)
  • 使用訪問器ReflectPropertyDescriptor(DataPoint)將級別0的項目替換為TrackerHitResult
  • 使用ReflectPropertyDescriptor(DataPoint)從TrackerHitResult獲得0級的GetValue:DataPoint
  • 在級別1-對於DataPoint.X,找到了訪問者ReflectPropertyDescriptor(X)
  • 使用訪問器ReflectPropertyDescriptor(X)將第1級的項目替換為DataPoint
  • 使用ReflectPropertyDescriptor(X)從DataPoint處獲取第1級的GetValue:'9'TransferValue-獲得原始值'9'
  • TransferValue-隱式轉換器產生的“ 9”
  • TransferValue-使用最終值“ 9”

最終顯示值...

對這個問題有什么想法嗎?

您的PropertyChangedCallback已損壞。 它不能包含行

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

順便說一句。 應該看起來像control.XValue = (double)e.NewValue;

該方法是XValue屬性的“已更改”回調,因此在屬性值已更改時調用。 它不應(也不得)再次設置該值,因為這會有效地從屬性中刪除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綁定,則代碼可以設置依賴項屬性並以正確的方式使用它們。 這篇文章在這里解釋了如何做。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM