Avalonia UI C# XAML WPF - настройка цвета строки сетки данных на основе значения столбца
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-го столбца "ВЫСОКОЕ".
3 ответа
Чтобы сделать это в "чистом" WPF, нужно определить ItemContainerStyle
с DataTrigger
:
<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;
}
Может быть и другой способ сделать то же самое, но в 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>
У меня была только одна проблема с кодом — привязка не использует DataContext DataGridCell (элемент ObservableCollection из ViewModel), а использует DataContext всего представления/окна (ViewModel).
@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");
}
}