سؤال

I know that my question was stated and answered in several ways here already. But I just can't get it to run the way I would like. As the title states, I try to change the background color of my datagridcell depending on its content. I am relatively new to WPF, but I guess the solution is a converter combined with a binding. The goal is to change the background colour of the cell in dependence of a property called "Status", which is an enum with four states.

I already wrote a converter:

using System;
using System.Windows.Data;
using System.Drawing;
using System.Windows;

namespace Admin
{
    [ValueConversion(typeof(Member.UserStatus), typeof(Brushes))]
    public class StatusToColorConverter : IValueConverter
    {
        #region IValueConverter Member

        public object Convert(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
        {
            var enumValue = (Member.UserStatus)value;

            if(enumValue == Member.UserStatus.Change)
                return Brushes.Red;
            if(enumValue == Member.UserStatus.Import)
                return Brushes.Blue;
            if(enumValue == Member.UserStatus.Remove)
                return Brushes.Orange;
            if(enumValue == Member.UserStatus.Synced)
                return Brushes.Green;
            else
                return DependencyProperty.UnsetValue;
        }

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

        #endregion
    }
}

So far so good. The xaml part looks like this (after some googling...)

<DataGrid.Columns>              
    <DataGridTemplateColumn Header="Status">
        <DataGridTemplateColumn.CellTemplate>
            <DataTemplate>
                <TextBlock Text="{Binding Status}" Background="{Binding Status, Converter={StaticResource StatusToColorConverter}}"/>
            </DataTemplate>
        </DataGridTemplateColumn.CellTemplate>
    </DataGridTemplateColumn>
</DataGrid.Columns> 

I don't really get (yet) what DataGridTemplateColums and DataTemplates are. But I tried the same with CellStyle and another way that I can't remember. The converter has a breakpoint and gets called in all solutions I tried. But somehow the "Background" property seems to ignore the return value from the converter. So I guess my fault (or my lack of understanding) has another source.

Anyone care to point me in the right direction?

هل كانت مفيدة؟

المحلول 3

Ok guys. I have the problem solved now. The problem wasn't my xaml code. The converter worked also fine. The Problem was the following line in the converter .cs file:

    using System.Drawing;

I replaced it with the correct one:

    using System.Windows.Media;

And now it works like a charm. ... I was passing Brushes for WinForms instead of WPF Brushes!

Thanks for all the help anyway :)

نصائح أخرى

If I interpret your XAML correctly - you are painting the column HEADER (the "topmost" cell), not the cell itself.

This works for me:

<DataGrid.CellStyle>
                <Style TargetType="{x:Type DataGridCell}">
                    <Setter Property="Background" Value="{Binding Status},
                       Converter={StaticResource StatusToColorConverter}">
                    </Setter>
                </Style>
</DataGrid.CellStyle>

This should paint your cell

As a side note: Your cells might look "weird" if you are painting their Background - my cells often lose their Borders etc. A quick and easy fix is to add the following Propertie Setters (it is the default wpf style)

 <Setter Property="BorderThickness" Value="1,0,1,1"></Setter>
 <Setter Property="BorderBrush" Value="#FF000000"></Setter>

I did it this way:

              <DataGrid.CellStyle>
                    <Style TargetType="DataGridCell">
                        <Setter Property="Background">
                            <Setter.Value>
                                <Binding Path="Row" Mode="OneWay" />
                            </Setter.Value>
                        </Setter>
                    </Style>
                </DataGrid.CellStyle>

Note that I am using DataView as ItemsSource to DataGrid and therefore I bind to "Row". Item is than basically DataRowView. Then you need to access row values in the converter:

public object Convert(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture) {
        var enumValue = (Member.UserStatus)((DataRow)value)["Status"];
        if(enumValue == Member.UserStatus.Change)
            return Brushes.Red;
        if(enumValue == Member.UserStatus.Import)
            return Brushes.Blue;
        if(enumValue == Member.UserStatus.Remove)
            return Brushes.Orange;
        if(enumValue == Member.UserStatus.Synced)
            return Brushes.Green;
        else
            return DependencyProperty.UnsetValue;
    }
مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top