XAML 使用特定颜色为第三行着色

3bygqnnd  于 2022-12-07  发布在  其他
关注(0)|答案(2)|浏览(111)

我已经看了很多关于如何改变行的背景颜色的例子,但是所有的例子都是基于行中的值。有没有其他方法来给特定的行号着色?我有一个项目,其中只有第三行得到绿色背景颜色。另一个项目要求行1到5得到橙色背景颜色。
我的第一个想法是添加一个索引列并填充它,然后根据该值设置背景行颜色。这是唯一的方法吗?

<DataGrid x:Name="grdRes" ItemsSource="{Binding Path=DvAirports, Mode=OneWay}" 
          HeadersVisibility="Column" AutoGenerateColumns="False" IsReadOnly="True" SelectionMode="Single" SelectionUnit="FullRow" 
          CanUserAddRows="False" CanUserDeleteRows="False"
          Style="{DynamicResource Esri_DataGrid}" Margin="0,0,0,31">
<DataGrid.Columns>
    <DataGridTextColumn Header="Origin" Binding="{Binding Origin}"/>
    <DataGridTextColumn Header="Proximity" Binding="{Binding Proximity}"/>
    <DataGridTextColumn Header="NAME" Binding="{Binding NAME}"/>
    <DataGridTextColumn Header="Range" Binding="{Binding Range, StringFormat=N2}"/>
</DataGrid.Columns>
46qrfjad

46qrfjad1#

最后我添加了一个Idx字段,然后将其关闭。我还隐藏了该列,因为分析不需要它。网格是CanUserSortColumns=“false”,因此用户无法对行进行排序。它的工作方式就像我希望的那样。

<DataGrid x:Name="grdRes" ItemsSource="{Binding Path=DvAirports, Mode=OneWay}" 
      HeadersVisibility="Column" AutoGenerateColumns="False" IsReadOnly="True" SelectionMode="Single" SelectionUnit="FullRow" 
      CanUserAddRows="False" CanUserDeleteRows="False" CanUserSortColumns="false"
      Style="{DynamicResource Esri_DataGrid}" Margin="0,0,0,31">

<DataGrid.Columns>
    <DataGridTextColumn Header="Origin" Binding="{Binding Origin}"/>
    <DataGridTextColumn Header="Proximity" Binding="{Binding Proximity}"/>
    <DataGridTextColumn Header="NAME" Binding="{Binding NAME}"/>
    <DataGridTextColumn Header="Range" Binding="{Binding Range, StringFormat=N2}"/>
    <DataGridTextColumn Header="Idx" Binding="{Binding Idx}" Visibility="Hidden"/>
</DataGrid.Columns>

<DataGrid.RowStyle>
    <Style TargetType="DataGridRow">
        <Style.Triggers>
            <DataTrigger Binding="{Binding Idx}" Value="2">
                <!--if its the third row (Idx=2) then color green--> 
                <Setter Property="Background" Value="Green"></Setter>
            </DataTrigger>
        </Style.Triggers>
    </Style>
</DataGrid.RowStyle>
wmvff8tz

wmvff8tz2#

一般信息
突出显示任何项都应该基于数据,而不是项控件中任何项的索引。原因很简单,视图中的索引和数据项之间没有可以保留的关联。当排序、筛选、分组或任何移动索引及其相应项的操作(如删除或插入项)时,会使项控件中的索引引用不同的项。
理想情况下,您应该公开一个表示特殊情况的属性,您可以为该属性添加触发器以适应可视状态。这可以像bool一样简单,就像IsSpecial一样,甚至可以像int一样简单,因为数据索引具有传达含义的。正如您已经展示的,这可以使用样式来完成。

<DataGrid.RowStyle>
   <Style TargetType="DataGridRow">
      <Style.Triggers>
         <DataTrigger Binding="{Binding IsSpecial}" Value="True">
            <Setter Property="Background" Value="Green"/>
         </DataTrigger>
      </Style.Triggers>
   </Style>
</DataGrid.RowStyle>

特殊情况脏

尽管不可见和脏,但如果您的应用程序中不需要交替索引,则有一种方法可以使用显示索引为行着色。交替索引用于为 n 行分别着色,其中 n 是交替计数。为此,提供了一个附加属性AlternationIndex。现在,如果您将AlternationCount设置为项数,AlternationIndex属性有效地提供了视图中的索引。

<DataGrid ItemsSource="{Binding YourItems}"
          AlternationCount="{Binding YourItems.Count}"
          ...>
   <DataGrid.RowStyle>
      <Style TargetType="DataGridRow">
         <Style.Triggers>
            <Trigger Property="AlternationIndex" Value="2">
               <Setter Property="Background" Value="Red"/>
            </Trigger>
         </Style.Triggers>
      </Style>
   </DataGrid.RowStyle>
</DataGrid>

您需要一个公开Count属性(如ObservableCollection<T>List<T>)的集合,或者一个公开项数(如Length)的数组。请注意,这种方法也存在上述问题,因此只有在索引和相应项始终保持不变的情况下,才可使用这种方法。

索引范围

如果要使用特殊模式检查范围或索引,可以创建一个转换器。

public class IsInRangeConverter : IValueConverter
{
   public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
   {
      if (!(value is int intValue) || !(parameter is string rangeString))
         return Binding.DoNothing;

      var range = rangeString.Split(",");
      if (range.Length != 2 ||
          !int.TryParse(range[0], out var lowerLimit) ||
          !int.TryParse(range[1], out var upperLimit) ||
          lowerLimit < 0 ||
          upperLimit < 0 ||
          lowerLimit > upperLimit)
         return Binding.DoNothing;

      return intValue >= lowerLimit && intValue <= upperLimit;
   }

   public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
   {
      throw new InvalidOperationException();
   }
}

然后,您可以使用DataTrigger中的转换器,并将范围作为参数传递。

<DataGrid ItemsSource="{Binding StringItems}"
          AlternationCount="{Binding StringItems.Count}"
          ...>
   <DataGrid.Resources>
      <local:IsInRangeConverter x:Key="IsInRangeConverter"/>
   </DataGrid.Resources>
   <DataGrid.RowStyle>
      <Style TargetType="DataGridRow">
         <Style.Triggers>
            <DataTrigger Binding="{Binding (ItemsControl.AlternationIndex), RelativeSource={RelativeSource Self}, Converter={StaticResource IsInRangeConverter}, ConverterParameter='3,5'}" Value="True">
               <Setter Property="Background" Value="Red"/>
            </DataTrigger>
         </Style.Triggers>
      </Style>
   </DataGrid.RowStyle>
</DataGrid>

如果需要绑定范围边界,则需要创建multi value converter

相关问题