将视图相关类型(如 Style)放入视图模型中违反了 MVVM 原则。相反,公开一个表示按钮状态的属性,该状态决定是否应显示一种样式或另一种样式。
public class MyViewModel : INotifyPropertyChanged
{
private bool _isPageLoaded;
public bool IsPageLoaded
{
get => _isPageLoaded;
set
{
if (_isPageLoaded == value)
return;
_isPageLoaded = value;
OnPropertyChanged();
}
}
public event PropertyChangedEventHandler PropertyChanged;
protected virtual void OnPropertyChanged([CallerMemberName] string propertyName = null)
{
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
}
// ...other properties and methods.
}
一定要给它一个有意义的名字。它不必是bool 类型,但它适合这里。还要确保实现INotifyPropertyChanged 以反映用户界面中属性的更改。
将此属性设置为单击按钮时调用的命令或方法中的正确值。从这里开始,您的方案有多种选择。
样式触发解决方案
您可以使用触发器为两种状态创建一个通用样式,而不是完全交换样式,该触发器根据存储在属性中的状态以不同方式设置属性。
<Style x:Key="MyButtonStyle" TargetType="{x:Type Button}" BasedOn="{StaticResource {x:Type Button}}">
<!-- Properties set for IsPageLoaded=False -->
<Setter Property="Foreground" Value="Red"/>
<Style.Triggers>
<DataTrigger Binding="{Binding IsPageLoaded}" Value="True">
<!-- Properties set for IsPageLoaded=True -->
<Setter Property="Foreground" Value="Blue"/>
</DataTrigger>
</Style.Triggers>
</Style>
<Button Style="{StaticResource MyButtonStyle}"
Grid.Row="0"
Grid.Column="1"
Content="News"
x:Name="LoadFirstPage"/>
价值转换器解决方案
您可以创建一个返回与属性状态对应的样式的值转换器。
public class ConditionToStyleConverter : IValueConverter
{
public Style SuccessStyle { get; set; }
public Style FailureStyle { get; set; }
public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
{
return (bool)value ? SuccessStyle : FailureStyle;
}
public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
{
return new InvalidOperationException();
}
}
以下是您在范围内的资源字典中放入两种样式和一个转换器的示例。
<Style x:Key="MyFirstButtonStyle" TargetType="{x:Type Button}" BasedOn="{StaticResource {x:Type Button}}">
<Setter Property="Foreground" Value="Red"/>
</Style>
<Style x:Key="MySecondButtonStyle" TargetType="{x:Type Button}" BasedOn="{StaticResource {x:Type Button}}">
<Setter Property="Foreground" Value="Blue"/>
</Style>
<local:ConditionToStyleConverter x:Key="ConditionToStyleConverter"
SuccessStyle="{StaticResource MyFirstButtonStyle}"
FailureStyle="{StaticResource MySecondButtonStyle}"/>
您可以像这样在按钮上使用转换器。
<Button Style="{Binding IsPageLoaded, Converter={StaticResource ConditionToStyleConverter}}"
Grid.Row="0"
Grid.Column="1"
Content="News"
x:Name="LoadFirstPage"/>
在此示例中,转换器是一个简单的IValueConverter,它公开了样式的属性,因此对于不同的样式,您必须创建其他实例。也可以创建一个可以直接绑定样式的多值转换器,但是对于你作为初学者的场景,这个方案应该足够了。