【问题标题】:Change DataTemplate style on the fly via binding通过绑定动态更改 DataTemplate 样式
【发布时间】:2014-08-14 17:22:51
【问题描述】:

我有一个父 DataTemplate 和两个孩子 DataTemplate,并且想要更改子模板的子组件(例如 Label.ForegroundTextBox.Background 等)的一个的属性在触发器上。我遇到了this post,它建议使用RelativeSource 绑定,但经过多次尝试后我无法让它工作,我不确定如何只影响其中一个子模板。下面显示了我预期的最终结果(需要更改任何/所有右子属性以显示它们与左子属性不同)。

DataTemplatexaml:

<DataTemplate x:Key="CoupleDataTemplate">
    <Grid>
        <Grid.ColumnDefinitions>
            <ColumnDefinition Width="1*" />
            <ColumnDefinition Width="Auto" />
            <ColumnDefinition Width="1*" />
        </Grid.ColumnDefinitions>

        <ContentControl Content="{Binding Left}"
                        ContentTemplate="{StaticResource PersonDataTemplate}"
                        />
        <Separator Grid.Column="1"
                       Style="{StaticResource {x:Static ToolBar.SeparatorStyleKey}}"/>
        <ContentControl Content="{Binding Right}"
                        ContentTemplate="{StaticResource PersonDataTemplate}"
                        Grid.Column="2"
                        />

            <!-- Does not work, but shows what I'm trying to do. -->
            <!--<ContentControl.Style>
                <Style TargetType="{StaticResource PersonDataTemplate}">
                    <Style.Triggers>
                        <DataTrigger Binding="{Binding
                            RelativeSource={RelativeSource FindAncestor,
                            AncestorType=ListBox},
                            Path=DataContext.IsFirstDifferent}"
                                     Value="True">
                            <Setter Property="Foreground" Value="Red" />
                        </DataTrigger>
                    </Style.Triggers>
                </Style>
            </ContentControl.Style>-->

        </ContentControl>
    </Grid>
</DataTemplate>

CoupleDataTemplate 然后在ListBox 中使用:

<ListBox ItemsSource="{Binding Couples}"
         ItemTemplate="{StaticResource CoupleDataTemplate}">
    <ListBox.ItemContainerStyle>
        <Style TargetType="ListBoxItem">
            <Setter Property="HorizontalContentAlignment" Value="Stretch" />
        </Style>
    </ListBox.ItemContainerStyle>
</ListBox>

Couples 属性是

public ObservableCollection<Couple> Couples { get; private set; }

我尝试了各种不同的触发器绑定,但均无济于事。我想要做的甚至可能吗?如果是这样,我错过了什么?

每个请求的 PersonDataTemplate

<DataTemplate x:Key="PersonDataTemplate">
    <Grid>
        <Grid.RowDefinitions>
            <RowDefinition Height="Auto" />
            <RowDefinition Height="Auto" />
            <RowDefinition Height="Auto" />
        </Grid.RowDefinitions>
        <Grid.ColumnDefinitions>
            <ColumnDefinition Width="Auto" />
            <ColumnDefinition />
        </Grid.ColumnDefinitions>

        <Label Grid.Row="0" Grid.Column="0"
               HorizontalAlignment="Right"
               Name="FirstLabel"
               Content="First:"
               />
        <TextBox Grid.Row="0" Grid.Column="1"
                 HorizontalAlignment="Stretch"
                 Name="FirstTextBox"
                 Text="{Binding First}"
                 />
        <Label Grid.Row="1" Grid.Column="0"
               HorizontalAlignment="Right"
               Name="LastLabel"
               Content="Last:"
               />
        <TextBox Grid.Row="1" Grid.Column="1"
                 HorizontalAlignment="Stretch"
                 Name="LastTextBox"
                 Text="{Binding Last}"
                 />
        <Label Grid.Row="2" Grid.Column="0"
               HorizontalAlignment="Right"
               Name="SexLabel"
               Content="Sex:"
               />
        <ComboBox Grid.Row="2" Grid.Column="1"
                  HorizontalAlignment="Stretch"
                  Name="Sex"
                  ItemsSource="{Binding SexTypes, Mode=OneWay}"
                  SelectedItem="{Binding Sex}"
                  />
    </Grid>
</DataTemplate>

【问题讨论】:

  • 添加PersonDataTemplate的来源,{Binding Couples}属于哪种类型?如果是 IList,那么绑定 DataContext.IsFirstDifferent 是没有意义的。

标签: c# wpf binding datatemplate


【解决方案1】:

嗯,有人给出了答案,但出于某种原因将其删除。它给了我绑定到Foreground 属性的想法。他们曾建议在CoupleDataTemplate 中使用ContentControl.Tag 属性,但这实际上并不适用于多个子组件属性。

从删除的答案演变而来的解决方案是使用与DataContext.IsFirstDifferent 属性的相对绑定,并使用IValueConverterbool 转换为颜色。因此,对于PersonDataTemplate 中的每个Label,我创建了一个自定义相对绑定。例如:

<Label Grid.Row="0" Grid.Column="0"
       HorizontalAlignment="Right"
       Name="FirstLabel"
       Content="First:"
       Foreground="{Binding Path=DataContext.IsFirstDifferent,
            RelativeSource={RelativeSource
            Mode=FindAncestor, AncestorType={x:Type ContentControl}},
            Converter={StaticResource IsDifferentConverter}}"
       />

IsDifferentConverter 来源在哪里:

public class DifferenceConverter : IValueConverter
{
    public object Convert(object value, Type targetType,
        object parameter, System.Globalization.CultureInfo culture)
    {
        return ((Boolean)value) ? "Red" : "Black";
    }

    public object ConvertBack(object value, Type targetType,
        object parameter, System.Globalization.CultureInfo culture)
    {
        return null;
    }

}

【讨论】:

    猜你喜欢
    • 2012-10-04
    • 2018-01-10
    • 2020-12-15
    • 2016-08-04
    • 1970-01-01
    • 1970-01-01
    • 2015-09-25
    • 2021-07-10
    • 2016-01-11
    相关资源
    最近更新 更多