根据条件更改 GridViewColumn 文本颜色

Change GridViewColumn text color base on condition

这是我的 GridViewColumn:

<GridViewColumn Width="180" Header="Status">
    <GridViewColumn.CellTemplate>
        <DataTemplate>
            <TextBlock x:Name="Txt" Text="{Binding Status}" Foreground="Yellow" />
        </DataTemplate>
    </GridViewColumn.CellTemplate>
</GridViewColumn>

状态 field 是我的绑定对象的 属性,我想做的就是更改此 GridViewColumn 颜色,但这次基于条件:

我有另一个名为 StatusMessage 的属性,它很简单 enum:

public enum StatusMessage
{
    InProcess,
    Done,
    Wait
}

所以这个 enum 属性 一直在变化,对于这个 enum 的每个值,我想定义不同的颜色。 可能吗?

编辑

我的视图模型 class 继承自 BaseObservableObject:

public class BaseObservableObject : INotifyPropertyChanged
{
    public event PropertyChangedEventHandler PropertyChanged;

    protected virtual void OnPropertyChanged([CallerMemberName] string propertyName = null)
    {
        var handler = PropertyChanged;
        if (handler != null) handler(this, new PropertyChangedEventArgs(propertyName));
    }

    protected virtual void OnPropertyChanged<T>(Expression<Func<T>> raiser)
    {
        var propName = ((MemberExpression)raiser.Body).Member.Name;
        OnPropertyChanged(propName);
    }

    protected bool Set<T>(ref T field, T value, [CallerMemberName] string name = null)
    {
        if (!EqualityComparer<T>.Default.Equals(field, value))
        {
            field = value;
            OnPropertyChanged(name);
            return true;
        }
        return false;
    }
}

我的属性:

public string Status
{
    get { return _status; }
    set
    {
        _status = value;
        OnPropertyChanged();
    }
}

public StatusMsg StatusMessage
{
    get { return _statusMsg; }
    set {
        _statusMsg = value;
        OnPropertyChanged();
    }
}

XAML:

<GridViewColumn Width="180" Header="Status" DisplayMemberBinding="{Binding Status}">
    <GridViewColumn.CellTemplate>
        <DataTemplate>
            <TextBlock Foreground="{Binding StatusMsg,Converter={c:StatusMessageToColorConverter}}" />
        </DataTemplate>
    </GridViewColumn.CellTemplate>
</GridViewColumn>

StatusMessageToColorConverter 与@grek40 建议的一样,我的 TextBlock Foreground 仍然没有改变。

在您的视图模型中,您可以添加一个名为 GetColour 的 属性 来查看当前枚举值和 returns 一种颜色。然后只需在 xaml.

中绑定 GetColour 属性

我先讲价值转换,再说说其他需求("So this enum property is changing all the time and for every value of this enum i want to define different color.")

由于您有一个枚举值但您想要一个颜色规范,您需要转换该值。这可以借助 IConverter 接口的实现来完成。在 XAML 中有多种引用转换器的方法,我还继承自 MarkupExtension,因此我可以直接访问转换器。

public class StatusMessageToColorConverter : MarkupExtension, IValueConverter
{
    // one way converter from enum StatusMessage to color
    public object Convert(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
    {
        if (value is StatusMessage && targetType == typeof(Brush))
        {
            switch ((StatusMessage)value)
            {
                case StatusMessage.InProcess:
                    return Brushes.Yellow;
                case StatusMessage.Done:
                    return Brushes.Green;
                case StatusMessage.Wait:
                    return Brushes.Red;
            }
        }
        return null;
    }
    public object ConvertBack(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
    {
        throw new NotImplementedException();
    }

    public StatusMessageToColorConverter()
    {
    }

    // MarkupExtension implementation
    public override object ProvideValue(IServiceProvider serviceProvider)
    {
        return this;
    }
}

大家可以看到,如果输入值是StatusMessage类型,目标类型是typeof(Brush),我就进行转换,也就是Foreground[=48=的Type ].我只是选择了一些颜色,如果你喜欢,你可以使用不同的颜色或更复杂的画笔。

在XAML中,需要引用转换器的命名空间。在我的例子中,它只是 WpfApplication2 关联到 XAML 命名空间名称 c

<Window 
    [... other properties]
    xmlns:c="clr-namespace:WpfApplication2">

现在,当绑定到前台时属性,利用转换器

<TextBlock Text="{Binding Status}" Foreground="{Binding StatusMessage,Converter={c:StatusMessageToColorConverter}}" />

这应该可以解决问题。

现在转到有关动态更改值的另一部分。您的视图模型 class 需要实现 INotifyPropertyChanged 并在值更改时引发 PropertyChanged 事件。例如,请参阅以下 class,其中仅包含示例的两个属性和必要的通知逻辑。

public class ItemModel : INotifyPropertyChanged
{
    public event PropertyChangedEventHandler PropertyChanged;
    void NotifyPropertyChanged([CallerMemberName]string prop = null)
    {
        var tmp = PropertyChanged;
        if (tmp != null) tmp(this, new PropertyChangedEventArgs(prop));
    }

    private string _Status;
    public string Status
    {
        get { return _Status; }
        set { _Status = value; NotifyPropertyChanged(); }
    }
    private StatusMessage _StatusMessage;
    public StatusMessage StatusMessage
    {
        get { return _StatusMessage; }
        set { _StatusMessage = value; NotifyPropertyChanged(); }
    }
}

更复杂的视图模型可以采用相同的方法。为了减少更新开销,比较 setter 中的当前值和新值,并且仅在值实际更改时通知。