Silverlight的MVVM困惑:基于状态更新图片 [英] Silverlight MVVM Confusion: Updating Image Based on State

查看:156
本文介绍了Silverlight的MVVM困惑:基于状态更新图片的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在开发一个Silverlight应用程序,我想坚持到MVVM校长,但我遇到了一些问题,改变图像的基于视图模型的属性的状态源。对于所有意图和目的,你能想到的我实施为音频应用程序播放/暂停按钮的功能。当在播放模式,IsActive是在视图模型和按钮上的Pause.png图像真应显示。暂停时,IsActive是在视图模型和Play.png假上显示的按钮。当然,有两个附加的图像,当鼠标悬停在按钮来处理。

I'm developing a Silverlight application and I'm trying to stick to the MVVM principals, but I'm running into some problems changing the source of an image based on the state of a property in the ViewModel. For all intents and purposes, you can think of the functionality I'm implementing as a play/pause button for an audio app. When in the "Play" mode, IsActive is true in the ViewModel and the "Pause.png" image on the button should be displayed. When paused, IsActive is false in the ViewModel and "Play.png" is displayed on the button. Naturally, there are two additional images to handle when the mouse hovers over the button.

我想我可以使用的样式触发,但显然他们不支持Silverlight。我一直在检讨一个论坛的帖子与我相似的问题在那里它建议使用 VisualStateManager 。虽然这可能会改变图像悬停/正常状态的帮助,缺失(或我不理解)的部分是如何做到这一点通过视图模型设置的状态工作。该职位似乎只适用于事件而不是视图模型的属性。话虽如此,我还没有成功完成正常/悬停的影响,无论是。

I thought I could use a Style Trigger, but apparently they're not supported in Silverlight. I've been reviewing a forum post with a question similar to mine where it's suggested to use the VisualStateManager. While this might help with changing the image for hover/normal states, the part missing (or I'm not understanding) is how this would work with a state set via the view model. The post seems to apply only to events rather than properties of the view model. Having said that, I also haven't successfully completed the normal/hover affects, either.

下面是我的Silverlight XAML 4。它也可能应该注意我与MVVM光工作

Below is my Silverlight 4 XAML. It should also probably be noted I'm working with 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>



这是与由所确定的状态来更新上的按钮的图像的正确方法?视图模型

What is the proper way to update images on buttons with the state determined by the view model?

推荐答案

通过一个同事的意见,因为我已经使用的 MVVM光,我能够利用的 EventToCommand 处理鼠标输入和鼠标离开事件视图模型,而不是依靠内置的VisualStateManager来处理这些事件。我也改变了我的按钮切换按钮。这让我利用选中和未选中状态来处理是否显示播放或暂停按钮。随着国家是由视图模型控制的,当时我能够确定的切换按钮的可见性属性绑定在该检查状态的视图模型属性显示的映像。我更新的XAML如下所示:

Through the advice of a colleague and since I was already using MVVM Light, I was able to make use of EventToCommand to handle the mouse enter and mouse leave events in the view model, as opposed to relying on the built in VisualStateManager to handle those events. I also changed my Button to a ToggleButton. This allowed me to utilize the checked and unchecked states to handle whether to display the play or pause buttons. As the state was controlled by the view model, I was then able to determine which image to display by binding the Visibility attribute of the ToggleButton to a property on the view model that checked the state. My updated XAML looks like the following:

<UserControl x:Class="Foo.Bar.MyControl"
    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"
    xmlns:cmd="clr-namespace:GalaSoft.MvvmLight.Command;assembly=GalaSoft.MvvmLight.Extras.SL4"
    mc:Ignorable="d"
    d:DesignHeight="100" d:DesignWidth="200">
    <i:Interaction.Triggers>
        <i:EventTrigger EventName="MouseEnter">
            <cmd:EventToCommand Command="{Binding MouseEnterCommand}" PassEventArgsToCommand="True"/>
        </i:EventTrigger>
        <i:EventTrigger EventName="MouseLeave">
            <cmd:EventToCommand Command="{Binding MouseLeaveCommand}" PassEventArgsToCommand="True"/>
        </i:EventTrigger>
    </i:Interaction.Triggers>
    <UserControl.Resources>
        <Style x:Key="MyButtonStyle" TargetType="ToggleButton">
            <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="ToggleButton">
                        <Grid>
                            <VisualStateManager.VisualStateGroups>
                                <VisualStateGroup x:Name="CheckStates">
                                    <VisualState x:Name="Checked">
                                        <Storyboard>
                                            <ObjectAnimationUsingKeyFrames Storyboard.TargetProperty="(UIElement.Visibility)" Storyboard.TargetName="Pause">
                                                <DiscreteObjectKeyFrame KeyTime="0">
                                                    <DiscreteObjectKeyFrame.Value>
                                                        <Visibility>Visible</Visibility>
                                                    </DiscreteObjectKeyFrame.Value>
                                                </DiscreteObjectKeyFrame>
                                            </ObjectAnimationUsingKeyFrames>
                                            <ObjectAnimationUsingKeyFrames Storyboard.TargetProperty="(UIElement.Visibility)" Storyboard.TargetName="Play">
                                                <DiscreteObjectKeyFrame KeyTime="0">
                                                    <DiscreteObjectKeyFrame.Value>
                                                        <Visibility>Collapsed</Visibility>
                                                    </DiscreteObjectKeyFrame.Value>
                                                </DiscreteObjectKeyFrame>
                                            </ObjectAnimationUsingKeyFrames>
                                        </Storyboard>
                                    </VisualState>
                                    <VisualState x:Name="Unchecked">
                                        <Storyboard>
                                            <ObjectAnimationUsingKeyFrames Storyboard.TargetProperty="(UIElement.Visibility)" Storyboard.TargetName="Play">
                                                <DiscreteObjectKeyFrame KeyTime="0">
                                                    <DiscreteObjectKeyFrame.Value>
                                                        <Visibility>Visible</Visibility>
                                                    </DiscreteObjectKeyFrame.Value>
                                                </DiscreteObjectKeyFrame>
                                            </ObjectAnimationUsingKeyFrames>
                                            <ObjectAnimationUsingKeyFrames Storyboard.TargetProperty="(UIElement.Visibility)" Storyboard.TargetName="Pause">
                                                <DiscreteObjectKeyFrame KeyTime="0">
                                                    <DiscreteObjectKeyFrame.Value>
                                                        <Visibility>Collapsed</Visibility>
                                                    </DiscreteObjectKeyFrame.Value>
                                                </DiscreteObjectKeyFrame>
                                            </ObjectAnimationUsingKeyFrames>
                                        </Storyboard>
                                    </VisualState>
                                    <VisualState x:Name="Indeterminate" />
                                </VisualStateGroup>
                            </VisualStateManager.VisualStateGroups>
                            <Image x:Name="Play" Source="/Foo.Bar;component/Resources/Icons/Bar/Play.png" />
                            <Image x:Name="Pause" Source="/Foo.Bar;component/Resources/Icons/Bar/Pause.png" Visibility="Collapsed" />
                            <Image x:Name="PlayHover" Source="/Foo.Bar;component/Resources/Icons/Bar/Play_Hover.png" Visibility="{Binding PlayHoverVisible,FallbackValue=Collapsed}" />
                            <Image x:Name="PauseHover" Source="/Foo.Bar;component/Resources/Icons/Bar/Pause_Hover.png" Visibility="{Binding PauseHoverVisible,FallbackValue=Collapsed}" />
                        </Grid>
                    </ControlTemplate>
                </Setter.Value>
            </Setter>
        </Style>
    </UserControl.Resources>
    <Grid x:Name="LayoutRoot" Background="White">
        <ToggleButton Style="{StaticResource MyButtonStyle}" IsChecked="{Binding IsPlaying}" Command="{Binding ChangeStatus}" Height="30" Width="30" />
    </Grid>
</UserControl>

这篇关于Silverlight的MVVM困惑:基于状态更新图片的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆