在ViewModel中存储信息或使用IValueConverter

时间:2015-09-09 07:24:01

标签: c# wpf mvvm ivalueconverter

如果我想将wpf中Background的{​​{1}} - 颜色更改为红色,如果我的视图模型中的属性ButtonAmount,并且绿色为{它大于0,为此使用值转换器是否更好,或者我应该在视图模型中简单地实现自定义0 - 属性?此Background - 属性会将Background - 值包装为Amount,该SolidColorBrush将绑定到Background的{​​{1}}。

哪种方式更直接?

谢谢!

4 个答案:

答案 0 :(得分:4)

我会使用DataTrigger

将以下样式应用于您的按钮。

它与视图模型中的Amount属性绑定。 它将默认背景颜色设置为'绿色'并更改为“红色”'如果Amount的值为0。

<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如何使用它。

对于范围检查,您似乎需要实现其他回复或this answer中提到的IValueConverter

答案 1 :(得分:2)

我会用Trigger做,但转换器也可以。但我肯定不会在ViewModel中创建属性Background,因为Background是关于视图的设计,所以最好在View中定义它

答案 2 :(得分:2)

我在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并不真正关心颜色。 Viewmodel应该只包含与模型相关的逻辑,然后由视图使用。如果您只想更改颜色(例如使用Blue而不是Green) - 此更改必须在视图中完成。因此,bool属性和BoolToColorConverter(或BoolToSolidBrushConverter直接与xaml转换器中的Background属性一起使用。

答案 3 :(得分:1)

设置Button的{​​{1}}是视图相关的东西我不是从ViewModel设置它是一个好主意,我认为如果你定义{{ 1}} ViewModel中的属性,使用转换器

定义background以检查Amount值对 0
DataTrigger

和转换器

amount

您还可以考虑将参数传递给转换器进行比较,以便您的解决方案尽可能自定义。