WPF MVVM中DataGrid的ComboBox列实现交替行背景绑定
问题描述
我已经修改了ComboBox的Style,将ComboBox内部ToggleButton的Background绑定到ComboBox自身的Background属性(这是让ToggleButton跟随ComboBox背景色的可行方式),相关Style代码如下:
... <Style x:Key="ComboBoxToggleButton" TargetType="{x:Type ToggleButton}"> ... <Setter Property="Template"> <Setter.Value> <ControlTemplate TargetType="{x:Type ToggleButton}"> <Border x:Name="templateRoot" BorderBrush="{StaticResource ComboBox.Static.Border}" BorderThickness="{TemplateBinding BorderThickness}" Background="{TemplateBinding Background}" SnapsToDevicePixels="true"> <!-- 绑定位置 --> <Border x:Name="splitBorder" BorderBrush="Transparent" BorderThickness="1" HorizontalAlignment="Right" Margin="0" SnapsToDevicePixels="true" Width="{DynamicResource {x:Static SystemParameters.VerticalScrollBarWidthKey}}"> <Path x:Name="arrow" Data="F1 M 0,0 L 2.667,2.66665 L 5.3334,0 L 5.3334,-1.78168 L 2.6667,0.88501 L0,-1.78168 L0,0 Z" Fill="{StaticResource ComboBox.Static.Glyph}" HorizontalAlignment="Center" Margin="0" VerticalAlignment="Center"/> </Border> </Border> <ControlTemplate.Triggers> ...
此时单独使用<ComboBox Background="Yellow" />可以正常生效,ToggleButton的背景会同步变成黄色。
现在我有一个包含ComboBox列的DataGrid,希望让ComboBox的Background自动跟随DataGrid的交替行颜色,当前代码如下:
<DataGrid AutoGenerateColumns="False" Name="datagrid1" Height="auto" ItemsSource="{Binding SourceList}" SelectedItem="{Binding SelectedSource}" BorderThickness="1" AlternatingRowBackground="#FFFFFFCC" HorizontalGridLinesBrush="#FFA0A0A0" VerticalGridLinesBrush="#FFA0A0A0" SelectionUnit="FullRow" HeadersVisibility="Column" GridLinesVisibility="Horizontal" CanUserResizeRows="False" VerticalContentAlignment="Center" BorderBrush="DarkGray" HorizontalAlignment="Stretch"> <DataGrid.Columns> <DataGridTextColumn Header="NameText" Binding="{Binding NameText}" Width="*"/> <DataGridTemplateColumn Width = "*" Header = "Names"> <DataGridTemplateColumn.CellTemplate> <DataTemplate> <ComboBox VerticalContentAlignment = "Center" ItemsSource = "{Binding DataContext.NamesList, RelativeSource ={RelativeSource Findancestor, AncestorType = { x:Type Window}}}" SelectedItem="{Binding Name, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}" DisplayMemberPath="Name"> <ComboBox.Style> <Style TargetType="ComboBox" BasedOn="{StaticResource {x:Type ComboBox}}"> <Setter Property="Background" Value="Yellow"/> <Style.Triggers> <DataTrigger Binding="{Binding Path=ItemsControl.AlternationIndex, ElementName=datagrid1}" Value="1"> <Setter Property="Background" Value="#FFFFFFCC"></Setter> </DataTrigger> </Style.Triggers> </Style> </ComboBox.Style> </ComboBox> </DataTemplate> </DataGridTemplateColumn.CellTemplate> </DataGridTemplateColumn> </DataGrid.Columns> </DataGrid>
请问该如何实现让ComboBox背景跟随DataGrid交替行颜色的需求?
解决方案
当前代码的核心问题是:DataTemplate有独立的命名作用域,无法通过ElementName=datagrid1直接绑定外部DataGrid的AlternationIndex;同时硬写颜色值不够灵活,最好直接绑定DataGrid的AlternatingRowBackground属性。
具体修改步骤如下:
- 给
DataGrid显式添加AlternationCount="2",确保交替行逻辑正常触发(仅设置AlternatingRowBackground有时不会自动开启交替机制)。 - 修改
ComboBox的Style,通过RelativeSource找到当前所在的DataGridRow来绑定AlternationIndex,同时绑定DataGrid的AlternatingRowBackground属性,避免硬编码颜色值。
修改后的ComboBox.Style代码:
<ComboBox.Style> <Style TargetType="ComboBox" BasedOn="{StaticResource {x:Type ComboBox}}"> <!-- 默认背景色,与DataGrid普通行背景保持一致 --> <Setter Property="Background" Value="White"/> <Style.Triggers> <!-- 绑定当前行的AlternationIndex --> <DataTrigger Binding="{Binding AlternationIndex, RelativeSource={RelativeSource AncestorType=DataGridRow}}" Value="1"> <!-- 绑定DataGrid的交替行背景色 --> <Setter Property="Background" Value="{Binding AlternatingRowBackground, RelativeSource={RelativeSource AncestorType=DataGrid}}"/> </DataTrigger> </Style.Triggers> </Style> </ComboBox.Style>
同时在DataGrid标签中补充AlternationCount属性:
<DataGrid AutoGenerateColumns="False" Name="datagrid1" ... AlternationCount="2" AlternatingRowBackground="#FFFFFFCC" ...>
修改完成后,交替行内的ComboBox会自动继承DataGrid的交替行背景色,普通行则使用默认背景色,同时解决了DataTemplate命名作用域导致的绑定失效问题。
内容的提问来源于stack exchange,提问作者Yannick
相关产品推荐
相关产品推荐

