2016-03-08 7 views
1

ОК, я не понимаю, и я знаю, этот вопрос задан и ответил как минимум 10000 раз .... но, возможно, у меня здесь какой-то особый случай, или я просто Не понимаю.WPF: свойство Dependency для usercontrol

У меня есть UserControl, который называется 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> 
.... 

Как вы можете видеть, я также добавил TextBlock к TrackerControl.Content тега. К сожалению, TextBlock показывает правильное значение, но я не получаю привязку в своем usercontrol.

Я получаю эту ошибку на выходе:

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, что определенно неправильно. Выход из TextBox:

  • На уровне 0 - для TrackerHitResult.DataPoint найдено аксессор ReflectPropertyDescriptor (DataPoint)
  • Заменить пункт на уровне 0 с TrackerHitResult, используя аксессор ReflectPropertyDescriptor (DataPoint)
  • GetValue на уровень 0 от TrackerHitResult использованием ReflectPropertyDescriptor (DataPoint): DataPoint
  • на уровне 1 - для DataPoint.X найдено аксессор ReflectPropertyDescriptor (X)
  • Заменить пункт на уровне 1 с DataPoint, используя аксессор ReflectPropertyDescriptor (Х)
  • GetValue на уровне 1 из DataPoint использования ReflectPropertyDescriptor (X): '9' TransferValue - получил сырое значение '9'
  • TransferValue - неявный конвертер, произведенные '9'
  • TransferValue - используя конечное значение '9'

наконец отображается значение ...

Любая идея для этой проблемы?

ответ

0

Хорошо, я получил его работу. Если я удалю привязку ViewModel, код сможет установить свойства зависимостей и использовать их правильным образом. This post here объясняет, как это сделать.

0

Ваш PropertyChangedCallback сломан. Он не должен содержать строку

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

, который кстати.должен выглядеть так: control.XValue = (double)e.NewValue;

Метод является «измененным» обратным вызовом для свойства XValue и поэтому вызывается, когда значение свойства уже изменилось. Он не должен (и не должен) устанавливать значение снова, потому что это эффектно удаляет привязку из свойства.

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); 
} 
+0

спасибо. Это может быть другой проблемой, но код даже не вызывается, если я использую свой код выше – thardes2

+1

. По соглашению статическое поле DependencyProperty также должно быть названо 'XValueProperty'. – Clemens