在通用 windows 应用程序中,如果视图模型中的 属性 更改,如何使用 xaml 和数据绑定更改按钮的背景颜色

In universal windows apps, how to change the background color of a button using xaml and databinding if a property in the view model changes

通用 windows 应用不支持数据触发器。

没有数据触发器,如何使用 xaml 和数据绑定更改按钮的背景颜色,仅当视图模型中的布尔值 属性 发生变化时?

例如给出这个 XAML:

<StackPanel>
    <Button Name="ButtonA" Click="ButtonA_Click" Content="A" />
    <Button Name="ButtonB" Click="ButtonB_Click" Content="B" />
    <Button Name="ButtonC" Click="ButtonC_Click" Content="C" />
</StackPanel>

后面有这段代码

private void ButtonA_Click(object sender, RoutedEventArgs e)
{
    Model.IsOnA = !Model.IsOnA;
}

private void ButtonB_Click(object sender, RoutedEventArgs e)
{
    Model.IsOnB = !Model.IsOnB;
}

private void ButtonC_Click(object sender, RoutedEventArgs e)
{
    Model.IsOnC = !Model.IsOnC;
}

当视图模型中的相应 属性 发生更改时,使用数据绑定更改按钮背景颜色的最佳方法是什么?

我仅使用 VisualStateManager 管理器就可以让它为一个按钮工作:

<VisualStateManager.VisualStateGroups>
    <VisualStateGroup>
        <VisualState>
            <VisualState.StateTriggers>
                <StateTrigger IsActive="{x:Bind Model.IsOnA, Mode=OneWay}" />
            </VisualState.StateTriggers>
            <VisualState.Setters>
                <Setter Target="ButtonA.Background" Value="Red"></Setter>
                <Setter Target="ButtonA.Foreground" Value="White"></Setter>
            </VisualState.Setters>
        </VisualState>
    </VisualStateGroup>
</VisualStateManager.VisualStateGroups>

但是对于绑定到视图模型中不同属性的多个按钮,这种方法不起作用。

你可以在下面link查看我之前的回答。 Delete button on ListView items

您只需要创建一个将 Boolean 转换为 SolidColorBrush 的转换器。例如:

public class BooleanToColorConverter : IValueConverter
{
    public object Convert(object value, Type targetType, object parameter, string language)
    {
        return (value is bool && (bool)value) ? new SolidColorBrush(Colors.Red) : new SolidColorBrush(Colors.Green);
    }

    public object ConvertBack(object value, Type targetType, object parameter, string language)
    {
        throw new Exception("Not Implemented");
    }
}

并将其添加到您的 Xaml 绑定中。

<Page.Resources>
    <local:BooleanToColorConverter x:Key="ColorConverter"/>
</Page.Resources>

<Grid Background="{ThemeResource ApplicationPageBackgroundThemeBrush}">
    <ListView ItemsSource="{x:Bind Activities}">
        <ListView.ItemTemplate>
            <DataTemplate x:DataType="local:Activity">
                <Grid>
                    <Grid.ColumnDefinitions>
                        <ColumnDefinition Width="3*"/>
                        <ColumnDefinition Width="1*"/>
                    </Grid.ColumnDefinitions>
                    <TextBlock x:Name="txt" Text="{x:Bind Name}" Grid.Column="0"/>
                    <Button x:Name="delItem" Click="delItem_Click" Grid.Column="1" Foreground="{x:Bind Visible, Mode=OneWay, Converter={StaticResource ColorConverter}}" Background="Transparent" Margin="100, 0, 0, 0">
                        <SymbolIcon Symbol="Delete"/>
                    </Button>
                </Grid>
            </DataTemplate>
        </ListView.ItemTemplate>
    </ListView>
</Grid>

转换器的替代方法是附加属性。如果需要更改多个 属性 或需要访问视图模型(通过控件的 DataContext)来决定如何更改用户界面属性,这很有用。

这是一个简单的例子:

public class IsFavoriteBehavior
{
    public static bool GetIsFavorite(DependencyObject obj)
    {
        return (bool)obj.GetValue(IsFavoriteProperty);
    }

    public static void SetIsFavorite(DependencyObject obj, bool value)
    {
        obj.SetValue(IsFavoriteProperty, value);
    }

    public static readonly DependencyProperty IsFavoriteProperty =
        DependencyProperty.RegisterAttached("IsFavorite", typeof(bool), typeof(Button), new PropertyMetadata(false, (o, e) =>
        {
            var button = o as Button;

            if (button == null)
                return;

            if ((bool)e.NewValue)
            {
                button.Background = (SolidColorBrush)Application.Current.Resources["HighlightBackgroundColorBrush"];
                button.Foreground = (SolidColorBrush)Application.Current.Resources["HighlightTextColorBrush"];
            }
            else
            {
                button.Background = (SolidColorBrush)Application.Current.Resources["NormalBackgroundColorBrush"];
                button.Foreground = (SolidColorBrush)Application.Current.Resources["NormalTextColorBrush"];
            }

            o.SetValue(IsFavoriteProperty, e.NewValue);
        }));
}

在XAML中可以这样使用:

<Button Name="FavoriteButton" Content="Favorite" local:IsFavoriteBehavior.IsFavorite="{x:Bind ViewModel.Favorite, Mode=OneWay}" >

可以将带有背景色画笔的 属性 直接放入视图模型中。

例如在视图模型中:

SolidColorBrush IsOnABackground
{
    get
    {
        if(IsOnA)
            return (SolidColorBrush)Application.Current.Resources["HighlightBackgroundColorBrush"];
        else
            return (SolidColorBrush)Application.Current.Resources["NormalBackgroundColorBrush"];
    }
}

bool isOnA = false;
bool IsOnA
{
    set
    {
        if (isOnA != value)
        {
            isOnA = value;

            OnPropertyChanged("IsOnA");
            OnPropertyChanged("IsOnABackground");
        }
    }
    get { return isOnA; }
}

并在 XAML 中:

<Button Name="ButtonA" Content="A" Background="{x:Bind ViewModel.IsOnABackground, Mode=OneWay}" />