我正在开发一个Silverlight应用程序,我试图坚持MVVM的原则,但我遇到了一些问题,改变图像的来源基于状态ViewModel中的一个属性。对于所有意图和目的,您可以将我作为音频应用的播放/暂停按钮实现的功能考虑在内。当处于“播放”模式时,ViewModel中的IsActive为真,并且应该显示按钮上的“Pause.png”图像。暂停时,ViewModel中的IsActive为false,按钮上显示“Play.png”。自然地,当鼠标悬停在按钮上时,还有两个额外的图像需要处理。Silverlight MVVM混乱:更新基于状态的图像
我以为我可以使用Style Trigger,但显然它们在Silverlight中不受支持。我一直在评论一个类似于我的建议使用VisualStateManager的问题的论坛帖子。虽然这可能有助于改变悬停/正常状态的图像,但缺失的部分(或我不理解)是如何通过视图模型设置状态。这篇文章似乎只适用于事件而不是视图模型的属性。话虽如此,我也没有成功完成正常/悬停的影响。
以下是我的Silverlight 4 XAML。也应该注意到我正在使用MVVM Light。
<UserControl x:Class="Foo.Bar.MyUserControl"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:i="clr-namespace:System.Windows.Interactivity;assembly=System.Windows.Interactivity"
mc:Ignorable="d"
d:DesignHeight="100" d:DesignWidth="200">
<UserControl.Resources>
<Style x:Key="MyButtonStyle" TargetType="Button">
<Setter Property="IsEnabled" Value="true"/>
<Setter Property="IsTabStop" Value="true"/>
<Setter Property="Background" Value="#FFA9A9A9"/>
<Setter Property="Foreground" Value="#FF000000"/>
<Setter Property="MinWidth" Value="5"/>
<Setter Property="MinHeight" Value="5"/>
<Setter Property="Margin" Value="0"/>
<Setter Property="HorizontalAlignment" Value="Left" />
<Setter Property="HorizontalContentAlignment" Value="Center"/>
<Setter Property="VerticalAlignment" Value="Top" />
<Setter Property="VerticalContentAlignment" Value="Center"/>
<Setter Property="Cursor" Value="Hand"/>
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="Button">
<Grid>
<Image Source="/Foo.Bar;component/Resources/Icons/Bar/Play.png">
<VisualStateManager.VisualStateGroups>
<VisualStateGroup x:Name="Active">
<VisualState x:Name="MouseOver">
<Storyboard>
<ObjectAnimationUsingKeyFrames Storyboard.TargetProperty="Source" Storyboard.TargetName="/Foo.Bar;component/Resources/Icons/Bar/Play_Hover.png" />
</Storyboard>
</VisualState>
</VisualStateGroup>
</VisualStateManager.VisualStateGroups>
</Image>
</Grid>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
</UserControl.Resources>
<Grid x:Name="LayoutRoot" Background="White">
<Button Style="{StaticResource MyButtonStyle}" Command="{Binding ChangeStatus}" Height="30" Width="30" />
</Grid>
</UserControl>
根据视图模型确定的状态更新按钮上图像的正确方法是什么?
非常感谢您的回复。我并不完全反对定制转换器,但我想要坚持纯XAML,如果可能的话。 – senfo 2011-02-18 15:43:07
如果你使用MVVM,作为一个规则,我尝试只使用BooleanToVisiblityConverter(如果可能的话)(只是b/c映射布尔到可见性是如此频繁使用)。你的ViewModel应该能够公开你需要绑定的属性。将此逻辑放在ViewModels而不是转换器中通常会更简单一些,并且您可以显式控制INotifyPropertyChanged。 – jonathanpeppers 2011-02-18 17:27:23