【问题标题】:C# WPF edit datagrid cell colour based on data lengthC# WPF 根据数据长度编辑数据网格单元格颜色
【发布时间】:2019-01-28 19:40:26
【问题描述】:

我有一个数据网格,如果单元格文本超过 32 个字符,我想将单元格设为红色。

我已经看到其他基于单元格文本何时为特定文本的解决方案,但我不确定如何在此处使用这些解决方案

我的 XAML 如下

<DataGrid Grid.Row="2" Name="DataGridView1" CanUserSortColumns="False" CanUserReorderColumns="False" IsReadOnly="True" ItemsSource="{Binding}" Background="LightGray" RowBackground="#BDBDBF" AlternatingRowBackground="#E3E3E5"></DataGrid>  

为了将我的数据读入一个名为 dt 的 DataTable 中,并执行以下操作。

DataGridView1.DataContext = dt.DefaultView;

更新

使用 Daniel W 的一些代码。我已经让它部分工作,我现在只需要最后润色。

通过执行以下操作,我已使其适用于 1 列:

  <DataGrid  Grid.Row="2" Name="DataGridView1" CanUserSortColumns="False" CanUserReorderColumns="False" IsReadOnly="True" ItemsSource="{Binding}" Background="LightGray" RowBackground="#BDBDBF" AlternatingRowBackground="#E3E3E5">
            <DataGrid.Columns>

                <DataGridTextColumn Binding="{Binding Address1}">
                    <DataGridTextColumn.ElementStyle>
                        <Style TargetType="{x:Type TextBlock}">
                            <Setter Property="Background" Value="{Binding Address1, Converter={StaticResource brushConverter}}">
                            </Setter>
                        </Style>
                    </DataGridTextColumn.ElementStyle>
                </DataGridTextColumn>
            </DataGrid.Columns>
        </DataGrid>  

但是这确实弄乱了我的数据表的格式

https://i.gyazo.com/525ce05a30cad36458a6734d6c61a0ff.png

如您所见,我要编辑的“address1”列没有被编辑,而是在常规列的左侧创建了一个新列。

现在,我无法定义每一列,因为列名可以在运行时更改,所以我不知道我将它绑定到什么

我需要一个仅充当模板的解决方案,因为我的列在我读取 csv 之前没有定义,它可以有任意数量的列/名称,因此我无法对这些列进行数据绑定

有什么想法吗?

【问题讨论】:

    标签: c# wpf colors datagrid cell


    【解决方案1】:

    手动定义的列

    您可以使用基于长度绑定到前景/背景转换字符串的转换器:

    public class LengthToBrush : IValueConverter
    {
        private const int _colorBorders = 0;
        private const int _pow = 2;
    
        public object Convert(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
        {
            var stringValue = value as String;
            if (stringValue == null || stringValue.Length <=32) return new SolidColorBrush(Colors.Black);
            return new SolidColorBrush(Colors.Red);
        }
    
        public object ConvertBack(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
        {
            throw new NotImplementedException();
        }
    }
    

    将转换器添加到资源中

    <Window.Resources>
        <converters:LengthToBrush x:Key="brushConverter"/>
    </Window.Resources>
    

    并在列定义中使用它

    <DataGrid Grid.Row="2" Name="DataGridView1" CanUserSortColumns="False" CanUserReorderColumns="False" IsReadOnly="True" ItemsSource="{Binding}" Background="LightGray" RowBackground="#BDBDBF" AlternatingRowBackground="#E3E3E5">
            <DataGrid.Columns>
    
                <DataGridTextColumn Header="Name" Binding="{Binding Name}" Foreground="{Binding Name, Converter={StaticResource brushConverter}}"/>
    
    
            </DataGrid.Columns>
        </DataGrid>
    

    自动生成的列

    如果你想使用自动生成的列,你必须使用 DataGridCell 的样式

    为此需要一个不同的转换器,如果前景应该是红色的,则返回 true:

    public class LengthToBool : IValueConverter
    {
        private const int _colorBorders = 0;
        private const int _pow = 2;
    
        public object Convert(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
        {
            var stringValue = value as String;            
            if (stringValue == null || stringValue.Length > 12) return true;
            return false;
        }
    
        public object ConvertBack(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
        {
            throw new NotImplementedException();
        }
    }
    

    样式可以在xaml文件中定义:

    <Window.Resources>
        <local:LengthToBool x:Key="lengthConverter"/>
        <Style TargetType="DataGridCell">
            <Style.Triggers>
                <DataTrigger Binding="{Binding RelativeSource={RelativeSource Mode=Self}, 
                           Path=Content.Text, Converter={StaticResource lengthConverter}}" Value="True" >
                    <Setter Property="Foreground" Value="Red" />
                </DataTrigger>
    </Window.Resources>
    

    Data Grid 的定义可以很简单:

        <DataGrid Grid.Row="2" Name="DataGridView1" CanUserSortColumns="False" CanUserReorderColumns="False" IsReadOnly="True" ItemsSource="{Binding Collection}" Background="LightGray" RowBackground="#BDBDBF" AlternatingRowBackground="#E3E3E5">
    
        </DataGrid>
    

    【讨论】:

    • 您好,我已经这样做了,但这并没有奏效,因为我通常不在 xaml 中定义数据列,而是将 csv 作为数据表读取,并将此数据表放入数据网格中这是因为csv 可以有任意数量的任意名称的列所以这段代码只是添加了一个名为“名称”的空白列
    • 我更新了 m 答案以解释如何使用自动生成的列的样式来完成此操作
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2023-03-09
    • 1970-01-01
    • 1970-01-01
    • 2018-02-13
    • 2018-02-02
    相关资源
    最近更新 更多