2015-10-23 3 views
5

Мое приложение имеет MainWindow. Внутри этого есть 1 элемент управления, ListBox, привязанный к свойству MainWindowViewModel. Это свойство является UserControl, типа CriteriaVmКак передать «привязанное» значение к свойству зависимостей

CriteriaVm имеет одну строку свойство называется MyString

В Критериями Просмотр У меня есть следующий код

<UserControl x:Class="CompoundInterests.View.CriteriaView" 
      xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" 
      xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" 
      xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" 
      xmlns:d="http://schemas.microsoft.com/expression/blend/2008" 
      xmlns:vm="clr-namespace:CompoundInterests.ViewModel" 
      mc:Ignorable="d" 
      d:DesignHeight="300" d:DesignWidth="600"> 

    <UserControl.Resources> 
     <ResourceDictionary Source="../Dictionary.xaml" /> 
    </UserControl.Resources> 
    <Grid> 
     <Border> 
      <Expander Header="{Binding MyString}" > 
       <vm:PropertiesVm ThresholdName="{Binding MyString}" /> 
      </Expander> 
     </Border> 
    </Grid> 
</UserControl> 

Как вы можете видеть, я связывании MyString в 2-х местах. Связывание в Expander отлично работает, то есть в vm: PropertiesVm не используется (который использует Dependency Properites). Следующая ошибка показывает в окне Output

System.Windows.Data Error: 2 : Cannot find governing FrameworkElement or FrameworkContentElement for target element. BindingExpression:Path=MyString; DataItem=null; target element is 'PropertiesVm' (HashCode=5991653); target property is 'ThresholdName' (type 'String')

ОК сообщение об ошибке говорит мне, что ищет MyString в ProperitesVm ... Я должен искать MyString в CriteriaVm. Это означает, что мне нужно использовать RelativeSource, который, как мне кажется, выше 1 уровня и типа UserControl. Так что я обновлена:

<vm:PropertiesVm ThresholdName="{Binding Path=MyString, RelativeSource={RelativeSource AncestorLevel=1,AncestorType=UserControl,Mode=FindAncestor}}" /> 

Я получаю немного другой вопрос, но это выглядит как если та же основная неисправность

System.Windows.Data Error: 4 : Cannot find source for binding with reference 'RelativeSource FindAncestor, AncestorType='System.Windows.Controls.UserControl', AncestorLevel='1''. BindingExpression:Path=MyString; DataItem=null; target element is 'PropertiesVm' (HashCode=24649639); target property is 'ThresholdName' (type 'String')

На данный момент PropertiesVm имеет только свойство зависимостей, то PropertiesView просто пустую сетку. Это значит, что я могу сначала обработать эту ошибку и беспокоиться о следующем этапе привязки позже.

Я не понимаю, почему я получаю сообщение об ошибке или что я делаю неправильно. Я могу с радостью предоставить больше кода, если это необходимо. Проект на этом этапе очень рано, как таковой, минимальный код.

+1

1.Add [BindableAttribute (истина)] атрибут ThresholdName свойства –

ответ

1

Ответ был в сообщении!

System.Windows.Data Error: 2 : Cannot find governing FrameworkElement or FrameworkContentElement for target element. BindingExpression:Path=MyString; DataItem=null; target element is 'PropertiesVm' (HashCode=5991653); target property is 'ThresholdName' (type 'String')

Из того, что я понял это, потому что мой UserControl унаследовал DependencyObject и не UserControl он не был UIElement ...

Поэтому мне пришлось перенести свойства зависимостей в коде моего View, который позволил работать с двумя способами, но сохранил datacontext моего ViewModel в ViewModel.

1

я ожидал бы вид выглядеть следующим образом:

<Style TargetType="{x:Type ns:YourViewModel}"> 
    <Setter Property="Template"> 
     <Setter.Value> 
      <ControlTemplate TargetType="{x:Type ns:YourViewModel}"> 
       <Grid> 
        <TextBlock Text="{Binding ThresholdName, 
           RelativeSource={RelativeSource TemplatedParent}}"/> 
       </Grid> 
      </ControlTemplate> 
     </Setter.Value> 
    </Setter> 
</Style> 

мнение код модели будет в значительной степени неизменным от того, что вы показали:

public class YourViewModel: Control 
{ 
    public static readonly DependencyProperty ThreshNameProperty = DependencyProperty.Register("ThresholdName", typeof(string), typeof(PropertiesVm), new PropertyMetadata(string.Empty)); 

    public string ThresholdName 
    { 
     get { return GetValue(ThreshNameProperty).ToString(); } 
     set { SetValue(ThreshNameProperty, value); } 
    } 
} 

Вы не были полностью ясно, что такое «MyStringValue», поэтому я ожидаю, что это будет нормальное свойство MainWindow. MainWindow бы создать экземпляр элемента управления, установив «ThresholdName» это свойство «MyStringValue»:

<Grid> 
    <ns:YourViewModel ThresholdName="{Binding MyStringValue}"/> 
</Grid> 

Наконец код MainWindow будет:

public string MyStringValue { get; set; } 

public MainWindow() 
{ 
    InitializeComponent(); 
    DataContext = this; 
    MyStringValue = "dog"; 
} 
+1

я потерял с вашим примером - вы используете ControlTemplate, по сути overwritting, что уже есть. Это не цель: S – MyDaftQuestions

+1

Я также сделал MAJOR обновление моего вопроса – MyDaftQuestions

1

Если вы изменили свое наследование с DependencyObject на FrameworkElement, это должно сработать.

<vm:PropertiesVm DataContext="{Binding}" ThresholdName="{Binding MyString}" /> 

В любом случае, вы пробовали Приватная недвижимость?

Я думаю, что это похоже так или иначе.

https://social.msdn.microsoft.com/Forums/vstudio/en-US/aff23943-5483-40b2-816b-4ce687bc6bf8/systemwindowsdata-error-2-cannot-find-governing-frameworkelement?forum=wpf