在通用 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}" />
通用 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}" />