C# 根据值更改DataGrid单元格颜色

C# 根据值更改DataGrid单元格颜色,c#,wpf,xaml,colors,datagrid,C#,Wpf,Xaml,Colors,Datagrid,我有一个WPF数据网格,我想要不同的细胞颜色根据值。我的xaml上有以下代码 Style TargetType="DataGridCell" 但不是只选择一个单元格,而是选择所有行?我遗漏了什么?只需将 <Style TargetType="{x:DataGridCell}" > 但请注意,这将针对所有单元格(您针对的是类型为DataGridCell的所有对象) 如果您想根据单元格类型设置样式,我建议您使用DataTemplateSelector Christian Mose

我有一个WPF数据网格,我想要不同的细胞颜色根据值。我的xaml上有以下代码

Style TargetType="DataGridCell"
但不是只选择一个单元格,而是选择所有行?我遗漏了什么?

只需将

<Style TargetType="{x:DataGridCell}" >

但请注意,这将针对所有单元格(您针对的是类型为
DataGridCell
的所有对象) 如果您想根据单元格类型设置样式,我建议您使用
DataTemplateSelector

Christian Mosers的DataGrid教程中有一个很好的例子:


玩得开心:)

如果您尝试设置数据网格。CellStyle数据上下文将是行,因此如果您想基于一个单元格更改颜色,在特定列中更改颜色可能最容易,特别是因为列可以具有不同的内容,如文本块、组合框和复选框。下面是一个将所有单元格设置为浅绿色的示例,
Name
John

<DataGridTextColumn Binding="{Binding Name}">
    <DataGridTextColumn.ElementStyle>
        <Style TargetType="{x:Type TextBlock}">
            <Style.Triggers>
                <Trigger Property="Text" Value="John">
                    <Setter Property="Background" Value="LightGreen"/>
                </Trigger>
            </Style.Triggers>
        </Style>
    </DataGridTextColumn.ElementStyle>
</DataGridTextColumn>
用法:

<Window.Resources>
    <local:NameToBrushConverter x:Key="NameToBrushConverter"/>
</Window.Resources>
...
<DataGridTextColumn Binding="{Binding Name}">
    <DataGridTextColumn.ElementStyle>
        <Style TargetType="{x:Type TextBlock}">
            <Setter Property="Background" Value="{Binding Name, Converter={StaticResource NameToBrushConverter}}"/>
        </Style>
    </DataGridTextColumn.ElementStyle>
</DataGridTextColumn>

在代码隐藏(VB.NET)中执行此操作


如果你需要设置一定数量的列,H.B.的方法是最好的。但是,如果您在运行时之前不知道要处理多少列,那么下面的代码[read:hack]将起作用。我不确定是否有更好的解决方案,列数未知。我断断续续地花了两天的时间才弄到它,所以不管怎样,我还是坚持

C#

XAML


在我的情况下,转换器必须返回字符串值。我不知道为什么,但它是有效的

*.xaml(通用样式文件,包含在另一个xaml文件中)


这可能对你有帮助。然而,它不是库存WPF数据网格

我将DevExpress与自定义ColorFormatter行为一起使用。我在市场上找不到任何现成的产品。这花了我几天的时间。我的代码附在下面,希望这能帮助其他人

编辑:我使用了POCO视图模型和MVVM,但是如果您愿意,您可以将其更改为不使用POCO

Viewmodel.cs

namespace ViewModel
{
    [POCOViewModel]
    public class Table2DViewModel
    {
        public ITable2DView Table2DView { get; set; }

        public DataTable ItemsTable { get; set; }


        public Table2DViewModel()
        {
        }

        public Table2DViewModel(MainViewModel mainViewModel, ITable2DView table2DView) : base(mainViewModel)
        {
            Table2DView = table2DView;   
            CreateTable();
        }

        private void CreateTable()
        {
            var dt = new DataTable();
            var xAxisStrings = new string[]{"X1","X2","X3"};
            var yAxisStrings = new string[]{"Y1","Y2","Y3"};

            //TODO determine your min, max number for your colours
            var minValue = 0;
            var maxValue = 100;
            Table2DView.SetColorFormatter(minValue,maxValue, null);

            //Add the columns
            dt.Columns.Add(" ", typeof(string));
            foreach (var x in xAxisStrings) dt.Columns.Add(x, typeof(double));

            //Add all the values
            double z = 0;
            for (var y = 0; y < yAxisStrings.Length; y++)
            {
                var dr = dt.NewRow();
                dr[" "] = yAxisStrings[y];
                for (var x = 0; x < xAxisStrings.Length; x++)
                {
                    //TODO put your actual values here!
                    dr[xAxisStrings[x]] = z++; //Add a random values
                }
                dt.Rows.Add(dr);
            }
            ItemsTable = dt;
        }


        public static Table2DViewModel Create(MainViewModel mainViewModel, ITable2DView table2DView)
        {
            var factory = ViewModelSource.Factory((MainViewModel mainVm, ITable2DView view) => new Table2DViewModel(mainVm, view));
            return factory(mainViewModel, table2DView);
        }
    }

}
View.xaml.cs

namespace View
{
    public partial class Table2DView : ITable2DView
    {
        public Table2DView()
        {
            InitializeComponent();
        }

        static ColorScaleFormat defaultColorScaleFormat = new ColorScaleFormat
        {
            ColorMin = (Color)ColorConverter.ConvertFromString("#FFF8696B"),
            ColorMiddle = (Color)ColorConverter.ConvertFromString("#FFFFEB84"),
            ColorMax = (Color)ColorConverter.ConvertFromString("#FF63BE7B")
        };

        public void SetColorFormatter(float minValue, float maxValue, ColorScaleFormat colorScaleFormat = null)
        {
            if (colorScaleFormat == null) colorScaleFormat = defaultColorScaleFormat;
            ConditionBehavior.MinValue = minValue;
            ConditionBehavior.MaxValue = maxValue;
            ConditionBehavior.ColorScaleFormat = colorScaleFormat;
        }
    }
}
DynamicConditionBehavior.cs

namespace Behaviors
{
    public class DynamicConditionBehavior : Behavior<GridControl>
    {
        GridControl Grid => AssociatedObject;

        protected override void OnAttached()
        {
            base.OnAttached();
            Grid.ItemsSourceChanged += OnItemsSourceChanged;
        }

        protected override void OnDetaching()
        {
            Grid.ItemsSourceChanged -= OnItemsSourceChanged;
            base.OnDetaching();
        }

        public ColorScaleFormat ColorScaleFormat { get; set;}
        public float MinValue { get; set; }
        public float MaxValue { get; set; }

        private void OnItemsSourceChanged(object sender, EventArgs e)
        {
            var view = Grid.View as TableView;

            if (view == null) return;

            view.FormatConditions.Clear();

            foreach (var col in Grid.Columns)
            {
                view.FormatConditions.Add(new ColorScaleFormatCondition
                {
                    MinValue = MinValue,
                    MaxValue = MaxValue,
                    FieldName = col.FieldName,
                    Format = ColorScaleFormat,
                });
            }

        }
    }
}
命名空间行为
{
公共类DynamicConditionBehavior:行为
{
GridControl网格=>AssociatedObject;
受保护的覆盖无效附加()
{
base.onatached();
Grid.ItemsSourceChanged+=OnItemsSourceChanged;
}
附加时受保护的覆盖无效()
{
Grid.ItemsSourceChanged-=OnItemsSourceChanged;
base.OnDetaching();
}
公共ColorScaleFormat ColorScaleFormat{get;set;}
公共浮点最小值{get;set;}
公共浮点最大值{get;set;}
私有资源已更改(对象发送方,事件参数e)
{
var view=Grid.view为TableView;
if(view==null)返回;
view.FormatConditions.Clear();
foreach(网格列中的变量列)
{
view.FormatConditions.Add(新建ColorScaleFormatCondition
{
MinValue=MinValue,
MaxValue=MaxValue,
FieldName=col.FieldName,
格式=ColorScaleFormat,
});
}
}
}
}
View.xaml

<UserControl x:Class="View"
             xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
             xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
             xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
             xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
             xmlns:dxmvvm="http://schemas.devexpress.com/winfx/2008/xaml/mvvm" 
             xmlns:ViewModels="clr-namespace:ViewModel"
             xmlns:dxg="http://schemas.devexpress.com/winfx/2008/xaml/grid"
             xmlns:behaviors="clr-namespace:Behaviors"
             xmlns:dxdo="http://schemas.devexpress.com/winfx/2008/xaml/docking"
             DataContext="{dxmvvm:ViewModelSource Type={x:Type ViewModels:ViewModel}}"
             mc:Ignorable="d" d:DesignHeight="300" d:DesignWidth="800">

    <UserControl.Resources>
        <Style TargetType="{x:Type dxg:GridColumn}">
            <Setter Property="Width" Value="50"/>
            <Setter Property="HorizontalHeaderContentAlignment" Value="Center"/>
        </Style>

        <Style TargetType="{x:Type dxg:HeaderItemsControl}">
            <Setter Property="FontWeight" Value="DemiBold"/>
        </Style>
    </UserControl.Resources>

        <!--<dxmvvm:Interaction.Behaviors>
            <dxmvvm:EventToCommand EventName="" Command="{Binding OnLoadedCommand}"/>
        </dxmvvm:Interaction.Behaviors>-->
        <dxg:GridControl ItemsSource="{Binding ItemsTable}"
                     AutoGenerateColumns="AddNew"
                     EnableSmartColumnsGeneration="True">

        <dxmvvm:Interaction.Behaviors >
            <behaviors:DynamicConditionBehavior x:Name="ConditionBehavior" />
            </dxmvvm:Interaction.Behaviors>
            <dxg:GridControl.View>
                <dxg:TableView ShowGroupPanel="False"
                           AllowPerPixelScrolling="True"/>
            </dxg:GridControl.View>
        </dxg:GridControl>
  </UserControl>

基于“卡西奥·博吉”的回答。使用此方法,根本不需要更改XAML

        DataGridTextColumn colNameStatus2 = new DataGridTextColumn();
        colNameStatus2.Header = "Status";
        colNameStatus2.MinWidth = 100;
        colNameStatus2.Binding = new Binding("Status");
        grdComputer_Servives.Columns.Add(colNameStatus2);

        Style style = new Style(typeof(TextBlock));
        Trigger running = new Trigger() { Property = TextBlock.TextProperty, Value = "Running" };
        Trigger stopped = new Trigger() { Property = TextBlock.TextProperty, Value = "Stopped" };

        stopped.Setters.Add(new Setter() { Property = TextBlock.BackgroundProperty, Value = Brushes.Blue });
        running.Setters.Add(new Setter() { Property = TextBlock.BackgroundProperty, Value = Brushes.Green });

        style.Triggers.Add(running);
        style.Triggers.Add(stopped);

        colNameStatus2.ElementStyle = style;

        foreach (var Service in computerResult)
        {
            var RowName = Service;  
            grdComputer_Servives.Items.Add(RowName);
        }

您好大马士革,谢谢您的回复,我有目标类型的DatagridCell,您是对的,因为它影响我的enire行。我只希望一个单元格受到影响,具体取决于该单元格的值。我该怎么做呢?事实上这取决于你的情况。你看到我给你的链接上的例子了吗?关于如何根据对象类型选择样式,有一个非常清楚的示例(在示例中:男孩或女孩)。您的问题相似吗?不,不相似,因为我希望选择单个单元格,而不是像示例中那样选择整行。您可以发布场景的示例代码吗。那会有帮助的。顺便说一句,一种方法是将datagridcell的背景属性与该单元格的值绑定,并使用转换器(从值转换为颜色)。嗨,H.B,谢谢你,这或多或少是我想要的,单元格正在更改,但要根据值进行更改,必须查看值转换器,并连接您发送给我的代码示例,但我认为这是正确的方向,你有我所说的例子吗?Thank uI现在可以根据单元格的值使用浅绿色,但要使用值转换器实现这一点,我不想定义value=“john”希望被触发并根据我将以编程方式设置的条件(cs.file c#)设置颜色,希望我能把自己说清楚。非常感谢你的帮助。这里有很多问题,说明了如何使用值转换器,你真的可以做一些搜索。编辑我的答案以显示等价值转换器。我已经这样做了,实际上我已经实现了一个claa,但它没有正常工作,这就是为什么问u,***
名称空间GridCellColor{public class MyValueConverter:IValueConverter{#region IValueConverter成员对象IValueConverter.Convert(对象值,类型targetType,对象参数,System.Globalization.CultureInfo区域性){if(Convert.ToInt32(value)>0)返回10;else if(Convert.ToInt32(value)==0)返回0;else返回-1;}
但是工作不正常,这就是为什么我问你是否有任何示例,谢谢你的回答。这个类将你的输入整数转换为另一个整数,这将如何改变背景颜色?你需要一个转换器,它返回一个
笔刷
。我希望在运行时完成。我是绑定的
public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
{
    Color color = VSColorTheme.GetThemedColor(EnvironmentColors.ToolWindowBackgroundColorKey);
    return "#" + color.Name;
}
namespace ViewModel
{
    [POCOViewModel]
    public class Table2DViewModel
    {
        public ITable2DView Table2DView { get; set; }

        public DataTable ItemsTable { get; set; }


        public Table2DViewModel()
        {
        }

        public Table2DViewModel(MainViewModel mainViewModel, ITable2DView table2DView) : base(mainViewModel)
        {
            Table2DView = table2DView;   
            CreateTable();
        }

        private void CreateTable()
        {
            var dt = new DataTable();
            var xAxisStrings = new string[]{"X1","X2","X3"};
            var yAxisStrings = new string[]{"Y1","Y2","Y3"};

            //TODO determine your min, max number for your colours
            var minValue = 0;
            var maxValue = 100;
            Table2DView.SetColorFormatter(minValue,maxValue, null);

            //Add the columns
            dt.Columns.Add(" ", typeof(string));
            foreach (var x in xAxisStrings) dt.Columns.Add(x, typeof(double));

            //Add all the values
            double z = 0;
            for (var y = 0; y < yAxisStrings.Length; y++)
            {
                var dr = dt.NewRow();
                dr[" "] = yAxisStrings[y];
                for (var x = 0; x < xAxisStrings.Length; x++)
                {
                    //TODO put your actual values here!
                    dr[xAxisStrings[x]] = z++; //Add a random values
                }
                dt.Rows.Add(dr);
            }
            ItemsTable = dt;
        }


        public static Table2DViewModel Create(MainViewModel mainViewModel, ITable2DView table2DView)
        {
            var factory = ViewModelSource.Factory((MainViewModel mainVm, ITable2DView view) => new Table2DViewModel(mainVm, view));
            return factory(mainViewModel, table2DView);
        }
    }

}
namespace Interfaces
    {
        public interface ITable2DView
        {
            void SetColorFormatter(float minValue, float maxValue, ColorScaleFormat colorScaleFormat);
        }
    }
namespace View
{
    public partial class Table2DView : ITable2DView
    {
        public Table2DView()
        {
            InitializeComponent();
        }

        static ColorScaleFormat defaultColorScaleFormat = new ColorScaleFormat
        {
            ColorMin = (Color)ColorConverter.ConvertFromString("#FFF8696B"),
            ColorMiddle = (Color)ColorConverter.ConvertFromString("#FFFFEB84"),
            ColorMax = (Color)ColorConverter.ConvertFromString("#FF63BE7B")
        };

        public void SetColorFormatter(float minValue, float maxValue, ColorScaleFormat colorScaleFormat = null)
        {
            if (colorScaleFormat == null) colorScaleFormat = defaultColorScaleFormat;
            ConditionBehavior.MinValue = minValue;
            ConditionBehavior.MaxValue = maxValue;
            ConditionBehavior.ColorScaleFormat = colorScaleFormat;
        }
    }
}
namespace Behaviors
{
    public class DynamicConditionBehavior : Behavior<GridControl>
    {
        GridControl Grid => AssociatedObject;

        protected override void OnAttached()
        {
            base.OnAttached();
            Grid.ItemsSourceChanged += OnItemsSourceChanged;
        }

        protected override void OnDetaching()
        {
            Grid.ItemsSourceChanged -= OnItemsSourceChanged;
            base.OnDetaching();
        }

        public ColorScaleFormat ColorScaleFormat { get; set;}
        public float MinValue { get; set; }
        public float MaxValue { get; set; }

        private void OnItemsSourceChanged(object sender, EventArgs e)
        {
            var view = Grid.View as TableView;

            if (view == null) return;

            view.FormatConditions.Clear();

            foreach (var col in Grid.Columns)
            {
                view.FormatConditions.Add(new ColorScaleFormatCondition
                {
                    MinValue = MinValue,
                    MaxValue = MaxValue,
                    FieldName = col.FieldName,
                    Format = ColorScaleFormat,
                });
            }

        }
    }
}
<UserControl x:Class="View"
             xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
             xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
             xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
             xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
             xmlns:dxmvvm="http://schemas.devexpress.com/winfx/2008/xaml/mvvm" 
             xmlns:ViewModels="clr-namespace:ViewModel"
             xmlns:dxg="http://schemas.devexpress.com/winfx/2008/xaml/grid"
             xmlns:behaviors="clr-namespace:Behaviors"
             xmlns:dxdo="http://schemas.devexpress.com/winfx/2008/xaml/docking"
             DataContext="{dxmvvm:ViewModelSource Type={x:Type ViewModels:ViewModel}}"
             mc:Ignorable="d" d:DesignHeight="300" d:DesignWidth="800">

    <UserControl.Resources>
        <Style TargetType="{x:Type dxg:GridColumn}">
            <Setter Property="Width" Value="50"/>
            <Setter Property="HorizontalHeaderContentAlignment" Value="Center"/>
        </Style>

        <Style TargetType="{x:Type dxg:HeaderItemsControl}">
            <Setter Property="FontWeight" Value="DemiBold"/>
        </Style>
    </UserControl.Resources>

        <!--<dxmvvm:Interaction.Behaviors>
            <dxmvvm:EventToCommand EventName="" Command="{Binding OnLoadedCommand}"/>
        </dxmvvm:Interaction.Behaviors>-->
        <dxg:GridControl ItemsSource="{Binding ItemsTable}"
                     AutoGenerateColumns="AddNew"
                     EnableSmartColumnsGeneration="True">

        <dxmvvm:Interaction.Behaviors >
            <behaviors:DynamicConditionBehavior x:Name="ConditionBehavior" />
            </dxmvvm:Interaction.Behaviors>
            <dxg:GridControl.View>
                <dxg:TableView ShowGroupPanel="False"
                           AllowPerPixelScrolling="True"/>
            </dxg:GridControl.View>
        </dxg:GridControl>
  </UserControl>
        DataGridTextColumn colNameStatus2 = new DataGridTextColumn();
        colNameStatus2.Header = "Status";
        colNameStatus2.MinWidth = 100;
        colNameStatus2.Binding = new Binding("Status");
        grdComputer_Servives.Columns.Add(colNameStatus2);

        Style style = new Style(typeof(TextBlock));
        Trigger running = new Trigger() { Property = TextBlock.TextProperty, Value = "Running" };
        Trigger stopped = new Trigger() { Property = TextBlock.TextProperty, Value = "Stopped" };

        stopped.Setters.Add(new Setter() { Property = TextBlock.BackgroundProperty, Value = Brushes.Blue });
        running.Setters.Add(new Setter() { Property = TextBlock.BackgroundProperty, Value = Brushes.Green });

        style.Triggers.Add(running);
        style.Triggers.Add(stopped);

        colNameStatus2.ElementStyle = style;

        foreach (var Service in computerResult)
        {
            var RowName = Service;  
            grdComputer_Servives.Items.Add(RowName);
        }