LoadingRow 이벤트를 통해 프로그래밍 방식으로 행 색상을 교체하고 있습니다. 그 이유는 일부 행, 즉 삭제 표시된 행과 수정 된 데이터가있는 행에 특정 색상을 지정해야하기 때문입니다.
이것은 DataGrid에서 위로 스크롤하고 행 색상을 두 배 또는 세 배로 늘리는 매우 이상한 상호 작용을 얻을 때까지 잘 작동합니다.
아래로 스크롤 할 때 올바르게 표시됩니다.
AlternationCount를 2로 설정 한 상태에서 AlternationIndex를 사용해 보았고 bool을 사용하여 사이를 전환하면 둘 다 똑같은 문제가 발생합니다.
LoadingRow 이벤트에서 이것을 설정하지 않고 DataGrid AlternatingRowBackground를 사용하면 테이블을 스크롤 할 때 행 색상이 다른 행으로 번집니다.
private void dataGrid_LoadingRow(object sender, DataGridRowEventArgs e)
{
// Get the DataRow corresponding to the DataGridRow that is loading.
var item = e.Row.Item as ExpandoObject;
if (loadedTable.ToDelete.Contains(item))
{
e.Row.Background = new SolidColorBrush(Colors.OrangeRed);
return;
}
else if (loadedTable.Modified.Contains(loadedTable.Rows.IndexOf(item)))
{
e.Row.Background = new SolidColorBrush(Colors.LightYellow);
return;
}
else if (e.Row.AlternationIndex == 0)
{
e.Row.Background = new SolidColorBrush(Colors.WhiteSmoke);
}
else if (e.Row.AlternationIndex == 1)
{
e.Row.Background = new SolidColorBrush(Colors.LightGray);
}
}
<DataGrid CanUserAddRows="False" GridLinesVisibility="All" VerticalGridLinesBrush="Gray" HorizontalGridLinesBrush="Gray"
FontSize="15" FrozenColumnCount ="1" x:Name="xmlData" EnableRowVirtualization="True" AlternationCount="1"
AlternatingRowBackground="LightGray" Background="WhiteSmoke"
Grid.Column="1" Margin="0,-31,5,10" AutoGenerateColumns="False" Grid.Row="2" SelectionUnit="Cell"
PreviewKeyDown="DataGridKeyDown_Event" IsReadOnly="True" CanUserDeleteRows="True"
LoadingRow="dataGrid_LoadingRow"/>
문제는 DataGrid가 DataGridRow 개체를 재사용하기 때문입니다 (EnableRowVirtualization = "False"를 시도 할 수 있음).
원하는 것은 스타일을 사용하여 데이터 / 항목을 기반으로 DataGridRow의 배경을 설정하는 것입니다.
다음은 원하는 작업을 수행하는 테스트 앱입니다.
XAML
<Window x:Class="WpfApp9.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:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:local="clr-namespace:WpfApp9"
mc:Ignorable="d"
Title="MainWindow" Height="450" Width="800">
<Window.DataContext>
<local:VM />
</Window.DataContext>
<Grid>
<DataGrid AutoGenerateColumns="False" ItemsSource="{Binding Items}" AlternationCount="2">
<DataGrid.Resources>
<!-- Converter used to convert the DataRow's Item and the VM.ToDelete list to bool (true = it is deleted) -->
<local:IsDeletedConverter x:Key="IsDeletedConverter" />
</DataGrid.Resources>
<DataGrid.RowStyle>
<Style TargetType="DataGridRow">
<Style.Triggers>
<!-- Setup the background color for normal rows using AlternationIndex -->
<Trigger Property="ItemsControl.AlternationIndex" Value="0">
<Setter Property="Background" Value="WhiteSmoke" />
</Trigger>
<Trigger Property="ItemsControl.AlternationIndex" Value="1">
<Setter Property="Background" Value="LightGray" />
</Trigger>
<!-- Override the above background colors if it is in the deleted list - NOTE: these styles are processed in order, make sure this is after the above triggers -->
<DataTrigger Value="True">
<DataTrigger.Binding>
<MultiBinding Converter="{StaticResource IsDeletedConverter}">
<!-- This is the DataContext of the DataGridRow - the item (ExpandoObject) we will check for in the deleted list -->
<Binding />
<!-- Need the deleted list, which is in VM -->
<Binding RelativeSource="{RelativeSource AncestorType=Window}" Path="DataContext" />
</MultiBinding>
</DataTrigger.Binding>
<DataTrigger.Setters>
<Setter Property="Background" Value="OrangeRed" />
</DataTrigger.Setters>
</DataTrigger>
</Style.Triggers>
</Style>
</DataGrid.RowStyle>
<DataGrid.Columns>
<DataGridTextColumn Header="Col1" Binding="{Binding Col1}" />
<DataGridTextColumn Header="Col2" Binding="{Binding Col2}" />
</DataGrid.Columns>
</DataGrid>
</Grid>
암호
using System;
using System.Collections.Generic;
using System.Globalization;
using System.Windows;
using System.Windows.Data;
namespace WpfApp9
{
public partial class MainWindow : Window
{
public MainWindow()
{
InitializeComponent();
}
}
public class VM
{
public List<System.Dynamic.ExpandoObject> Items { get; set; }
public List<System.Dynamic.ExpandoObject> ToDelete { get; set; }
public VM()
{
Items = new List<System.Dynamic.ExpandoObject>();
ToDelete = new List<System.Dynamic.ExpandoObject>();
for (int i = 0; i < 1000; i++)
{
var eo = new System.Dynamic.ExpandoObject();
var d = eo as IDictionary<string, object>;
d["Col1"] = $"String {i}";
d["Col2"] = i;
Items.Add(eo);
// Add some items to ToDelete list
if (i % 10 == 0)
{
ToDelete.Add(eo);
}
}
}
}
public class IsDeletedConverter : IMultiValueConverter
{
public object Convert(object[] values, Type targetType, object parameter, CultureInfo culture)
{
if (values.Length != 2)
throw new ArgumentException($"IsDeletedConverter is expecting 2 values but got {values.Length} values!", nameof(values));
if (values[0] is System.Dynamic.ExpandoObject eo && values[1] is VM vm)
{
if (vm.ToDelete.Contains(eo))
return true;
}
return false;
}
public object[] ConvertBack(object value, Type[] targetTypes, object parameter, CultureInfo culture)
{
throw new NotImplementedException();
}
}
}
이 기사는 인터넷에서 수집됩니다. 재 인쇄 할 때 출처를 알려주십시오.
침해가 발생한 경우 연락 주시기 바랍니다[email protected] 삭제
몇 마디 만하겠습니다