WPF:usercontrol

时间:2016-03-08 10:55:33

标签: c# wpf xaml data-binding oxyplot

好的,我没有得到它而且我知道,这个问题至少被问过并回答了10000次....但也许我在这里遇到某种特殊情况或者我只是没有得到它。

我有一个名为Statisticspopup的usercontrol,它有一个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显示正确的值,但我没有在我的usercontrol中收到绑定。

我收到此输出错误:

  

BindingExpression路径错误:&#39; DataPoint&#39;在&#39; object&#39;上找不到的属性&#39;&#39; StatisticspopupViewModel&#39; (的HashCode = 3740464)&#39 ;.
  BindingExpression:路径= DataPoint.X;的DataItem =&#39; StatisticspopupViewModel&#39; (的HashCode = 3740464);目标元素是&#39; Statisticspopup&#39; (名称=&#39;&#39);目标财产是“XValue&#39; (键入&#39; Double&#39;)

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

我认为它与Binding.Path属性有某种关系,因为它试图访问绝对错误的StatisticspopupViewModel。 TextBox的输出:

  • 在0级 - 对于TrackerHitResult.DataPoint找到了访问者 ReflectPropertyDescriptor(数据点)
  • 使用访问者使用TrackerHitResult替换级别0的项目 ReflectPropertyDescriptor(数据点)
  • 来自TrackerHitResult的0级GetValue使用 ReflectPropertyDescriptor(DataPoint):DataPoint
  • 在第1级 - 对于DataPoint.X找到了访问者 ReflectPropertyDescriptor(X)
  • 使用访问者使用DataPoint替换级别1的项目 ReflectPropertyDescriptor(X)
  • 使用DataPoint从1级获取GetValue ReflectPropertyDescriptor(X):&#39; 9&#39; TransferValue - 获得原始值&#39; 9&#39;
  • TransferValue - 隐式转换器生成&#39; 9&#39;
  • TransferValue - 使用最终值&#39; 9&#39;

最后显示的值......

对这个问题有任何想法吗?

2 个答案:

答案 0 :(得分:0)

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

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

该方法已经改变了#34; 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);
}

答案 1 :(得分:0)

好的,我明白了。如果我删除ViewModel绑定,代码可以设置依赖项属性并以正确的方式使用它们。 This post here解释了如何做到这一点。