在WPF中通过MVVM模式更改按钮背景颜色

24

我正在使用MVVM light和WPF。我想通过ViewModel根据某些特定条件设置按钮的背景颜色。请提供一些实现方式。谢谢。

3个回答

35

你可以将控件的Background绑定到viewmodel上的一个属性,技巧在于使用IValueConverter来返回所需颜色的Brush。这是一个示例,它将从viewmodel转换布尔值为颜色:

public class BoolToBrushConverter : IValueConverter
{
    public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
    {
        if (value == null)
            return Brushes.Transparent;

        return Convert.ToBoolean(value)
            ? Brushes.Red
            : Brushes.Transparent; 
    }

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

使用绑定表达式,例如

"{Binding Reviewed, Converter={StaticResource BoolToBrushConverter}}"

其中 Reviewed 是你的布尔型视图模型属性。


1
你不需要将转换器密钥添加到资源吗? - levi Clouser
为什么要使用布尔属性而不是ColorToBrushConverter? - demoncrate
1
@demoncrate 将其保留为 ViewModel 上的布尔值,将 WPF 的特定 UI 知识隐藏在 ViewModel 中,从而提高了可测试性,因此您可以在测试中无头运行 ViewModel 并检查其功能,您也可以将其轻松地移植到其他堆栈中(例如 Blazor 中的相同 ViewModel)。还有其他原因,但我现在还没有喝足够的咖啡来记得它们。 - almog.ori

31

使用触发器:

<Button>
    <Button.Style>
        <Style TargetType="Button">
            <!-- Set the default value here (if any). 
                 If you set it directly on the button that will override the trigger. -->
            <Setter Property="Background" Value="LightGreen" />
            <Style.Triggers>
                <DataTrigger Binding="{Binding SomeConditionalProperty}"
                             Value="True">
                    <Setter Property="Background" Value="Pink" />
                </DataTrigger>
            </Style.Triggers>
        </Style>
    </Button.Style>
</Button>

解释该注释的含义。


在视图模型(MVVM)中使用依赖属性:

public bool SomeConditionalProperty 
{
    get { /*...*/ }
    set
    {
        //...

        OnPropertyChanged(nameof(SomeConditionalProperty));
        //Because Background is dependent on this property.
        OnPropertyChanged(nameof(Background));
    }
}

public Brush Background =>
    SomeConditionalProperty ? Brushes.Pink : Brushes.LightGreen;

然后你只需绑定到Background


这是在使用WPF时执行此操作的非常好的方法,如果您正在寻找可移植到Silverlight的代码,则可能还需要Expression SDK以获取触发器语义。 - almog.ori

0
我会使用一个颜色属性,在Setter中将颜色转换为画刷。
private SolidColorBrush _penBrush;
public SolidColorBrush PenBrush { get { return _penBrush; } set { SetPropertyChanged(ref _penBrush, value, "PenBrush"); } }

private Color _penColor;
public Color PenColor { get { return _penColor; } set { SetPropertyChanged(ref _penColor, value, "PenColor"); PenBrush = new SolidColorBrush(_penColor); } }

使用以下XAML代码:

<Button Background="{Binding PenBrush}"></Button>

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接