Как я могу установить привязку для свойства элемента управления (которое находится внутри DataTemplate и UserControl), чтобы использовать данное свойство ItemSource? - PullRequest
1 голос
/ 27 марта 2019

Я хотел бы создать UserControl, который имеет DataTemplate, а внутри этого DataTemplate есть элементы управления.Я хотел бы привязать к свойствам этих вложенных (внутри DataTemplate) элементов управления, чтобы я мог установить их при повторном использовании этого UserControl.Вложенные элементы управления будут использовать свойства ItemSource, но имена свойств свойств ItemSource могут отличаться.

UserControl:

<UserControl x:Class="ContextMenu.BaseFilterUserControl"
             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"
             mc:Ignorable="d"
             x:Name="Self">
    <Grid Margin="10">
        <Grid.ColumnDefinitions>
            <ColumnDefinition Width="80" />
            <ColumnDefinition Width="auto" />
            <ColumnDefinition Width="*" />
        </Grid.ColumnDefinitions>
        <Grid.RowDefinitions>
            <RowDefinition Height="70" />
        </Grid.RowDefinitions>
        <TextBlock Grid.Column="0"
                   VerticalAlignment="Center"
                   HorizontalAlignment="Right"
                   Margin="10"
                   Text="Owners" />
        <Button Grid.Column="1"
                VerticalAlignment="Center"
                HorizontalAlignment="Center"
                Margin="10"
                Click="FilteButtonClicked"
                Width="40"
                Height="40"
                x:Name="FilterButton">
            <Popup x:Name="FilterBoxPopup"
                   PlacementTarget="{Binding ElementName=FilterButton}"
                   Placement="Bottom"
                   StaysOpen="False">
                <Border BorderBrush="Black"
                        Background="White"
                        Margin="2">
                    <ListView ItemsSource="{Binding ElementName=Self, Path=FilterList}"
                              x:Name="FilterListView"
                              Height="300"
                              Width="150">
                        <ListView.ItemTemplate>
                            <DataTemplate>
                                <StackPanel Orientation="Horizontal">
                                    <!--<CheckBox IsChecked="{Binding IsChecked}" />-->
                                    <!--<TextBlock Text="{Binding Name}" />-->
                                    <!--This is where I don't know how to properly bind eg. the above control, things I tried:-->
                                    <!--<TextBlock Text="{Binding ElementName=FilterListView, Path=FilterElementName}" />-->
                                    <!--<TextBlock Text="{Binding ElementName=Self, Path=DataContext.FilterElementName}" />-->
                                    <!--<TextBlock Text="{Binding ElementName=FilterListView, Path=DataContext.FilterElementName}" />-->
                                </StackPanel>
                            </DataTemplate>
                        </ListView.ItemTemplate>
                    </ListView>
                </Border>
            </Popup>
        </Button>
        <TextBlock Grid.Column="3"
                   VerticalAlignment="Center"
                   HorizontalAlignment="Left"
                   Margin="10"
                   Text="{Binding ElementName=Self, Path=SelectedNames}" />
    </Grid>
</UserControl>

При этом используется UserControl, FilterElementName = "Name"это то, что я хотел бы установить, в зависимости от списка, связанного со списком FilterList:

<local:BaseFilterUserControl FilterList="{Binding Owners}"
                             FilterElementName="Name"
                             SelectedNames="{Binding SelectedNames}"/>

В этом случае Owners - это простой IReadOnlyList класса Owner.Класс Owner имеет строковое свойство Name.Но я буду использовать этот UserControl снова с другим списком, например.где я хотел бы использовать свойство Release списка версий (для TextBlock внутри UserControl):

<local:BaseFilterUserControl FilterList="{Binding Versions}"
                             FilterElementName="Release"
                             SelectedNames="{Binding SelectedReleases}"/>

ListView правильно заполнен элементами, так что FilterList DependencyProperty работает.Но вложенные элементы управления работают только тогда, когда я жестко кодирую привязки:

<TextBlock Text="{Binding Name}" />

1 Ответ

0 голосов
/ 28 марта 2019

Чтобы это работало, вам необходимо привязать свойство Path вашего TextBlocks Text-Binding к свойству FilterElementName вашего UserControl.К сожалению, свойство Path класса Binding не является объектом DependencyProperty и поэтому не может быть привязано.

Одним из способов достижения вашей цели будет использование свойства DisplayMemberPath объекта ListView, которое можно привязать:

   <ListView x:Name="FilterListView"
              Width="150"
              Height="300"
              ItemsSource="{Binding ElementName=Self, Path=FilterList}"
              DisplayMemberPath="{Binding ElementName=self, Path=FilterElementName}"/>

Если этот подход не работает, посколькувам нужно указать более сложный ItemTemplate, другим способом было бы создать свойство типа DataTemplate в вашем UserControl, использовать его как ItemTemplate в ListView и указать его извне, например:

    <local:BaseFilterUserControl FilterList="{Binding Versions}"
                                 SelectedNames="{Binding SelectedReleases}">
        <local:BaseFilterUserControl.ItemTemplate>
            <DataTemplate>
                <TextBlock Text="{Binding Release}" />
            </DataTemplate>
        </local:BaseFilterUserControl.ItemTemplate>
    </local:BaseFilterUserControl>
...