【问题标题】:Change colour of single cell in DataGrid when selected, overriding current colour选中时更改 DataGrid 中单个单元格的颜色,覆盖当前颜色
【发布时间】:2020-11-09 11:04:38
【问题描述】:

我有这段代码会影响DataGrid 的整行:

<DataGrid x:Name="tblopenRequests" ItemsSource="{Binding}" Grid.Column="1" Grid.Row="2" 
          IsReadOnly="true" RowHeaderWidth="0" AutoGenerateColumns="False" CanUserAddRows="False" SelectionMode="Single">
   <DataGrid.Resources>
      <Style BasedOn="{StaticResource {x:Type DataGridColumnHeader}}" TargetType="{x:Type DataGridColumnHeader}" >
         <Setter Property="Background" Value="LightSeaGreen" />
         <Setter Property="Foreground" Value="white" />
         <Setter Property="BorderBrush" Value="Black"/>
         <Setter Property="BorderThickness" Value="1 1 1 1"/>
         <Setter Property="Margin" Value="-1,-1,0,0" />
         <Setter Property="Height" Value="28" />
         <Setter Property="Width" Value="auto"/>
         <Setter Property="HorizontalContentAlignment" Value="Center"/>
      </Style>
      <Style TargetType="DataGridCell">
         <Setter Property="HorizontalContentAlignment" Value="Right" />

         <Style.Triggers>
            <Trigger Property="DataGridCell.IsSelected" Value="True">
               <Setter Property="Background" Value="Goldenrod" />
               <Setter Property="BorderBrush" Value="white" />
               <Setter Property="Foreground" Value="black" />
               <Setter Property="FontWeight" Value="Bold" />
               <Setter Property="FontSize" Value="15"/>
            </Trigger>
         </Style.Triggers>

      </Style>

   </DataGrid.Resources>

我现在想用不同的格式覆盖行中的一个单元格以更加突出。

这就是我目前所拥有的,但我的尝试总是失败。

<DataGridTextColumn Binding="{Binding expectedDate}" Header="Expected Date" Width="90">
   <DataGridTextColumn.ElementStyle>
      <Style TargetType="TextBlock">
         <Setter Property="HorizontalAlignment" Value="center" />
      </Style>
   </DataGridTextColumn.ElementStyle>
</DataGridTextColumn>

我已尝试在此处添加触发器并仅对单元格着色。但是,这并没有做任何事情,只是在资源部分中保留了上述代码中的橙色。

我只需要这个粉红色/浅红色而不是橙色的单元格,但我找不到具有此答案的网站或论坛文章。

【问题讨论】:

  • 橙色?我没有在你的代码/XAML 中找到 Orange。
  • @GlennAngel:您知道DataGridColumn 有一个CellStyle 属性,您可以为每个单独的列设置一个Style
  • 谢谢@mm8 我会调查这个问题和答案。 WPF 上第一次有这么大的学习曲线!

标签: wpf xaml datagrid


【解决方案1】:

感谢 @thatguy。上层对我帮助很大。值得一提的是,这是关于 stackoverflow 和使用 AutoGenerateColumns="True" 的网络的众多答案之一。

条件颜色也可以在后面的代码中完成:

<DataGrid.CellStyle>
            <Style TargetType="DataGridCell">                     
                <Style.Triggers>                         
                    <DataTrigger Binding="{Binding Column.Header, RelativeSource={RelativeSource Self}}" Value="Expected Date">
                        <Setter Property="Background" Value="{Binding SomeColor}" />
                    </DataTrigger>
                </Style.Triggers>
            </Style>
  </DataGrid.CellStyle>

例如:

public SolidColorBrush SomeColor
{
    get
    {
         return IsDifferent ? new SolidColorBrush(System.Windows.Media.Color.FromArgb(255, 255, 139, 0)) : new SolidColorBrush(System.Windows.Media.Color.FromArgb(139, 255, 139, 0));
    }
 } 

【讨论】:

    【解决方案2】:

    带绑定的单单元格样式

    在您的单元格样式中,您可以引用关联的列并识别它,例如通过比较它的Header

    <DataGrid.CellStyle>
       <Style TargetType="DataGridCell">
          <!-- ...other setters. -->
          <Style.Triggers>
             <!-- ...other triggers. -->
             <DataTrigger Binding="{Binding Column.Header, RelativeSource={RelativeSource Self}}" Value="Expected Date">
                <Setter Property="Background" Value="Pink" />
             </DataTrigger>
          </Style.Triggers>
       </Style>
    </DataGrid.CellStyle>
    

    根据应更改颜色的状态,您可能需要使用MultiDataTrigger 来仅在选定状态下更改颜色。

    <MultiDataTrigger>
       <MultiDataTrigger.Conditions>
          <Condition Binding="{Binding IsSelected, RelativeSource={RelativeSource Self}}" Value="True" />
          <Condition Binding="{Binding Column.Header, RelativeSource={RelativeSource Self}}" Value="Expected Date" />
       </MultiDataTrigger.Conditions>
       <Setter Property="Background" Value="Pink" />
    </MultiDataTrigger>
    

    使用Header 标识列很麻烦并且容易出错。不幸的是,您可以使用的列上没有内置的唯一标识符。但是,您可以创建附加属性。

    public static class DataGridColumnProperties
    {
       public static readonly DependencyProperty IdentifierProperty = DependencyProperty.RegisterAttached("Identifier",
          typeof(string), typeof(DataGridColumnProperties), new PropertyMetadata(null));
    
       public static string GetIdentifier(DependencyObject dependencyObject)
       {
          return (string)dependencyObject.GetValue(IdentifierProperty);
       }
    
       public static void SetIdentifier(DependencyObject dependencyObject, string value)
       {
          dependencyObject.SetValue(IdentifierProperty, value);
       }
    }
    

    使用此附加属性,您可以在列上设置标识符。

    <DataGridTextColumn local:DataGridColumnProperties.Identifier="ExpectedDate" ...>
    

    你可以这样引用它:

    <DataTrigger Binding="{Binding Column.(local:DataGridColumnProperties.Identifier), RelativeSource={RelativeSource Self}}" Value="ExpectedDate">
       <Setter Property="Background" Value="Pink" />
    </DataTrigger>
    

    这种方法使您的列定义更加健壮,因为样式独立于Header

    多种单元格样式

    如果您更喜欢使用多种单元格样式,则无需绑定即可解决您的问题。在下文中,我在DataGrid 中创建了所有样式,但您可以将它们移动到任何资源字典中。

    定义适用于大多数列的常规单元格样式,此处为RegularCellStyle。这是您问题的风格。然后,为第一列创建一个特殊的样式,这里是SpecialCellStyle

    此样式使用BasedOn 属性从常规样式继承所有设置器和触发器。在这种风格中,您只定义与基本风格相比的变化。在您的情况下,它只是处于选中状态的Background,因此我们为它添加了一个触发器。

    接下来,我们将常规样式应用于DataGrids CellStyle 属性。此样式将应用于所有列。然后我们将特殊样式应用到第一列的CellStyle。列单元格样式将优先。来自documentation

    样式可以应用于表格、列或单元格级别的单元格。要将样式应用于列中的所有单元格,请设置 DataGridColumn.CellStyle 属性。这将优先于 DataGrid.CellStyle 属性。要将样式应用于单个单元格,请直接在 DataGridCell 上设置样式属性。这将优先于应用于单元格的所有其他样式。

    以下是您的示例的完整代码。

    <DataGrid x:Name="tblopenRequests" ItemsSource="{Binding}" Grid.Column="1" Grid.Row="2" 
              IsReadOnly="true" RowHeaderWidth="0" AutoGenerateColumns="False" CanUserAddRows="False" SelectionMode="Single">
       <DataGrid.Resources>
    
          <!-- Style from your question. -->
          <Style x:Key="RegularCellStyle" TargetType="DataGridCell">
             <Setter Property="HorizontalContentAlignment" Value="Right" />
             <Style.Triggers>
                <Trigger Property="DataGridCell.IsSelected" Value="True">
                   <Setter Property="Background" Value="Goldenrod" />
                   <Setter Property="BorderBrush" Value="white" />
                   <Setter Property="Foreground" Value="black" />
                   <Setter Property="FontWeight" Value="Bold" />
                   <Setter Property="FontSize" Value="15" />
                </Trigger>
             </Style.Triggers>
          </Style>
    
          <!-- Special first column style based on the regular style. -->
          <Style x:Key="SpecialCellStyle"
                       BasedOn="{StaticResource RegularCellStyle}"
                       TargetType="DataGridCell">
             <Style.Triggers>
                <Trigger Property="DataGridCell.IsSelected" Value="True">
                   <Setter Property="Background" Value="Pink" />
                </Trigger>
             </Style.Triggers>
          </Style>
    
       </DataGrid.Resources>
       <DataGrid.CellStyle>
          <StaticResource ResourceKey="RegularCellStyle" />
       </DataGrid.CellStyle>
       <DataGrid.ColumnHeaderStyle>
          <Style BasedOn="{StaticResource {x:Type DataGridColumnHeader}}" TargetType="{x:Type DataGridColumnHeader}">
             <Setter Property="Background" Value="LightSeaGreen" />
             <Setter Property="Foreground" Value="white" />
             <Setter Property="BorderBrush" Value="Black" />
             <Setter Property="BorderThickness" Value="1,1,1,1" />
             <Setter Property="Margin" Value="-1,-1,0,0" />
             <Setter Property="Height" Value="28" />
             <Setter Property="Width" Value="auto" />
             <Setter Property="HorizontalContentAlignment" Value="Center" />
          </Style>
       </DataGrid.ColumnHeaderStyle>
       <DataGrid.Columns>
    
          <DataGridTextColumn Binding="{Binding expectedDate}"
                              Header="Expected Date"
                              Width="90"
                              CellStyle="{StaticResource SpecialCellStyle}"/>
    
          <!-- ...other columns WITHOUT cell style will apply the regular style. -->
    
       </DataGrid.Columns>
    </DataGrid>
    

    【讨论】:

      猜你喜欢
      • 2023-03-28
      • 1970-01-01
      • 1970-01-01
      • 2021-04-06
      • 1970-01-01
      • 2016-12-31
      • 1970-01-01
      • 2013-09-29
      • 2018-09-26
      相关资源
      最近更新 更多