WPF中DataTrigger内Converter未触发,求正确实现方案
问题分析与解决
当前写法的问题
你的代码存在两个核心问题:
- 绑定上下文错误:
DataTrigger的Setter中,Binding Path="Row.ExamBlockType"的默认上下文是RowControl本身,但RowControl的DataContext是DevExpress的RowData对象,直接写Row.ExamBlockType无法正确定位到数据实体的属性。 - Trigger优先级冲突:若
IsStatusRead=true的条件满足,第一个DataTrigger会先设置背景为Khaki,后续DataTrigger即便条件符合也不会生效——Style的Trigger按声明顺序执行,同一属性的Setter不会被后续Trigger覆盖。
此外,直接在Binding内实例化Converter的方式虽可行,但不利于复用,也可能引发绑定解析异常。
修正后的写法
步骤1:在资源中声明Converter实例
<Window.Resources> <valueConverters:ExamBlockTypeToBackgroundBrush x:Key="ExamBlockTypeBrushConverter" /> </Window.Resources>
步骤2:调整RowStyle的Trigger逻辑
通过MultiDataTrigger避免优先级冲突,确保两种状态不会互相覆盖:
<dxg:TableView.RowStyle> <Style TargetType="{x:Type dxg:RowControl}"> <Setter Property="Height" Value="{StaticResource examRowHeight}" /> <Setter Property="Background" Value="Transparent" /> <Style.Triggers> <!-- 仅当IsRecordingFileOpened为true且IsStatusRead为false时应用Converter转换的背景 --> <MultiDataTrigger> <MultiDataTrigger.Conditions> <Condition Binding="{Binding Row.IsRecordingFileOpened, UpdateSourceTrigger=PropertyChanged}" Value="true" /> <Condition Binding="{Binding Row.IsStatusRead, UpdateSourceTrigger=PropertyChanged}" Value="false" /> </MultiDataTrigger.Conditions> <Setter Property="Background" Value="{Binding Row.ExamBlockType, Converter={StaticResource ExamBlockTypeBrushConverter}}" /> </MultiDataTrigger> <!-- IsStatusRead为true时优先设置Khaki背景 --> <DataTrigger Binding="{Binding Row.IsStatusRead, UpdateSourceTrigger=PropertyChanged}" Value="true"> <Setter Property="Background" Value="Khaki" /> </DataTrigger> </Style.Triggers> </Style> </dxg:TableView.RowStyle>
其他实现方式
1. 使用DevExpress内置条件格式化
无需手写Converter和Trigger,直接通过FormatConditions配置更简洁:
<dxg:TableView> <dxg:TableView.FormatConditions> <!-- 匹配IsStatusRead=true的行 --> <dxg:FormatCondition FieldName="IsStatusRead" Value="true"> <dxg:Format Background="Khaki" /> </dxg:FormatCondition> <!-- 匹配IsRecordingFileOpened=true的行,通过Converter转换背景 --> <dxg:FormatCondition Expression="[IsRecordingFileOpened] == true"> <dxg:Format> <dxg:Format.Background> <Binding Path="Row.ExamBlockType" Converter="{StaticResource ExamBlockTypeBrushConverter}" /> </dxg:Format.Background> </dxg:Format> </dxg:FormatCondition> </dxg:TableView.FormatConditions> </dxg:TableView>
2. ViewModel层直接控制背景色
在数据实体类中添加计算属性,通过业务逻辑直接返回背景色,再绑定到行控件:
public class YourRowData : INotifyPropertyChanged { // 原有属性 public bool IsStatusRead { get; set; } public bool IsRecordingFileOpened { get; set; } public ExamBlockType ExamBlockType { get; set; } // 计算背景色属性 public Brush RowBackground { get { if (IsStatusRead) return Brushes.Khaki; if (IsRecordingFileOpened) { var converter = new ExamBlockTypeToBackgroundBrush(); return (Brush)converter.Convert(ExamBlockType, typeof(Brush), null, CultureInfo.CurrentCulture); } return Brushes.Transparent; } } // 属性变更通知,注意触发RowBackground的更新 public event PropertyChangedEventHandler PropertyChanged; private void OnPropertyChanged(string propName) { PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propName)); if (propName != nameof(RowBackground)) { OnPropertyChanged(nameof(RowBackground)); } } }
XAML绑定:
<dxg:TableView.RowStyle> <Style TargetType="{x:Type dxg:RowControl}"> <Setter Property="Height" Value="{StaticResource examRowHeight}" /> <Setter Property="Background" Value="{Binding Row.RowBackground}" /> </Style> </dxg:TableView.RowStyle>
3. 使用CellStyle替代RowStyle
若RowStyle的背景被单元格样式覆盖,可改用CellStyle控制整行背景:
<dxg:TableView.CellStyle> <Style TargetType="{x:Type dxg:CellContentPresenter}"> <Setter Property="Height" Value="{StaticResource examRowHeight}" /> <Style.Triggers> <MultiDataTrigger> <MultiDataTrigger.Conditions> <Condition Binding="{Binding RowData.Row.IsRecordingFileOpened}" Value="true" /> <Condition Binding="{Binding RowData.Row.IsStatusRead}" Value="false" /> </MultiDataTrigger.Conditions> <Setter Property="Background" Value="{Binding RowData.Row.ExamBlockType, Converter={StaticResource ExamBlockTypeBrushConverter}}" /> </MultiDataTrigger> <DataTrigger Binding="{Binding RowData.Row.IsStatusRead}" Value="true"> <Setter Property="Background" Value="Khaki" /> </DataTrigger> </Style.Triggers> </Style> </dxg:TableView.CellStyle>
内容的提问来源于stack exchange,提问作者Riccardo Zamuner
相关产品推荐
相关产品推荐

