WPF: Как связать свойство, расположенное в дереве визуалов смежного элемента управления? - PullRequest
0 голосов
/ 03 июня 2019

У меня есть WPF Window и UserControl, которые я использую внутри Window

Окно:

<Window x:Class="AdjacentControlVisualTree.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:local="clr-namespace:AdjacentControlVisualTree"
        Title="MainWindow" Height="350" Width="525">

    <Window.DataContext>
        <local:MainViewModel/>
    </Window.DataContext>

    <StackPanel Orientation="Vertical">
        <local:AdjacentControl x:Name="AdjacentControl"/>
        <Button Content="Foo"
            CommandParameter="{Binding SelectedItem, ElementName=AdjacentControl.BarDataGrid}"
            Command="{Binding FooCommand}"/>
    </StackPanel>
</Window>

UserControl:

<UserControl x:Class="AdjacentControlVisualTree.AdjacentControl"
             xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
             xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
             xmlns:local="clr-namespace:AdjacentControlVisualTree">

    <UserControl.DataContext>
        <local:AdjacentViewModel/>
    </UserControl.DataContext>

    <Grid>
        <DataGrid x:Name="BarDataGrid"
            ItemsSource="{Binding Collection}"
            IsReadOnly="True"
            AutoGenerateColumns="False"
            SelectionUnit="FullRow"
            SelectionMode="Single">
            <DataGrid.Columns>
                <DataGridTextColumn Header="String" Binding="{Binding}"/>
            </DataGrid.Columns>
        </DataGrid>
    </Grid>
</UserControl>

Дело в том, что я хотел бы передать SelectedItem свойство DataGrid внутри AdjacentControl в команду FooCommand , но привязка всегда проходит ноль:

CommandParameter="{Binding SelectedItem, ElementName=AdjacentControl.BarDataGrid}"

Есть ли способ заставить привязку работать без изменения структуры элементов управления?

1 Ответ

1 голос
/ 04 июня 2019

Вероятно, наиболее простым способом было бы выставить BarDataGrid как свойство.

Измените имя XAML (например, на x:Name="barDataGrid") и добавьте это свойство в код UserControl:

public DataGrid BarDataGrid { get { return barDataGrid; } }

Затем привяжите к свойству SelectedItem объекта DataGrid, как показано ниже:

CommandParameter="{Binding BarDataGrid.SelectedItem, ElementName=AdjacentControl}"

Более чистым решением было бы не предоставление дочернего элемента DataGrid, а только его SelectedItem с помощью специального свойства зависимости.

public static readonly DependencyProperty SelectedItemProperty =
    System.Windows.Controls.Primitives.Selector.SelectedItemProperty.AddOwner(
        typeof(AdjacentControl));

public object SelectedItem
{
    get { return GetValue(SelectedItemProperty); }
    set { SetValue(SelectedItemProperty, value); }
}

Вы бы привязали SelectedItem DataGrid к этому свойству с помощью привязки RelativeSource

<DataGrid SelectedItem="{Binding SelectedItem,
                         RelativeSource={RelativeSource AncestorType=UserControl}}"

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

CommandParameter="{Binding SelectedItem, ElementName=AdjacentControl}"
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...