根据值更改DataGrid单元格颜色
我有一个WPF数据网格,我想根据值不同的单元格颜色。 我有我的xaml下面的代码
Style TargetType="DataGridCell"
而不是select一个单元格只select所有行? 我错过了什么?
如果您尝试设置DataGrid.CellStyle
那么DataContext将成为行,所以如果您想要根据一个单元格更改颜色,那么在特定列中执行操作可能是最简单的,特别是因为列可以具有不同的内容,例如TextBlocks,combobox和checkbox。 这里是一个设置所有单元格的例子,其中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>
你也可以使用ValueConverter
来改变颜色。
public class NameToBrushConverter : IValueConverter { public object Convert(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture) { string input = value as string; switch (input) { case "John": return Brushes.LightGreen; default: return DependencyProperty.UnsetValue; } } public object ConvertBack(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture) { throw new NotSupportedException(); } }
用法:
<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>
另一个select是将Background
直接绑定到一个属性,该属性返回分别着色的画笔。 您必须在颜色所依赖的属性的设置者中触发属性更改通知。
例如
public string Name { get { return _name; } set { if (_name != value) { _name = value; OnPropertyChanged("Name"); OnPropertyChanged("NameBrush"); } } } public Brush NameBrush { get { switch (Name) { case "John": return Brushes.LightGreen; default: break; } return Brushes.Transparent; } }
如果你需要用一定数量的列来完成,HB的方法是最好的。 但是如果直到运行时才知道要处理多less列,那么下面的代码[read:hack]就可以工作。 我不确定是否有更好的解决scheme,列数不详。 我花了两天的时间去研究它,所以我坚持不懈。
C#
public class ValueToBrushConverter : IValueConverter { public object Convert(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture) { int input; try { DataGridCell dgc = (DataGridCell)value; System.Data.DataRowView rowView = (System.Data.DataRowView)dgc.DataContext; input = (int)rowView.Row.ItemArray[dgc.Column.DisplayIndex]; } catch (InvalidCastException e) { return DependencyProperty.UnsetValue; } switch (input) { case 1: return Brushes.Red; case 2: return Brushes.White; case 3: return Brushes.Blue; default: return DependencyProperty.UnsetValue; } } public object ConvertBack(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture) { throw new NotSupportedException(); } }
XAML
<UserControl.Resources> <conv:ValueToBrushConverter x:Key="ValueToBrushConverter"/> <Style x:Key="CellStyle" TargetType="DataGridCell"> <Setter Property="Background" Value="{Binding RelativeSource={RelativeSource Self}, Converter={StaticResource ValueToBrushConverter}}" /> </Style> </UserControl.Resources> <DataGrid x:Name="dataGrid" CellStyle="{StaticResource CellStyle}"> </DataGrid>
只是换而言之
<Style TargetType="{x:DataGridCell}" >
但是要注意,这将把所有的单元格(你瞄准的是DataGridCell
types的所有对象)如果你想根据单元格types放置一个样式,我build议你使用一个DataTemplateSelector
在Christian Mosers的DataGrid教程中可以find一个很好的例子:
http://www.wpftutorial.net/DataGrid.html#rowDetails
玩的开心 :)
这可能对你有帮助。 这不是股票的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); } } }
IView.cs
namespace Interfaces { public interface ITable2DView { void SetColorFormatter(float minValue, float maxValue, ColorScaleFormat colorScaleFormat); } }
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, }); } } } }
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>
在我的情况下,转换器必须返回string值。 我不是为什么,但它的作品。
* .xaml (常用样式文件,其中包含另一个xaml文件)
<Style TargetType="DataGridCell"> <Setter Property="Background" Value="{Binding RelativeSource={RelativeSource Self}, Converter={StaticResource ValueToBrushConverter}}" /> </Style>
*的.cs
public object Convert(object value, Type targetType, object parameter, CultureInfo culture) { Color color = VSColorTheme.GetThemedColor(EnvironmentColors.ToolWindowBackgroundColorKey); return "#" + color.Name; }
// Example: Adding a converter to a column (C#) Style styleReading = new Style(typeof(TextBlock)); Setter s = new Setter(); s.Property = TextBlock.ForegroundProperty; Binding b = new Binding(); b.RelativeSource = RelativeSource.Self; b.Path = new PropertyPath(TextBlock.TextProperty); b.Converter = new ReadingForegroundSetter(); s.Value = b; styleReading.Setters.Add(s); col.ElementStyle = styleReading;
在Code Behind(VB.NET)中执行此操作
Dim txtCol As New DataGridTextColumn Dim style As New Style(GetType(TextBlock)) Dim tri As New Trigger With {.Property = TextBlock.TextProperty, .Value = "John"} tri.Setters.Add(New Setter With {.Property = TextBlock.BackgroundProperty, .Value = Brushes.Green}) style.Triggers.Add(tri) xtCol.ElementStyle = style