I'm building a WinUI 3.0 Application and I need to change DataGrid cell's color depend on it's value, like this:
But nothing worked so far... The Microsoft's document doesn't make it clear enough: [ styling_formatting_options ]
Is there any way to do this Programatically in WinUi 3.0?
I have query many data, but they are related to WPF, not for WinUI 3.0.
You can create a derived class from DataGridTextColumn
and override GenerateElement()
:
using CommunityToolkit.WinUI.UI.Controls;
using Microsoft.UI.Xaml.Media;
using Microsoft.UI.Xaml;
using System.Collections.Generic;
using Windows.UI;
namespace DataGridTests;
public class DataGridTextColumnEx : DataGridTextColumn
{
public Dictionary<string, Color> ValueToColorDictionary
{
get => (Dictionary<string, Color>)GetValue(ValueToColorDictionaryProperty);
set => SetValue(ValueToColorDictionaryProperty, value);
}
public static readonly DependencyProperty ValueToColorDictionaryProperty = DependencyProperty.Register(
nameof(ValueToColorDictionary),
typeof(Dictionary<string, Color>),
typeof(DataGridTextColumnEx),
new PropertyMetadata(new Dictionary<string, Color>()));
protected override FrameworkElement GenerateElement(DataGridCell cell, object dataItem)
{
if (dataItem is Item item &&
ValueToColorDictionary.TryGetValue(item.Value, out Color color) is true)
{
cell.Background = new SolidColorBrush(color);
}
return base.GenerateElement(cell, dataItem); ;
}
}
We can pass he colors using the DependencyProperty
ValueToColorDictionary.
Now wen can use it like this:
MainWindowViewModel.cs
using CommunityToolkit.Mvvm.ComponentModel;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.Linq;
namespace DataGridTests;
public class Item
{
public string Name { get; set; } = string.Empty;
public string Value { get; set; } = string.Empty;
}
public partial class MainWindowViewModel : ObservableObject
{
[ObservableProperty]
private ObservableCollection<Item> items = new()
{
{ new Item() { Name="Person1", Value="A" } },
{ new Item() { Name="Person2", Value="Z" } },
{ new Item() { Name="Person3", Value="B" } },
{ new Item() { Name="Person4", Value="Z" } },
{ new Item() { Name="Person5", Value="C" } },
};
[ObservableProperty]
private Dictionary<string, Color>valueToDictionary = new()
{
{ "A", Colors.HotPink },
{ "B", Colors.LightGreen },
{ "C", Colors.SkyBlue },
};
}
MainWindow.xaml
<Window
x:Class="DataGridTests.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:local="using:DataGridTests"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:toolkit="using:CommunityToolkit.WinUI.UI.Controls"
mc:Ignorable="d">
<Grid>
<toolkit:DataGrid
AutoGenerateColumns="False"
ItemsSource="{x:Bind ViewModel.Items, Mode=OneWay}">
<toolkit:DataGrid.Columns>
<toolkit:DataGridTextColumn
Width="250"
Binding="{Binding Name}"
FontSize="14"
Header="Name" />
<local:DataGridTextColumnEx
Width="250"
Binding="{Binding Value}"
FontSize="14"
Header="Value"
ValueToColorDictionary="{x:Bind ViewModel.ValueToDictionary, Mode=OneWay}" />
</toolkit:DataGrid.Columns>
</toolkit:DataGrid>
</Grid>
</Window>
What I can suggest is a solution to apply a background color to whole rows of the DataGrid
using events and the code behind file. Unfortunately I do not know any way to access DataGridCell
instances using code.
XAML
In my app, I set an event handler for the LoadingRow
event:
<controls:DataGrid AutoGenerateColumns="False"
ItemsSource="{x:Bind ViewModel.Items}"
SelectedItem="{x:Bind ViewModel.SelectedItem, Mode=TwoWay}"
LoadingRow="OnLoadingRow">
CodeBehind
In the code behind file the event handling code sets the background color of the rows depending on some value of the viewmodel that is related to the row:
private void OnLoadingRow(object sender, DataGridRowEventArgs e)
{
DataGrid dataGrid = (DataGrid) sender;
ViewModelOfRow viewModelOfRow = (ViewModelOfRow)e.Row.DataContext;
if (dataGrid is null)
{
return;
}
switch (viewModelOfRow.SomeProperty)
{
case A:
e.Row.Background = new SolidColorBrush(Colors.Green);
break;
case B:
e.Row.Background = new SolidColorBrush(Colors.Yellow);
break;
default:
break;
}
}
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.