views:

246

answers:

1

The View and ViewModel listed below show two buttons:

  • when you click Show ToolBar, the toolbar fades in
  • when you click Hide ToolBar, the toolbar fades out

However, the following things don't work:

  • when the application is loaded and OnPropertyChanged("PageToolBarVisible") is fired, if the value is false then the Toolbar shows in spite of that fact (why is that?)
  • when the application is loaded and OnPropertyChanged("PageToolBarVisible") is fired, if the value is true then the toolbar does indeed fade in, however, this is not supposed to happen on loading but only when explicitly changed by pressing the buttons, so I change the constructor to do this: _pageToolBarVisible = "true", but then the toolbar still still fades in even though the OnPropertyChanged was never called (why is that?)

View:

<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>

ViewModel:

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";
        }

    }
}
A: 

Ok to answer the two parts of your question:

  1. Why when PageToolBarVisible is fired as "False" at loading the toolbar still shows: Your only hiding the toolbar with the animation in the "ExitActions", which aren't being hit. The logic flows as such.

    if(PageToolBarVisible == true) Run EnterActions

    if(PageToolBarVisible changes to false) Run ExitActions

    if(PageToolBarVisible starts as false) Do nothing

    if(PageToolBarVisible starts as false and is set to false) Do nothing

Conclusion, because the PageToolBarVisible is not changing from True to False ... the animation doesn't run.

Solution:

Consider having a second DataTrigger that handles the False case for your PageToolBarVisible property. Or you can set the Property to True and then False to hit your ExitActions (though I'm not sure if this would A) work or B) be a good solution)

  1. Why setting the backing field for the Property still runs the animation when loaded:

    I believe what is happening here, is that when the application loads, the Binding is checking the value of the property, if you've set the value of the backing field then it should be getting this from the "Get" on "PageToolBarVisible".

    So it's not that you're triggering the OnPropertyChanged, it's that the Binding is getting the value when your app is loading

Solution:

Either rethink your logic around how your binding to the trigger and thus the animation. Or you can play with the Binding Modes, to be honest I don't think there's a mode that would satisfy the conditions you're looking for, however I might be wrong.

Chris Nicol