【问题标题】:How can I set the binding for a control's property (which is inside DataTemplate and UserControl) to use the ItemSource's given property?如何设置控件属性(位于 DataTemplate 和 UserControl 内)的绑定以使用 ItemSource 的给定属性?
【发布时间】:2019-03-27 19:37:59
【问题描述】:

我想制作一个具有 DataTemplate 的 UserControl,并且在该 DataTemplate 中有控件。我想绑定到那些嵌套(在 DataTemplate 内)控件的属性,以便在重用此 UserControl 时可以设置它们。嵌套控件将使用 ItemSource 的属性,但 ItemSource 属性的属性名称可能不同。

用户控件:

<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}" />

【问题讨论】:

    标签: wpf xaml user-controls datatemplate


    【解决方案1】:

    为此,您需要将 TextBlocks Text-Binding 的 Path-property 绑定到 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>
    

    【讨论】:

      猜你喜欢
      • 2013-03-23
      • 2013-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2018-04-26
      • 2017-02-21
      • 2012-09-06
      • 2015-08-02
      相关资源
      最近更新 更多