Avalonia UI C# XAML WPF -根据列值调整数据网格行颜色

vyu0f0g1  于 2023-02-25  发布在  C#
关注(0)|答案(3)|浏览(382)
public class EventLogView : UserControl
{
    private DataGrid dataGrid;
    public EventLogView()
    {
        this.InitializeComponent();
        dataGrid = this.FindControl<DataGrid>("EventLogsDataGrid");
        this.dataGrid.LoadingRow += new EventHandler<DataGridRowEventArgs>(dataGrid_LoadingRows);
    } 

    private void InitializeComponent()
    {
        AvaloniaXamlLoader.Load(this);
    }

    void dataGrid_LoadingRows(object sender, DataGridRowEventArgs e)
    {

    }
}

我想改变每行的颜色为红色,如果第4列的值是“高”。

lstz6jyr

lstz6jyr1#

在“纯”WPF中实现此操作的方法是使用DataTrigger定义ItemContainerStyle

<DataGrid x:Name="EventLogsDataGrid"
                  AutoGenerateColumns="False"
                  Items="{Binding LogsData}"
                  CanUserReorderColumns="True"
                  CanUserResizeColumns="True"
                  IsReadOnly="True">
    <DataGrid.ItemContainerStyle>
        <Style TargetType="DataGridRow">
            <Style.Triggers>
                <DataTrigger Binding="{Binding Importance}" Value="HIGH">
                    <Setter Property="Background" Value="Red" />
                </DataTrigger>
            </Style.Triggers>
        </Style>
    </DataGrid.ItemContainerStyle>
    <DataGrid.Columns>
        <DataGridTextColumn Binding="{Binding Id}"
                                Header="ID"
                                Width="Auto"/>
        <DataGridTextColumn Binding="{Binding Content}"
                                Header="Content"
                                Width="Auto"/>
        <DataGridTextColumn Binding="{Binding CreationDate}"
                                Header="Date Time"
                                Width="Auto"/>
        <DataGridTextColumn Binding="{Binding Source}"
                                Header="Source"
                                Width="Auto"/>
        <DataGridTextColumn Binding="{Binding Importance}"
                                Header="Priority"
                                Width="Auto"/>
    </DataGrid.Columns>
</DataGrid>

但是,由于Avalonia不支持触发器,因此您可能必须像这样处理LoadingRow事件,以编程方式设置Background属性:

void dataGrid_LoadingRows(object sender, DataGridRowEventArgs e)
{
    var dataObject = e.Row.DataContext as YourDataObject;
    if (dataObject != null && dataObject.Importance == "HIGH")
        e.Row.Background = Brushes.Red;
}
qmelpv7a

qmelpv7a2#

@mm8:谢谢你的提示!我也在寻找同样的答案,所以就从你的建议开始了。我在对行进行排序,或者修改后重新加载内容时遇到了问题。有几行不符合条件,但附加了背景属性。所以我使用样式来附加/分离样式:

<Window.Styles>
    <Style Selector="DataGridRow.rejectedStatus">
        <Setter Property="Background" Value="Red"/>
        <Setter Property="Foreground" Value="White"/>
    </Style>
</Window.Styles>
private void DataGrid_OnLoadingRow(object? sender, DataGridRowEventArgs e)
{
    var dataObject = e.Row.DataContext as Models.Banknote;
    if (dataObject != null && dataObject.Status == "Rejected")
    {
        e.Row.Classes.Add("rejectedStatus");
    }
    else
    {
        e.Row.Classes.Remove("rejectedStatus");
    }
}
zqry0prt

zqry0prt3#

也许还有另一种方法可以做同样的事情,但是是在XAML中。老实说,我并没有参与这个探索,但它真的很接近。Avalonia.Xaml.Behaviors的作者Wiesław Šoltés已经发布了一个非常有趣的方法的示例。我试图将它用于DataGrid的行,它几乎成功了:

<Window xmlns="https://github.com/avaloniaui"
        xmlns:int="clr-namespace:Avalonia.Xaml.Interactivity;assembly=Avalonia.Xaml.Interactivity"
        xmlns:ia="clr-namespace:Avalonia.Xaml.Interactions.Core;assembly=Avalonia.Xaml.Interactions"        
        x:Class="BvsDesktopLinux.Views.MainWindow" ...>
...
<Window.Styles>
    <Style Selector="DataGridCell.statusColumn">
        <Setter Property="FontSize" Value="24"/>
        <Setter Property="(int:Interaction.Behaviors)">
            <int:BehaviorCollectionTemplate>
                <int:BehaviorCollection>
                    <ia:DataTriggerBehavior Binding="{Binding Status}" ComparisonCondition="Equal" Value="Rejected">
                        <ia:ChangePropertyAction TargetObject="DataGridCell" PropertyName="Background" Value="Red" />
                    </ia:DataTriggerBehavior>
                </int:BehaviorCollection>
            </int:BehaviorCollectionTemplate>
        </Setter>
    </Style>
</Window.Styles>
...
<DataGrid AutoGenerateColumns="False" Margin="10"
          Items="{Binding Banknotes}" SelectedItem="{Binding SelectedBanknote}">
    <DataGrid.Columns>
        <DataGridTextColumn Header="{x:Static p:Resources.NoteId}" Binding="{Binding Id}" />
        <DataGridTextColumn Header="{x:Static p:Resources.NoteCurrency}" Binding="{Binding Currency}" />
        <DataGridTextColumn Header="{x:Static p:Resources.NoteDenomination}" Binding="{Binding Denomination}" />
        <DataGridTextColumn Header="{x:Static p:Resources.Status}" Binding="{Binding Status}" CellStyleClasses="statusColumn" />
    </DataGrid.Columns>
</DataGrid>

代码中只有一个问题-绑定不使用DataGridCell的DataContext(ViewModel中ObservableCollection的元素),但它使用整个视图/窗口(ViewModel)的DataContext。
如果有人知道如何在绑定中指定DataGridCell的DataContext而不是View的DataContext,请帮助!

相关问题