You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何根据IsValid状态修改ItemsControl内TextBlock与TextBox的前景色?

问题描述

我定义了如下类:

public class ShippingMethodMap
{
    public string ShippingMethod { get; set; }
    public int? MethodId { get; set; }
    public bool IsManaged { get; set; }
    public bool IsValid { get; set; }
}

数据存储在ObservableCollection<ShippingMethodMap> ShippingMethodMapCollection中,并通过以下XAML代码展示:

<ItemsControl ItemsSource="{Binding Path=ShippingMethodMapCollection}">
    <ItemsControl.ItemTemplate>
        <DataTemplate>
            <Border Margin="1" BorderThickness="1" BorderBrush="LightGray">
                <Grid>
                    <Grid.ColumnDefinitions>
                        <ColumnDefinition Width="*"/>
                        <ColumnDefinition Width="50"/>
                    </Grid.ColumnDefinitions>
                    <TextBlock Grid.Column="0"
                               Text="{Binding Path=ShippingMethod}">
                    </TextBlock>
                    <TextBox Grid.Column="1"
                             Text="{Binding Path=MethodId}"
                             IsEnabled="{Binding Path=IsManaged}">
                    </TextBox>
                </Grid>
            </Border>
        </DataTemplate>
    </ItemsControl.ItemTemplate>
</ItemsControl>

请问当ShippingMethodMap.IsValid为false时,如何将对应项的TextBlock和TextBox的前景色设置为红色?


解决方案

可以通过WPF的DataTrigger实现这个需求,下面提供几种常用的实现方式:

方式一:通过父元素继承前景色(最简洁)

利用WPF的属性继承特性,给外层Border添加DataTrigger,当IsValid为false时设置前景色为红色,内部的TextBlock和TextBox会自动继承这个属性:

<ItemsControl ItemsSource="{Binding Path=ShippingMethodMapCollection}">
    <ItemsControl.ItemTemplate>
        <DataTemplate>
            <Border Margin="1" BorderThickness="1" BorderBrush="LightGray">
                <Border.Style>
                    <Style TargetType="Border">
                        <Style.Triggers>
                            <DataTrigger Binding="{Binding IsValid}" Value="False">
                                <Setter Property="Foreground" Value="Red"/>
                            </DataTrigger>
                        </Style.Triggers>
                    </Style>
                </Border.Style>
                <Grid>
                    <Grid.ColumnDefinitions>
                        <ColumnDefinition Width="*"/>
                        <ColumnDefinition Width="50"/>
                    </Grid.ColumnDefinitions>
                    <TextBlock Grid.Column="0"
                               Text="{Binding Path=ShippingMethod}">
                    </TextBlock>
                    <TextBox Grid.Column="1"
                             Text="{Binding Path=MethodId}"
                             IsEnabled="{Binding Path=IsManaged}">
                    </TextBox>
                </Grid>
            </Border>
        </DataTemplate>
    </ItemsControl.ItemTemplate>
</ItemsControl>

方式二:定义共享样式复用逻辑

在Grid的资源中定义通用样式,让TextBlock和TextBox共用这个样式,避免重复代码:

<ItemsControl ItemsSource="{Binding Path=ShippingMethodMapCollection}">
    <ItemsControl.ItemTemplate>
        <DataTemplate>
            <Border Margin="1" BorderThickness="1" BorderBrush="LightGray">
                <Grid>
                    <Grid.Resources>
                        <Style TargetType="FrameworkElement" x:Key="InvalidForegroundStyle">
                            <Style.Triggers>
                                <DataTrigger Binding="{Binding IsValid}" Value="False">
                                    <Setter Property="Foreground" Value="Red"/>
                                </DataTrigger>
                            </Style.Triggers>
                        </Style>
                    </Grid.Resources>
                    <Grid.ColumnDefinitions>
                        <ColumnDefinition Width="*"/>
                        <ColumnDefinition Width="50"/>
                    </Grid.ColumnDefinitions>
                    <TextBlock Grid.Column="0"
                               Text="{Binding Path=ShippingMethod}"
                               Style="{StaticResource InvalidForegroundStyle}">
                    </TextBlock>
                    <TextBox Grid.Column="1"
                             Text="{Binding Path=MethodId}"
                             IsEnabled="{Binding Path=IsManaged}"
                             Style="{StaticResource InvalidForegroundStyle}">
                    </TextBox>
                </Grid>
            </Border>
        </DataTemplate>
    </ItemsControl.ItemTemplate>
</ItemsControl>

注:TextBlock和TextBox都继承自FrameworkElement,因此这个通用样式可同时作用于两者。

方式三:单独给每个控件添加触发器

如果不需要复用样式,可直接给TextBlock和TextBox分别添加DataTrigger:

<ItemsControl ItemsSource="{Binding Path=ShippingMethodMapCollection}">
    <ItemsControl.ItemTemplate>
        <DataTemplate>
            <Border Margin="1" BorderThickness="1" BorderBrush="LightGray">
                <Grid>
                    <Grid.ColumnDefinitions>
                        <ColumnDefinition Width="*"/>
                        <ColumnDefinition Width="50"/>
                    </Grid.ColumnDefinitions>
                    <TextBlock Grid.Column="0"
                               Text="{Binding Path=ShippingMethod}">
                        <TextBlock.Style>
                            <Style TargetType="TextBlock">
                                <Style.Triggers>
                                    <DataTrigger Binding="{Binding IsValid}" Value="False">
                                        <Setter Property="Foreground" Value="Red"/>
                                    </DataTrigger>
                                </Style.Triggers>
                            </Style>
                        </TextBlock.Style>
                    </TextBlock>
                    <TextBox Grid.Column="1"
                             Text="{Binding Path=MethodId}"
                             IsEnabled="{Binding Path=IsManaged}">
                        <TextBox.Style>
                            <Style TargetType="TextBox">
                                <Style.Triggers>
                                    <DataTrigger Binding="{Binding IsValid}" Value="False">
                                        <Setter Property="Foreground" Value="Red"/>
                                    </DataTrigger>
                                </Style.Triggers>
                            </Style>
                        </TextBox.Style>
                    </TextBox>
                </Grid>
            </Border>
        </DataTemplate>
    </ItemsControl.ItemTemplate>
</ItemsControl>

内容的提问来源于stack exchange,提问作者Alexey Titov

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.17 11:04:52