如何设置控件属性(在DataTemplate和UserControl中)的绑定以使用ItemSource的给定属性?

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了如何设置控件属性(在DataTemplate和UserControl中)的绑定以使用ItemSource的给定属性?相关的知识,希望对你有一定的参考价值。

我想创建一个具有DataTemplate的UserControl,并在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是Owner类的简单IReadOnlyList。 Owner类有一个字符串Name属性。但我会再次使用此UserControl与不同的列表,例如。我想在哪里使用Versions列表的Release属性(对于UserControl中的TextBlock):

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

ListView已正确填充项目,因此FilterList DependencyProperty正在运行。但嵌套控件仅在我对绑定进行硬编码时才起作用:

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

为此,您需要将TextBlocks Text-Binding的Path属性绑定到UserControl的FilterElementName属性。不幸的是,Binding类的Path property不是DependencyProperty,因此不可绑定。

实现目标的一种方法是使用ListView的DisplayMemberPath属性,该属性是可绑定的:

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

如果这种方法不起作用,因为你需要指定一个更复杂的ItemTemplate,另一种方法是在你的UserControl中创建一个DataTemplate类型的属性,在ListView中使用它作为ItemTemplate并从外面指定它,如下所示:

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

以上是关于如何设置控件属性(在DataTemplate和UserControl中)的绑定以使用ItemSource的给定属性?的主要内容,如果未能解决你的问题,请参考以下文章

WPF 在 GridViewColumn.CellTemplate 的 DataTemplate 中绑定 UserControl 属性

WPF为没有DataTemplate属性的控件创建DataTemplate

DataTemplate的用法

DataTemplate 和 ControlTemplate 详细应用

MVVM + Datacontext + DataTemplate + Blend = 问题

WPF在DataTemplate中宽度设置