0

我有 a datagrid,它绑定到 a datatable,每个单元格都有一个唯一的值,所以没有两个单元格具有相同的值。

我想将值为 1 (int32) 的单元格更改为绿色。注意,1 的值是动态的,这只是一个例子,它可以在 1-90 之间。

我已经四处搜索了,大多数帮助都为您提供了基于其坐标的单元格的值,即 (4,2) 或选定的单元格。这不是我想要的,我想根据其值更改单元格的颜色。

有没有办法做到这一点,例如在 JavaScript 中,我只需为每个单元格分配一个与其值相等的 id,然后类似$('#' + 1).css('background-color:green;')(注意:这可能不是正确的语法,但你明白了)。有没有像这样简单的方法或这样做的标准方法?

我的数据网格

<DataGrid Name="grid" ItemsSource="{Binding}" Height="300" Width="900"
          AutoGenerateColumns="True"
          VerticalScrollBarVisibility="Disabled" HorizontalAlignment="Center" VerticalAlignment="Top" RowHeight="40">
            <DataGrid.ItemsPanel>
                <ItemsPanelTemplate>
                    <WrapPanel Orientation="Vertical" />
                </ItemsPanelTemplate>
            </DataGrid.ItemsPanel>
        </DataGrid>

表创建

DataSet dataSet = new DataSet("myDS");
            DataTable numbersTable = new DataTable("Numbers");
            numbersTable.Columns.Add("Number", typeof(Int32));
            for (int i = 1; i < 91; i++)
            {
                numbersTable.Rows.Add(i);
            }
            dataSet.Tables.Add(numbersTable);
            grid.DataContext = numbersTable.DefaultView;
4

3 回答 3

3

根据值查看此更改 DataGrid 单元格颜色

Public class NameToBrushConverter : IValueConverter
{
    public object Convert(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
    {
        string input = value as string;
        switch (input)
        {
            case "John":
                return Brushes.LightGreen;
            default:
                return DependencyProperty.UnsetValue;
        }
    }

    public object ConvertBack(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
    {
        throw new NotSupportedException();
    }
}

网格:

<DataGridTextColumn Binding="{Binding Name}">
    <DataGridTextColumn.ElementStyle>
        <Style TargetType="{x:Type TextBlock}">
            <Setter Property="Background" Value="{Binding Name, Converter={StaticResource NameToBrushConverter}}"/>
        </Style>
    </DataGridTextColumn.ElementStyle>
</DataGridTextColumn>

刷子:

public string Name
{
    get { return _name; }
    set
    {
        if (_name != value)
        {
            _name = value;
            OnPropertyChanged("Name");
            OnPropertyChanged("NameBrush");
        }
    }
}

public Brush NameBrush
{
    get
    {
        switch (Name)
        {
            case "John":
                return Brushes.LightGreen;
        }

        return Brushes.Transparent;
    }
}
于 2013-12-02T08:20:10.437 回答
1

有几种方法可以满足您的要求。这有点不方便,因为我们必须在 the 的列上应用 a Stylewith a而不是在其本身上。这意味着您不能使用该功能,您必须手动定义它们,如下所示。试试这个:TriggerDataGridDataGridAutoGenerateColumns

<DataGrid ItemsSource="{Binding YourItems}" AutoGenerateColumns="False">
    <DataGrid.Resources>
        <Style x:Key="BackgroundColourStyle" TargetType="{x:Type TextBlock}">
            <Style.Triggers>
                <Trigger Property="Text" Value="1">
                    <Setter Property="Background" Value="LightGreen" />
                </Trigger>
            </Style.Triggers>
        </Style>
    </DataGrid.Resources>
    <DataGrid.Columns>
        <DataGridTextColumn Binding="{Binding YourPropertyName}" 
            ElementStyle="{StaticResource BackgroundColourStyle}">
        </DataGridTextColumn>
    </DataGrid.Columns>
</DataGrid>

更新>>>

好的,因此要使用变量值执行此操作,最好以 WPF 以数据为中心的方式执行此操作。与 WPF 中的往常一样,我们希望创建具有我们需要在 UI 中显示的所有属性的数据对象。因此,您需要将新bool属性添加到您在...中显示的任何数据类型类中DataGrid,如果您坚持使用DataTable.

但是,我建议您使用一个类,如果您创建一个类,则必须确保INotifyPropertyChanged在其中正确实现接口。您可以像这样向其中添加属性:

public int NumberValue { get; set; } // implement `INotifyPropertyChanged` here
public bool HasHighlightValue { get; set; } // implement `INotifyPropertyChanged` here

然后我们可以使用这个属性来突出显示中的相关单元格DataGrid

<Style x:Key="BackgroundColourStyle" TargetType="{x:Type TextBlock}">
    <Style.Triggers>
        <Trigger Property="HasHighlightValue" Value="True">
            <Setter Property="Background" Value="LightGreen" />
        </Trigger>
    </Style.Triggers>
</Style>

最后,您可以在处理程序或代码中设置此新属性以响应某些用户操作:

// reset previous cell value
YourDataType previousItem = YourItems.Where(I => i.HasHighlightValue).Single();
previousItem.HasHighlightValue = false;
// set new cell value
YourDataType item = YourItems.Where(I => i.NumberValue == relevantNumber).Single();
item.HasHighlightValue = true;
于 2013-11-22T12:21:02.180 回答
1

当 DataGridCell 的值发生变化时,您还可以使用以下方法动态格式化 DataGridCell,方法是使用 DataGridCell 上的 Binding.TargetUpdated 或 Binding.SourceUpdated 事件。

为此,您必须执行以下操作:

  • 为 DataGrid 上的 AutoGeneratingColumn 事件添加事件处理程序。例如:

<DataGrid ItemsSource="{Binding}" AutoGeneratingColumn="OnAutoGeneratingColumn"/>

  • 在 AutoGeneratingColumn 处理程序中,确定自动生成的列是否具有 Binding,如果有,将其上的 NotifyOnTargetUpdated 设置为 true 并在列上设置 CellStyle,该列将包括 Binding.TargetUpdatedEvent 事件的 EventSetter。例如:

    void OnAutoGeneratingColumn(object sender, DataGridAutoGeneratingColumnEventArgs e)
    {
        BindingBase bindingBase = null;
    
        var dataGridBoundColumn = e.Column as DataGridBoundColumn;
        if (dataGridBoundColumn != null)
        {
            bindingBase = dataGridBoundColumn.Binding;
        }
        else
        {
            var dataGridComboBoxColumn = e.Column as DataGridComboBoxColumn;
            if (dataGridComboBoxColumn != null)
                bindingBase = dataGridComboBoxColumn.SelectedItemBinding;
        }
    
        var binding = bindingBase as Binding;
        if (binding != null)
        {
            binding.NotifyOnTargetUpdated = true;
    
            e.Column.CellStyle = new Style(typeof(DataGridCell))
            {
                Setters = 
                {
                    new EventSetter(Binding.TargetUpdatedEvent, new EventHandler<DataTransferEventArgs>(OnDataGridCellBindingTargetUpdated))
                }
            };
        }
    }
    
  • 当 OnDataGridCellBindingTargetUpdated 处理程序中的值更改时,实现自定义逻辑以格式化 DataGridCell。例如:

    private static void OnDataGridCellBindingTargetUpdated(object sender, DataTransferEventArgs e)
    {
        var dataGridCell = (DataGridCell)sender;
    
        // Get context: column and item.
        var column = dataGridCell.Column;
        var item = dataGridCell.DataContext;
    
        // TODO: based on context, format DataGridCell instance.
    }
    
于 2013-11-29T16:31:28.050 回答