【问题标题】:Setting background of a list of rows and columns in WPF在 WPF 中设置行和列列表的背景
【发布时间】:2014-05-14 10:46:16
【问题描述】:

问题

我正在使用 xmlprovider 为数据填充数据网格。加载后,我尝试根据“锁定”行和列的列表为“锁定”列和行着色。这里的“锁定”只是对特定行或列的视觉反馈,不用于进一步计算。虽然数据加载工作正常,但我尝试了不同的解决方案来设置某些行和列的背景属性,方法是使用来自 data grid extensions 的扩展名循环遍历所有单元格,但效果好坏参半。

我尝试为 LOADED 事件中的单元格着色,但这显然并不总是有效。并且没有事件显示:“您的数据已加载,先生,现在想做点什么”?

所以我为行和列着色的最后手段可能是使用带有 IMultiValueConverter 类的样式设置器。但我不清楚如何将正确的数据发送到转换器。

代码

这是我现在拥有的:

public partial class MainWindow : Window
{
    public ObservableCollection<Person> MyDynData { get; set; }

    // property representing the locked rows
    public List<int> LockedRows { get; set; }
    // property representing the locked colums
    public List<int> LockedColumns { get; set; }

    public MainWindow()
    {
        InitializeComponent();

        MyDynData = Person.GetData();
        LockedRows = new List<int>{1,3};
        LockedColumns = new List<int>{0};

        DataContext = this;
    }
}

public class Person
{
    public string FirstName { get; set; }
    public string LastName { get; set; }
    public int Age { get; set; }

    public static ObservableCollection<Person>GetData()
    {
        return new ObservableCollection<Person>
        {
            new Person {Age = 19, FirstName = "John", LastName = "Gates"},
            new Person {Age = 25, FirstName = "Jill", LastName = "Vegas"},
            new Person {Age = 48, FirstName = "Bill", LastName = "Bates"},
            new Person {Age = 29, FirstName = "Agnes", LastName = "Henderson"},
            new Person {Age = 33, FirstName = "Jenny", LastName = "Giggles"}

        };
    }
}

XAML:

<Window x:Class="DatagridColRowLocker.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:converters="clr-namespace:DatagridColRowLocker"
        Title="MainWindow" Height="350" Width="525">
    <Grid>
        <Grid.Resources>
            <converters:CellBackgroundConverter x:Key="CellBackgroundConverter"/>
        </Grid.Resources>

        <DataGrid ItemsSource="{Binding Path=MyDynData}" AutoGenerateColumns="True">
            <DataGrid.Resources>
                <Style x:Key="LockedCellStyle" TargetType="DataGridCell">
                    <Style.Setters>
                        <Setter Property="Background">
                            <Setter.Value>
                                <MultiBinding Converter="{StaticResource CellBackgroundConverter}">
                                    <Binding> ??? the current cell</Binding>
                                    <Binding> ??? List of locked columns</Binding>
                                    <Binding> ??? list of locked rows</Binding>
                                </MultiBinding>
                            </Setter.Value>
                        </Setter>
                    </Style.Setters>
                </Style>
            </DataGrid.Resources>
        </DataGrid>
    </Grid>
</Window>

单元格背景颜色转换器:

class CellBackgroundConverter : IMultiValueConverter
{
    public object Convert(object[] values, Type targetType, object parameter, CultureInfo culture)
    {
        var cell = (DataGridCell)values[0];
        var lockedColumns = (List<int>)values[1];
        var lockedRows = (List<int>)values[2];

        // how to get the row index? 
        var isLocked = lockedColumns.Contains(cell.Column.DisplayIndex);

        return (isLocked) ? new SolidColorBrush(Colors.LightGray) : new SolidColorBrush(Colors.White);
    }

    public object[] ConvertBack(object value, Type[] targetTypes, object parameter, CultureInfo culture)
    {
        throw new NotImplementedException();
    }
}

总结

  • 如何正确绑定 xaml 中的值以使多转换器工作
  • 如果我将 datagridcell 传递给转换器,我可以获得 displaycolIndex 而不是 rowIndex,这是如何工作的?

【问题讨论】:

    标签: c# wpf binding datagrid imultivalueconverter


    【解决方案1】:

    如果您希望样式应用于所有单元格,请去掉样式上的 x:Key。

    这是您要求的绑定:

    <Style TargetType="DataGridCell">
        <Style.Setters>
            <Setter Property="Background">
                <Setter.Value>
                    <MultiBinding Converter="{StaticResource CellBackgroundConverter}">
                        <Binding RelativeSource="{RelativeSource Self}" />
                        <Binding RelativeSource="{RelativeSource AncestorType=Window}" Path="DataContext.LockedColumns" />
                        <Binding RelativeSource="{RelativeSource AncestorType=Window}" Path="DataContext.LockedRows" />
                        <Binding RelativeSource="{RelativeSource AncestorType=DataGridRow}" />
                    </MultiBinding>
                </Setter.Value>
            </Setter>
        </Style.Setters>
    </Style>
    

    以下是转换器的更改:

    public object Convert(object[] values, Type targetType, object parameter, CultureInfo culture)
    {
        var cell = (DataGridCell)values[0];
        var lockedColumns = (List<int>)values[1];
        var lockedRows = (List<int>)values[2];
        var row = (DataGridRow)values[3];
    
        // how to get the row index? 
        var isLocked = lockedColumns.Contains(cell.Column.DisplayIndex);
        if (!isLocked)
        {
            isLocked = lockedRows.Contains(row.GetIndex());
        }
    
        return (isLocked) ? new SolidColorBrush(Colors.LightGray) : new SolidColorBrush(Colors.White);
    }
    

    【讨论】:

    • 非常感谢 J.H.,这就行了!似乎我需要了解有关“RelativeSource”关键字的更多信息。让我们希望它适用于我的真实世界应用程序:)
    • 不客气。如果有帮助,这里是 WPF 绑定的备忘单。 nbdtech.com/Free/WpfBinding.pdf
    【解决方案2】:

    除了已接受的答案之外,您可能会在选择一行时看到样式问题,如下图所示。 “Bill”右侧的文字是白色的,不可读

    在这种情况下,您可以通过为数据网格添加额外的资源设置来解决此问题:

    <DataGrid.Resources>
        <SolidColorBrush x:Key="{x:Static SystemColors.HighlightTextBrushKey }" Color="Black"></SolidColorBrush>
        <SolidColorBrush x:Key="{x:Static SystemColors.HighlightBrushKey}" Color="Transparent"></SolidColorBrush>
    </DataGrid.Resources>
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2020-10-17
      • 1970-01-01
      • 2013-07-25
      • 2013-05-25
      • 1970-01-01
      • 2011-09-14
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多