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

WPF MaterialDesignThemes中TreeViewItem触发器修改背景色问题

嘿,我来帮你搞定TreeViewItem背景色不生效的问题!你的思路其实是对的,但WPF的TreeViewItem默认模板有点“顽固”——它的背景并不是直接用控件的Background属性,而是由模板里名为Bd的Border控件控制的,所以你直接设置Background的Setter不会生效。

给你两个靠谱的解决方案:

方案一:修改模板触发器(最直接)

把你的DataTrigger放到TreeViewItem的模板触发器里,直接修改模板中负责显示背景的Border。这样就能绕过默认模板的限制,直接生效:

<Style x:Key="TaskStyle" TargetType="{x:Type TreeViewItem}" BasedOn="{StaticResource {x:Type TreeViewItem}}">
    <Setter Property="Template">
        <Setter.Value>
            <ControlTemplate TargetType="{x:Type TreeViewItem}">
                <Grid>
                    <Grid.ColumnDefinitions>
                        <ColumnDefinition Width="Auto" MinWidth="19"/>
                        <ColumnDefinition Width="*"/>
                    </Grid.ColumnDefinitions>
                    <Grid.RowDefinitions>
                        <RowDefinition Height="Auto"/>
                        <RowDefinition Height="*"/>
                    </Grid.RowDefinitions>
                    <!-- 这里是负责背景的Border -->
                    <Border x:Name="Bd" Grid.Column="1" 
                            Background="{TemplateBinding Background}"
                            BorderBrush="{TemplateBinding BorderBrush}"
                            BorderThickness="{TemplateBinding BorderThickness}"
                            Padding="{TemplateBinding Padding}">
                        <ContentPresenter x:Name="PART_Header"
                                        ContentSource="Header"
                                        HorizontalAlignment="{TemplateBinding HorizontalContentAlignment}"
                                        SnapsToDevicePixels="{TemplateBinding SnapsToDevicePixels}"/>
                    </Border>
                    <ItemsPresenter x:Name="ItemsHost" Grid.Column="1" Grid.Row="1"/>
                </Grid>
                <ControlTemplate.Triggers>
                    <!-- 保留默认的触发器(展开、选中、禁用等) -->
                    <Trigger Property="IsExpanded" Value="false">
                        <Setter TargetName="ItemsHost" Property="Visibility" Value="Collapsed"/>
                    </Trigger>
                    <Trigger Property="HasItems" Value="false">
                        <Setter TargetName="ItemsHost" Property="Visibility" Value="Collapsed"/>
                    </Trigger>
                    <Trigger Property="IsSelected" Value="true">
                        <Setter TargetName="Bd" Property="Background" Value="{DynamicResource {x:Static SystemColors.HighlightBrushKey}}"/>
                        <Setter Property="Foreground" Value="{DynamicResource {x:Static SystemColors.HighlightTextBrushKey}}"/>
                    </Trigger>
                    <MultiTrigger>
                        <MultiTrigger.Conditions>
                            <Condition Property="IsSelected" Value="true"/>
                            <Condition Property="IsSelectionActive" Value="false"/>
                        </MultiTrigger.Conditions>
                        <Setter TargetName="Bd" Property="Background" Value="{DynamicResource {x:Static SystemColors.InactiveSelectionHighlightBrushKey}}"/>
                        <Setter Property="Foreground" Value="{DynamicResource {x:Static SystemColors.InactiveSelectionHighlightTextBrushKey}}"/>
                    </MultiTrigger>
                    <Trigger Property="IsEnabled" Value="false">
                        <Setter Property="Foreground" Value="{DynamicResource {x:Static SystemColors.GrayTextBrushKey}}"/>
                    </Trigger>
                    
                    <!-- 你的DataTrigger,直接修改Bd的背景 -->
                    <DataTrigger Binding="{Binding IsOK}" Value="false">
                        <Setter TargetName="Bd" Property="Background" Value="#7FF90000"/>
                    </DataTrigger>
                </ControlTemplate.Triggers>
            </ControlTemplate>
        </Setter.Value>
    </Setter>
</Style>

方案二:确保DataContext和属性通知正确

除了模板问题,还要检查两个关键点:

  • 你的数据对象要实现INotifyPropertyChanged接口,这样当IsOK的值变化时,UI才会收到通知更新:
public class TaskItem : INotifyPropertyChanged
{
    private bool _isOK;
    public bool IsOK
    {
        get => _isOK;
        set 
        { 
            _isOK = value; 
            OnPropertyChanged(nameof(IsOK)); 
        }
    }

    public event PropertyChangedEventHandler PropertyChanged;
    private void OnPropertyChanged(string propertyName)
    {
        PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
    }
}
  • 确认TreeViewItem的DataContext确实是包含IsOK属性的对象——比如TreeView的ItemsSource绑定的是你的TaskItem集合,每个TreeViewItem的DataContext就是集合里的项。

额外小提示

如果你的半透明红色(#7FF90000)看起来不明显,可以先换成不透明的红色(#FFFF0000)测试,排除透明度的干扰;如果选中状态会覆盖你的背景色,可以调整触发器的顺序,或者用MultiDataTrigger同时判断选中状态和IsOK的值。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.25 04:26:19