如何通过MultiDataTrigger在WPF DataGrid上具有选定行的替代背景色

问题描述

我想在WPF DataGrid显示具有不同背景颜色(灰色)的奇数行与偶数行。我已经将RowBackground="#DDD"本身的AlternatingRowBackground="#EEE"AlternationCount=2DataGrid属性Style.Triggers本身一起使用来改变未选择的行的颜色。

我已经在StackOverflow上浏览了很多线程,但是找不到<DataGrid.RowStyle> <Style targettype="DataGridRow"> <!-- Changes the row style template to have more advanced "borders" (dotted,dashed,etc.) based on value converters --> <Setter Property="Template"> <!-- ... --> </Setter> <!-- Changes the background color of odd rows (will do the same for even one with a slightly different color) --> <Style.Triggers> <multidatatrigger> <multidatatrigger.Conditions> <Condition Binding="{Binding IsSelected,RelativeSource={RelativeSource Self}}" Value="True"/> <Condition Binding="{Binding (behaviors:DataGridBehavior.IsOddRow),RelativeSource={RelativeSource Self}}" Value="True"/> </multidatatrigger.Conditions> <multidatatrigger.Setters> <Setter Property="Background" Value="LightYellow"/> </multidatatrigger.Setters> </multidatatrigger> <!-- Same principle for even rows --> <!-- ... --> </Style.Triggers> </Style> </DataGrid.RowStyle> 无效的原因。我使用此attached property来确定它是奇数行还是偶数行。

Condition

如果我在MutliDataTrigger中仅使用一个const CPromise= require("c-promise2"); // cancellable sleep function sleep(ms,signal) { return new CPromise((resolve,reject,{onCancel}) => { const timer = setTimeout(resolve,ms); onCancel(() => clearTimeout(timer)); },{signal}).catch(() => {}); } (async()=>{ const sleeper= sleep(30000); socket.on("end_sleep",function(){ sleeper.cancel(); }); await sleeper; })(); ,则效果相同(否)。

感谢您的见解:-)

解决方法

您不必为此使用自定义行为,可以使用内置的交替机制。

<DataGrid AlternationCount="2"
          ...>
   <!-- ...other properties -->
</DataGrid>

使用DataGridRowAlternationIndex附加属性的触发器为IsSelected创建样式。请注意,我们也必须在此处设置行背景色和交替背景色,因为在DataGrid上设置RowBackgroundAlternatingRowBackground将会覆盖样式和选择突出显示将不起作用,因此请将它们从DataGrid中删除。

<DataGrid.RowStyle>
   <Style TargetType="{x:Type DataGridRow}" BasedOn="{StaticResource {x:Type DataGridRow}}">

      <!-- Changes the row style template to have more advanced "borders" (dotted,dashed,etc.) based on value converters -->
      <Setter Property="Template">
         <!-- ... -->
      </Setter>

      <!-- Part for odd rows. -->
      <Style.Triggers>
         <MultiTrigger>
            <MultiTrigger.Conditions>
               <Condition Property="IsSelected"
                          Value="False"/>
               <Condition Property="AlternationIndex"
                          Value="1"/>
            </MultiTrigger.Conditions>
            <MultiTrigger.Setters>
               <Setter Property="Background"
                       Value="#EEE"/>
            </MultiTrigger.Setters>
         </MultiTrigger>

         <MultiTrigger>
            <MultiTrigger.Conditions>
               <Condition Property="IsSelected"
                          Value="True"/>
               <Condition Property="AlternationIndex"
                          Value="1"/>
            </MultiTrigger.Conditions>
            <MultiTrigger.Setters>
               <Setter Property="Background"
                       Value="Yellow"/>
            </MultiTrigger.Setters>
         </MultiTrigger>

         <!-- Part for even rows. -->

         <MultiTrigger>
            <MultiTrigger.Conditions>
               <Condition Property="IsSelected"
                          Value="False"/>
               <Condition Property="AlternationIndex"
                          Value="0"/>
            </MultiTrigger.Conditions>
            <MultiTrigger.Setters>
               <Setter Property="Background"
                       Value="#DDD"/>
            </MultiTrigger.Setters>
         </MultiTrigger>

         <MultiTrigger>
            <MultiTrigger.Conditions>
               <Condition Property="IsSelected"
                          Value="True"/>
               <Condition Property="AlternationIndex"
                          Value="0"/>
            </MultiTrigger.Conditions>
            <MultiTrigger.Setters>
               <Setter Property="Background"
                       Value="LightYellow"/>
            </MultiTrigger.Setters>
         </MultiTrigger>

      </Style.Triggers>

   </Style>
</DataGrid.RowStyle>

由于DataGridCellDataGridRow的子级,因此在那里定义的选择颜色将遮盖行颜色。为了避免也为DataGridCell创建相同的样式,我们在选择背景时将其背景设置为透明。

<DataGrid.CellStyle>
   <Style TargetType="{x:Type DataGridCell}" BasedOn="{StaticResource {x:Type DataGridCell}}">
      <Style.Triggers>
         <DataTrigger Binding="{Binding IsSelected,RelativeSource={RelativeSource AncestorType={x:Type DataGridRow}}}"
                      Value="True">
            <Setter Property="Background"
                    Value="Transparent"/>
         </DataTrigger>
      </Style.Triggers>
   </Style>
</DataGrid.CellStyle>