按值获取datagridcell

时间:2013-11-22 11:25:33

标签: c# wpf datagrid datatable datagridcell

我有datagrid,绑定到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;

3 个答案:

答案 0 :(得分:3)

请查看此Change DataGrid cell colour based on values

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;
    }
}

答案 1 :(得分:1)

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

<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>

更新&gt;&gt;&gt;

好的,所以要使用变量值这样做,最好以WPF以数据为中心的方式来做这件事。像往常一样,我们希望使用所有我们需要在UI中显示的属性来创建数据对象。因此,您需要将新的bool属性添加到您在DataGrid中显示的任何数据类型类中...如果您坚持使用{{}},则可以为此添加新列{1}}。

但是,我建议您使用一个类,如果您创建一个类,则必须确保在其中正确实现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>

答案 2 :(得分:1)

通过在DataGridCell上使用Binding.TargetUpdated或Binding.SourceUpdated事件,只要其值发生变化,您就可以使用以下方式动态格式化DataGridCell。

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

  • 在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.
    }