값에 따라 DataGrid 셀 색상 변경
WPF 데이터 그리드가 있고 값에 따라 다른 셀 색상을 원합니다. 내 xaml에 아래 코드가 있습니다.
Style TargetType="DataGridCell"
하지만 셀을 선택하는 대신 모든 행을 선택합니까? 내가 무엇을 놓치고 있습니까?
DataGrid.CellStyle
DataContext를 행 으로 설정하려고하면 한 셀을 기준으로 색상을 변경하려는 경우 특정 열에서 변경하는 것이 가장 쉬울 수 있습니다. 특히 열은 TextBlocks, ComboBoxes 및 CheckBoxes와 같은 다양한 내용을 가질 수 있기 때문입니다. . 여기에 모든 셀 라이트 녹색 어디로 설정하는 예이다 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>
a 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>
또 다른 옵션은 Background
각각의 컬러 브러시를 반환하는 속성에 를 직접 바인딩하는 것입니다. 색상이 종속 된 속성의 setter에서 속성 변경 알림을 실행해야합니다.
예 :
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의 방법이 가장 좋습니다. 그러나 런타임까지 얼마나 많은 열을 다루고 있는지 모르는 경우 아래 코드 [read : hack]이 작동합니다. 알 수없는 수의 열로 더 나은 솔루션이 있는지 확실하지 않습니다. 그것을 얻는 데 이틀이 걸렸습니다. 그래서 나는 그것을 고수하고 있습니다.
씨#
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
) 세포 유형에 따라 스타일을 넣으려면 다음을 사용하는 것이 좋습니다.DataTemplateSelector
Christian Mosers의 DataGrid 튜토리얼에서 좋은 예를 찾을 수 있습니다.
http://www.wpftutorial.net/DataGrid.html#rowDetails
재미있게 보내세요 :)
제 경우에는 변환기가 문자열 값을 반환해야합니다. 이유는 아니지만 작동합니다.
* .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;
}
이것은 당신에게 도움이 될 수 있습니다. 그러나 주식 WPF 데이터 그리드가 아닙니다.
사용자 지정 ColorFormatter 동작과 함께 DevExpress를 사용했습니다. 나는 이것을 상자에서 꺼내는 것을 시장에서 찾을 수 없었다. 개발하는 데 며칠이 걸렸습니다. 내 코드는 아래에 첨부되어 있습니다.
편집 : 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>
// 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;
'Cassio Borghi'의 답변을 기반으로합니다. 이 방법을 사용하면 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);
}
코드 숨김 (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
참고 URL : https://stackoverflow.com/questions/5549617/change-datagrid-cell-colour-based-on-values
'Program Tip' 카테고리의 다른 글
Swift XCTest UI에서 테스트 사이에 앱을 재설정하는 방법이 있습니까? (0) | 2020.11.26 |
---|---|
다른 유형에 대한 반복 (0) | 2020.11.26 |
Rails 콘솔이 lib에서 모듈을 다시로드 할 수 있습니까? (0) | 2020.11.26 |
링크 위로 마우스를 가져갈 때 나타나는 손 모양 커서를 제거 할 수 있습니까? (0) | 2020.11.26 |
Bash / Debian에서 파일 생성 날짜 / 시간을 얻는 방법은 무엇입니까? (0) | 2020.11.26 |