Привязка одного элемента управления к другому DataContext - PullRequest
3 голосов
/ 09 сентября 2011

Я привязываю свое окно wpf к классу слоя приложения (WindowVM.cs), используя DataContext в конструкторе Window.xaml.cs (DataContext = WindowVM). Но один элемент управления (btnAdd) я хочу привязать к свойству Window.xaml.cs. Поэтому в конструкторе Window.xaml.cs я добавляю this.btnAdd.DataContext. Это конструктор Window.xaml.cs и свойство, к которому я хочу привязать Button btnAdd:

    public Window()
    {
        InitializeComponent();
        DataContext = WindowVM;
        this.btnAdd.DataContext = this;
    }

    public RelayCommand Add
    {
        get
        {
            return _add == null ? _add= new RelayCommand(AddPP, CanAddPP) : _add;
        }
        set
        {
            OnPropertyChanged("Add");
        }
    }

Xaml выглядит так (класс PP является свойством WindowVM):

<TextBox Name="txtName" Text="{Binding PP.Name, ValidatesOnDataErrors=true, UpdateSourceTrigger=PropertyChanged}" />
<TextBox Name="txtSurname" Text="{Binding PP.Surname, ValidatesOnDataErrors=true, UpdateSourceTrigger=PropertyChanged}" />
<Button Command="{Binding Add}" Content="Add" ... />

И - все работает, но консоль выводит это:

BindingExpression path error: 'Add' property not found on 'object' ''WindowVM'...

В следующих вызовах нет ошибки вывода консоли для свойства Add.

Теперь я немного запутался из-за этой ошибки. Является ли эта ошибка первой DataContext (для WindowVM), потому что отсутствует свойство Add, а в строке this.btnAdd.DataContext найдено свойство Add, и это причина его работы?

Ответы [ 3 ]

2 голосов
/ 04 ноября 2011

Просто установите DataContext из Button в XAML, используя RelativeSource:

<Button Command="{Binding Add}" Content="Add" DataContext="{Binding Add, RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type Window}}}" />
1 голос
/ 08 марта 2013

У меня была эта проблема, и я знаю, что это старый пост, но я думаю, что это может помочь кому-то, кто наткнется на это в будущем.

то, что я сделал, объявил модели представления как ресурсы

<Page.Resources>
    <local:LocationListViewModel x:Key="LocationList" />
    <local:LocationNewViewModel x:Key="NewLocation" />
    <code:BinaryImageConverter x:Key="imgConverter" />
</Page.Resources>

, то какой контроль я хотел связать с указанной моделью представления, я добавил это в их datacontext

<TabItem x:Name="tabSettingsLocations" x:Uid="tabSettingsLocations" 
                 Header="Locations"
                 DataContext="{StaticResource ResourceKey=LocationList}">....

<TabItem x:Name="tbSettingsLocationsAdd" x:Uid="tbSettingsLocationsAdd" 
         Header="Add New"
         DataContext="{StaticResource ResourceKey=NewLocation}">....

<Image x:Name="imgSettingsLocationMapNew" x:Uid="imgSettingsLocationMapNew" 
         Source="{Binding Map, Converter={StaticResource imgConverter}, 
         Mode=TwoWay}"
         DataContext="{StaticResource ResourceKey=NewLocation}" />

Таким образом, в моем примере выше у меня есть Listview, связанный с моделью представления списка, и я создаю новое единственное местоположение для моей новой записи.Вы заметите, что, создав его как ресурс, я могу связать tabitem и изображение (которое не является дочерним элементом элемента tab) с новой моделью просмотра местоположения.

Моя команда для местоположения addnew находится вновая модель просмотра местоположения.

<TabItem x:Name="tbSettingsLocationsAdd" x:Uid="tbSettingsLocationsAdd" 
         Header="Add New"
         DataContext="{StaticResource ResourceKey=NewLocation}">....

    <Button x:Name="btnSettingsLocationSaveAdd" x:Uid="btnSettingsLocationSaveAdd" Content="Submit" Margin="0,80,10,0" 
        VerticalAlignment="Top" Style="{DynamicResource ButtonStyle}" HorizontalAlignment="Right" Width="75"
        Command="{Binding AddCommand}" />.....

Какая дочерняя часть табе, которую я привязал к новой модели просмотра местоположения.

Надеюсь, это поможет.

0 голосов
/ 23 октября 2011

Когда вы устанавливаете свойство DataContext, ваше окно сбрасывает привязки дочерних элементов управления. Даже привязка вашей кнопки. На этом этапе (до того, как "button.DataContext = this" оценивается) выполняется поиск "Добавить" в WindowVM. После этого вы устанавливаете класс Window как кнопки DC, и все работает нормально.

Чтобы избежать начальной ошибки, поменяйте местами две строки из этого

public Window()
{
    InitializeComponent();
    DataContext = WindowVM;
    this.btnAdd.DataContext = this;
}

к этому

public Window()
{
    InitializeComponent();
    this.btnAdd.DataContext = this;
    DataContext = WindowVM;
}
...