在 ViewModel 中存储信息或使用 IValueConverter
Storing information in ViewModel or using IValueConverter
如果我想将 wpf 中的 Button
的 Background
颜色更改为红色,如果我的视图模型中的 属性 Amount
是 0
如果它大于 0 则变为绿色,为此使用值转换器更好,还是我应该简单地在我的视图模型中实现自定义 Background
-属性? Background
-属性 会将 Amount
值包装到 SolidColorBrush
,它将绑定到 Button
的 Background
。
哪种方式更直接?
谢谢!
我会用 Trigger 做,但 Converter 也可以。但是我肯定不会在ViewModel中做属性 Background,因为Background是关于设计的,是关于view的,所以最好在View
中定义
我会使用 DataTrigger
.
将以下样式应用到您的按钮。
它绑定到视图模型中的 Amount
属性。
它将默认背景色设置为 'green',如果 Amount
的值为 0,则更改为 'red'。
<Button.Style>
<Style TargetType="Button">
<Setter Property="Background" Value="Green" />
<Style.Triggers>
<DataTrigger Binding="{Binding Amount}" Value="0">
<Setter Property="Background" Value="Red" />
</DataTrigger>
</Style.Triggers>
</Style>
</Button.Style>
附加信息
您还可以使用 MultiDataTrigger
.
检查多个条件
看起来像这样:
<MultiDataTrigger>
<MultiDataTrigger.Conditions>
<Condition Binding="{...}, Value="..."/>
<Condition Binding="{...}, Value="..."/>
</MultiDataTrigger.Conditions>
<MultiDataTrigger.Setters>
<Setter Property="A" Value="..."/>
<Setter Property="B" Value="..."/>
</MultiDataTrigger.Setters>
</MultiDataTrigger>
查看 this article 如何使用它。
似乎要进行范围检查,您需要实施 IValueConverter
,就像其他回复或 this answer 中提到的那样。
设置 Button
的 background
与视图相关 我不认为从 ViewModel 设置它是个好主意,我认为如果您定义Amount
属性 在 ViewModel 中,定义一个 DataTrigger
来检查 amount
值 对照 0 使用 转换器
<Window.Resources>
<YurNs:GreaterThanValConverter x:Key="GreaterThanValConverter"/>
</Window.Resources>
<StackPanel>
<TextBox Text="{Binding Amount,Mode=TwoWay,UpdateSourceTrigger=PropertyChanged}"/>
<Button Content="Button">
<Button.Style>
<Style TargetType="Button">
<Setter Property="Background" Value="Green"/>
<Style.Triggers>
<DataTrigger Binding="{Binding Amount,Converter={StaticResource GreaterThanValConverter}}" Value="false">
<Setter Property="Background" Value="Red"/>
</DataTrigger>
</Style.Triggers>
</Style>
</Button.Style>
</Button>
</StackPanel>
和转换器
public class GreaterThanValConverter:IValueConverter
{
public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
{
return (int) value > 0;
}
public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
{
throw new NotImplementedException();
}
}
您还可以考虑将参数传递给转换器进行比较,以便您的解决方案尽可能可定制。
我会在 viewmodel 中制作 bool
属性,这是在 Amount
更改时计算的:
public bool IsAmountZero
{
get { return Amount == 0; }
}
private int _amount;
public int Amount
{
get { return _amount; }
set
{
_amount = value;
OnPropertyChanged();
OnPropertyChanged(nameof(IsAmountZero));
}
}
然后编写转换器BoolToColorConverter
(颜色可以通过ConverterParameter
以某种方式)。
// in current form it's actually BoolToColorRedGreenConverter
public class BoolToColorConverter : MarkupExtension, IValueConverter
{
public BoolToColorConverter() { }
public override object ProvideValue(IServiceProvider serviceProvider)
{
return this;
}
public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
{
if (value is bool)
{
var colorFalse = Colors.Green;
var colorTrue = Colors.Red;
if (parameter != null)
{
//...
}
return (bool)value ? colorTrue : colorFalse;
}
throw new InvalidCastException();
}
public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
{
throw new NotImplementedException();
}
}
这样使用
<Button.Background>
<SolidColorBrush Color="{Binding IsAmountZero, Converter={local:BoolToColorConverter}}" />
</Button.Background>
这将是一个可重用的解决方案。
否则只需制作转换器 IntZeroCheckToColorGreenRedConverter
,但与具有 bool
属性.
的转换器相比,它的可重用性不会很高
在视图模型中使用 Brush
属性 的想法很糟糕,因为视图模型并不真正关心颜色。 Viewmodel 应该只包含与模型相关的逻辑,然后由视图使用。如果你想简单地改变颜色(例如使用 Blue
而不是 Green
)——这个改变必须在视图中完成。因此 bool
属性 和 BoolToColorConverter
(或 BoolToSolidBrushConverter
直接与 xaml 中的 Background
属性一起使用)转换器。
如果我想将 wpf 中的 Button
的 Background
颜色更改为红色,如果我的视图模型中的 属性 Amount
是 0
如果它大于 0 则变为绿色,为此使用值转换器更好,还是我应该简单地在我的视图模型中实现自定义 Background
-属性? Background
-属性 会将 Amount
值包装到 SolidColorBrush
,它将绑定到 Button
的 Background
。
哪种方式更直接?
谢谢!
我会用 Trigger 做,但 Converter 也可以。但是我肯定不会在ViewModel中做属性 Background,因为Background是关于设计的,是关于view的,所以最好在View
中定义我会使用 DataTrigger
.
将以下样式应用到您的按钮。
它绑定到视图模型中的 Amount
属性。
它将默认背景色设置为 'green',如果 Amount
的值为 0,则更改为 'red'。
<Button.Style>
<Style TargetType="Button">
<Setter Property="Background" Value="Green" />
<Style.Triggers>
<DataTrigger Binding="{Binding Amount}" Value="0">
<Setter Property="Background" Value="Red" />
</DataTrigger>
</Style.Triggers>
</Style>
</Button.Style>
附加信息
您还可以使用 MultiDataTrigger
.
看起来像这样:
<MultiDataTrigger>
<MultiDataTrigger.Conditions>
<Condition Binding="{...}, Value="..."/>
<Condition Binding="{...}, Value="..."/>
</MultiDataTrigger.Conditions>
<MultiDataTrigger.Setters>
<Setter Property="A" Value="..."/>
<Setter Property="B" Value="..."/>
</MultiDataTrigger.Setters>
</MultiDataTrigger>
查看 this article 如何使用它。
似乎要进行范围检查,您需要实施 IValueConverter
,就像其他回复或 this answer 中提到的那样。
设置 Button
的 background
与视图相关 我不认为从 ViewModel 设置它是个好主意,我认为如果您定义Amount
属性 在 ViewModel 中,定义一个 DataTrigger
来检查 amount
值 对照 0 使用 转换器
<Window.Resources>
<YurNs:GreaterThanValConverter x:Key="GreaterThanValConverter"/>
</Window.Resources>
<StackPanel>
<TextBox Text="{Binding Amount,Mode=TwoWay,UpdateSourceTrigger=PropertyChanged}"/>
<Button Content="Button">
<Button.Style>
<Style TargetType="Button">
<Setter Property="Background" Value="Green"/>
<Style.Triggers>
<DataTrigger Binding="{Binding Amount,Converter={StaticResource GreaterThanValConverter}}" Value="false">
<Setter Property="Background" Value="Red"/>
</DataTrigger>
</Style.Triggers>
</Style>
</Button.Style>
</Button>
</StackPanel>
和转换器
public class GreaterThanValConverter:IValueConverter
{
public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
{
return (int) value > 0;
}
public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
{
throw new NotImplementedException();
}
}
您还可以考虑将参数传递给转换器进行比较,以便您的解决方案尽可能可定制。
我会在 viewmodel 中制作 bool
属性,这是在 Amount
更改时计算的:
public bool IsAmountZero
{
get { return Amount == 0; }
}
private int _amount;
public int Amount
{
get { return _amount; }
set
{
_amount = value;
OnPropertyChanged();
OnPropertyChanged(nameof(IsAmountZero));
}
}
然后编写转换器BoolToColorConverter
(颜色可以通过ConverterParameter
以某种方式)。
// in current form it's actually BoolToColorRedGreenConverter
public class BoolToColorConverter : MarkupExtension, IValueConverter
{
public BoolToColorConverter() { }
public override object ProvideValue(IServiceProvider serviceProvider)
{
return this;
}
public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
{
if (value is bool)
{
var colorFalse = Colors.Green;
var colorTrue = Colors.Red;
if (parameter != null)
{
//...
}
return (bool)value ? colorTrue : colorFalse;
}
throw new InvalidCastException();
}
public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
{
throw new NotImplementedException();
}
}
这样使用
<Button.Background>
<SolidColorBrush Color="{Binding IsAmountZero, Converter={local:BoolToColorConverter}}" />
</Button.Background>
这将是一个可重用的解决方案。
否则只需制作转换器 IntZeroCheckToColorGreenRedConverter
,但与具有 bool
属性.
在视图模型中使用 Brush
属性 的想法很糟糕,因为视图模型并不真正关心颜色。 Viewmodel 应该只包含与模型相关的逻辑,然后由视图使用。如果你想简单地改变颜色(例如使用 Blue
而不是 Green
)——这个改变必须在视图中完成。因此 bool
属性 和 BoolToColorConverter
(或 BoolToSolidBrushConverter
直接与 xaml 中的 Background
属性一起使用)转换器。