简体   繁体   English

如何自定义WinUI 3.0 DataGrid Cell颜色?

[英]How to customize WinUI 3.0 DataGrid Cell color?

I'm building a WinUI 3.0 Application and I need to change DataGrid cell's color depend on it's value, like this:我正在构建一个 WinUI 3.0 应用程序,我需要根据它的值更改 DataGrid 单元格的颜色,如下所示:

1个

But nothing worked so far... The Microsoft's document doesn't make it clear enough: [ styling_formatting_options ]但到目前为止没有任何效果......微软的文档不够清楚:[ styling_formatting_options ]

Is there any way to do this Programatically in WinUi 3.0?有没有办法在 WinUi 3.0 中以编程方式执行此操作?

I have query many data, but they are related to WPF, not for WinUI 3.0.查询了很多数据,都是WPF相关的,不是WinUI 3.0的。

You can create a derived class from DataGridTextColumn and override GenerateElement() :您可以从DataGridTextColumn创建派生的 class 并覆盖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.我们可以使用DependencyProperty ValueToColorDictionary 传递 colors。

Now wen can use it like this:现在我们可以像这样使用它:

MainWindowViewModel.cs 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主窗口.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.我可以建议的是使用事件和文件隐藏代码将背景颜色应用于DataGrid的整行的解决方案。 Unfortunately I do not know any way to access DataGridCell instances using code.不幸的是,我不知道有什么方法可以使用代码访问DataGridCell实例。

XAML XAML

In my app, I set an event handler for the LoadingRow event:在我的应用程序中,我为LoadingRow事件设置了一个事件处理程序:

    <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;
        }
    }

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM