简体   繁体   中英

Change BorderBrush Colour of Wpf DatagridTemplateColumn dynamically

In my wpf project I made a IMultiValueConverter that would change the Foreground of my DataGridCells like this:

class CellForegroundMultiValueConverter : IMultiValueConverter
{
    #region Implementation of IMultiValueConverter

    /// <inheritdoc />
    public object Convert(object[] values, Type targetType, object parameter, CultureInfo culture)
    {
        SolidColorBrush mainred = new SolidColorBrush(System.Windows.Media.Color.FromRgb(223,70,75));
        var columnHeader = values[0] as string;
        var dataItem = values[1] as Task;
        if( columnHeader.Equals("Status", StringComparison.OrdinalIgnoreCase)
               && dataItem.Status.Equals("Success!", StringComparison.OrdinalIgnoreCase))
        {
            return mainred;
        }
        if( columnHeader.Equals("#", StringComparison.OrdinalIgnoreCase))
        {
            return mainred;
        }
        if( columnHeader.Equals("Proxy"))
        {
            if(dataItem.Proxy)
            {
                return Brushes.LightGreen;
            }
            return mainred;
        }


        return Brushes.White;
    }

    public object[] ConvertBack(object value, Type[] targetTypes, object parameter, CultureInfo culture) => throw new NotSupportedException();

    #endregion
}

Which is linked to my DataGrid here like this:

<DataGrid.CellStyle>
                             <Style TargetType="{x:Type DataGridCell}">
                                    ...
                                    <Setter Property="Foreground">
                                        <Setter.Value>
                                            <MultiBinding>
                                                <MultiBinding.Converter>
                                                    <local:CellForegroundMultiValueConverter />
                                                </MultiBinding.Converter>

                                                <Binding RelativeSource="{RelativeSource Self}" Path="Column.Header"/>
                                                <Binding/>
                                                <Binding Path="HasChanges" />
                                            </MultiBinding>
                                        </Setter.Value>
                                    </Setter>
                                </Style>
                            </DataGrid.CellStyle>

I have a DataGridTemplateColumn that shows the number of items you have in the DataGrid like this:

<DataGridTemplateColumn Width="*" Header="#" MaxWidth="60">
                                    <DataGridTemplateColumn.HeaderStyle>
                                        <Style BasedOn="{StaticResource MaterialDesignDataGridColumnHeader}" TargetType="{x:Type DataGridColumnHeader}">
                                            <Setter Property="HorizontalAlignment" Value="Left" />
                                        </Style>
                                    </DataGridTemplateColumn.HeaderStyle>
                                    <DataGridTemplateColumn.CellStyle>
                                        <Style TargetType="{x:Type DataGridCell}">
                                            <Setter Property="Padding" Value="20"/>
                                            <!--<Setter Property="Height" Value="57"/>-->
                                            <Setter Property="BorderBrush">
                                                <Setter.Value>
                                                    <MultiBinding>
                                                        <MultiBinding.Converter>
                                                            <local:CellForegroundMultiValueConverter />
                                                        </MultiBinding.Converter>

                                                        <Binding RelativeSource="{RelativeSource Self}" Path="Column.Header"/>
                                                        <Binding/>
                                                        <Binding Path="HasChanges" />
                                                    </MultiBinding>
                                                </Setter.Value>
                                            </Setter>
                                        </Style>
                                    </DataGridTemplateColumn.CellStyle>
                                    <DataGridTemplateColumn.CellTemplate>
                                        <DataTemplate>
                                            <Border Background="#262626" CornerRadius="5,5,5,5" BorderThickness="2" BorderBrush="{Binding StatusColour}">
                                                <Border.Style>
                                                    <Style TargetType="Border">

                                                    </Style>
                                                </Border.Style>
                                                <TextBlock Text="{Binding NumberOTasks}" FontWeight="Bold" HorizontalAlignment="Center" VerticalAlignment="Center" FontSize="15" Foreground="#E43D47"/>
                                            </Border>
                                        </DataTemplate>
                                    </DataGridTemplateColumn.CellTemplate>
                                </DataGridTemplateColumn>

If I put the IMultiValueConverter in the DataGridTemplateColumn.CellStyle it works and adds the colour for the border, but it isn't affected by the cornerradius of the border, but if I put it on the border style, it doesn't work and says the column header is = null. How would I be able to change the borderbrush and it be affected by the border's cornerradius?

To change the inner grid borders, you need to override the default template for the DataGridCell and modify the border properties from there. Keep in mind there are two templates for a ContentControl : a ControlTemplate for the ContentControl itself (eg ListBoxItem or DataGridCell ) and the DataTemplate for the content of the ContentControl .

<DataGridTemplateColumn.CellStyle>
  <Style TargetType="DataGridCell">
    <Setter Property="Background" Value="#262626">
    <Setter Property="BorderBrush">
      <Setter.Value>
        <MultiBinding>
          <MultiBinding.Converter>
            <local:CellForegroundMultiValueConverter />
          </MultiBinding.Converter>

          <Binding RelativeSource="{RelativeSource Self}" Path="Column.Header"/>
          <Binding/>
          <Binding Path="HasChanges" />
        </MultiBinding>
      </Setter.Value>
    </Setter>

    <Setter Property="Template">
      <Setter.Value>
        <ControlTemplate TargetType="DataGridCell">
          <Border BorderThickness="{TemplateBinding BorderThickness}"
                  BorderBrush="{TemplateBinding BorderBrush}" 
                  Background="{TemplateBinding Background}" 
                  CornerRadius="5">
            <ContentPresenter />
          </Border>
        </ControlTemplate>
      </Setter.Value>
    </Setter>
  </Style>
</DataGridTemplateColumn.CellStyle>

You can set a cell style for each column or use a global cell style based on a value:

<DataGrid xmlns:system="clr-namespace:System;assembly=mscorlib">
  <DataGrid.Resources>
   <Style TargetType="DataGridCell">
    <Style.Triggers>
     <DataTrigger Binding="{Binding}"
                  Value="Proxy">
      <Setter Property="Foreground"
              Value="LightGreen" />
      <Setter Property="BorderBrush"
              Value="LightGreen" />
     </DataTrigger>
     <DataTrigger Binding="{Binding}"
                  Value="#">
      <Setter Property="Foreground"
              Value="Gray" />
      <Setter Property="BorderBrush"
              Value="Red" />
     </DataTrigger>
    </Style.Triggers>
   </Style>
  </DataGrid.Resources>
  <DataGrid.Columns>
   <DataGridTextColumn Binding="{Binding}"
                       Header="#" />
   <DataGridTextColumn Binding="{Binding}"
                       Header="Proxy" />
   <DataGridTextColumn  Binding="{Binding}"
                        Header="Status">
    <DataGridTextColumn.CellStyle>
     <Style TargetType="DataGridCell">
      <Setter  Property="Foreground"
               Value="Blue" />
      <Setter  Property="BorderBrush"
               Value="Blue" />
     </Style>
    </DataGridTextColumn.CellStyle>
   </DataGridTextColumn>
  </DataGrid.Columns>
  <system:String>Proxy</system:String>
  <system:String>#</system:String>
  <system:String>Success</system:String>
 </DataGrid> 

The result should look like this:
在此处输入图片说明

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM