如何根据ViewModel属性的值获取View元素淡入/淡出?

时间:2009-07-07 14:22:31

标签: wpf xaml animation mvvm triggers

下面列出的查看 ViewModel 会显示两个按钮:

  • 点击显示工具栏时,工具栏淡入
  • 点击隐藏工具栏时,工具栏淡出

但是,以下情况不起作用:

  • 当加载应用程序并触发OnPropertyChanged(“PageToolBarVisible”)时,如果值为 false ,则工具栏会显示尽管如此(为什么会这样?
  • 加载应用程序并触发OnPropertyChanged(“PageToolBarVisible”)时,如果值为 true ,则工具栏确实淡入,但是,这不是应该发生加载,但只有当按下按钮明确更改时,所以我更改构造函数来执行此操作:_pageToolBarVisible =“true”,但工具栏仍然仍然淡入即使从未调用 OnPropertyChanged 为什么会这样?

查看:

<Window x:Class="TestAnim334.Views.MainView"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    xmlns:c="clr-namespace:TestAnim334.Commands"
    Title="Main Window" Height="400" Width="800">

    <Window.Resources>
        <Style x:Key="PageToolBarStyle" TargetType="Border">
            <Style.Triggers>
                <DataTrigger Binding="{Binding PageToolBarVisible}" Value="true">

                    <DataTrigger.EnterActions>
                        <BeginStoryboard>
                            <Storyboard>
                                <DoubleAnimation
                                    Storyboard.TargetProperty="Opacity"
                                    From="0.0" 
                                    To="1.0" 
                                    Duration="0:0:1"/>
                            </Storyboard>
                        </BeginStoryboard>
                    </DataTrigger.EnterActions>

                    <DataTrigger.ExitActions>
                        <BeginStoryboard>
                            <Storyboard>
                                <DoubleAnimation
                                    Storyboard.TargetProperty="Opacity"
                                    From="1.0" 
                                    To="0.0" 
                                    Duration="0:0:1"/>
                            </Storyboard>
                        </BeginStoryboard>
                    </DataTrigger.ExitActions>

                </DataTrigger>

                <Trigger Property="Opacity" Value="0">
                    <Setter Property="Visibility" Value="Collapsed"/>
                </Trigger>

            </Style.Triggers>
        </Style>

    </Window.Resources>


    <DockPanel LastChildFill="False">

        <StackPanel DockPanel.Dock="Top"
                    Margin="10">

            <TextBlock Text="This is the content of the page."/>
            <TextBlock Text="The ViewModel property is:"/>
            <TextBlock Text="{Binding PageToolBarVisible}"/>
            <Button Content="Hide ToolBar" 
                    Width="150"
                    Command="{Binding HideToolBarCommand}"
                    HorizontalAlignment="Left"/>
            <Button Content="Show ToolBar" 
                    Width="150"
                    Command="{Binding ShowToolBarCommand}"
                    HorizontalAlignment="Left"/>

        </StackPanel>

        <Border Style="{StaticResource PageToolBarStyle}"
            Height="40"
            DockPanel.Dock="Bottom" Background="#ddd" CornerRadius="5">
            <TextBlock FontSize="24" Text="This is the ToolBar text"/>
        </Border>

    </DockPanel>


</Window>

视图模型:

using System.Windows.Input;
using TestAnim334.Commands;

namespace TestAnim334.ViewModels
{
    public class MainViewModel : ViewModelBase
    {

        #region ViewModelProperty: PageToolBarVisible
        private string _pageToolBarVisible;
        public string PageToolBarVisible
        {
            get
            {
                return _pageToolBarVisible;
            }

            set
            {
                _pageToolBarVisible = value;
                OnPropertyChanged("PageToolBarVisible");
            }
        }
        #endregion

        #region DelegateCommand: HideToolBar
        private DelegateCommand hideToolBarCommand;

        public ICommand HideToolBarCommand
        {
            get
            {
                if (hideToolBarCommand == null)
                {
                    hideToolBarCommand = new DelegateCommand(HideToolBar, CanHideToolBar);
                }
                return hideToolBarCommand;
            }
        }

        private void HideToolBar()
        {
            PageToolBarVisible = "false";
        }

        private bool CanHideToolBar()
        {
            return PageToolBarVisible == "true";
        }
        #endregion

        #region DelegateCommand: ShowToolBar
        private DelegateCommand showToolBarCommand;

        public ICommand ShowToolBarCommand
        {
            get
            {
                if (showToolBarCommand == null)
                {
                    showToolBarCommand = new DelegateCommand(ShowToolBar, CanShowToolBar);
                }
                return showToolBarCommand;
            }
        }

        private void ShowToolBar()
        {
            PageToolBarVisible = "true";
        }

        private bool CanShowToolBar()
        {
            return PageToolBarVisible == "false";
        }
        #endregion

        public MainViewModel()
        {
            PageToolBarVisible = "false";
        }

    }
}

1 个答案:

答案 0 :(得分:1)

好的回答你问题的两个部分:

  1. 为什么在加载工具栏时将PageToolBarVisible触发为“False”仍然显示: 你唯一隐藏了工具栏中带有动画的“ExitActions”,它们没有被击中。逻辑流如此。

    if(PageToolBarVisible == true)    运行EnterActions

    if(PageToolBarVisible变为false)      运行ExitActions

    if(PageToolBarVisible开头为false)      什么都不做

    if(PageToolBarVisible从false开始并设置为false)      什么都不做

  2. 结论,因为PageToolBarVisible没有从True变为False ......动画不会运行。

    解决方案:

    考虑使用第二个DataTrigger处理PageToolBarVisible属性的False大小写。或者您可以将Property设置为True然后将False设置为您的ExitActions(虽然我不确定这是否A)工作或B)是一个很好的解决方案)

    1. 为什么设置Property的支持字段仍会在加载时运行动画:

      我相信这里发生的事情是,当应用程序加载时,Binding正在检查属性的值,如果你设置了支持字段的值,那么应该从“Get”获取它“PageToolBarVisible”。

      所以并不是你在触发OnPropertyChanged,而是在你的应用加载时Binding正在获取值

    2. 解决方案:

      要么重新考虑你对触发器的绑定方式以及动画的逻辑。或者你可以玩绑定模式,说实话我不认为有一种模式可以满足你正在寻找的条件,但我可能是错的。