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
相关产品推荐
相关产品推荐

