根据条件更改 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 中的当前值和新值,并且仅在值实际更改时通知。
这是我的 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 中的当前值和新值,并且仅在值实际更改时通知。