WPF Szukam sposobu na ukrywanie i pokazywanie kontrolki PŁYNNIE w zależności od wartości

0

Witajcie !
Mam flagę IsCurrentlyLogged (ustawioną ze startu na false) oraz 2 x <grid>.
Początkowo grid1 jest widoczny, a grid2 nie.
Gdy IsCurrentlyLogged zmieni się na TRUE chciałbym, aby grid1 zniknął natychmiast (zwykły trigger), a grid2 pojawił się płynnie.
Myślałem, żeby zrobić to drugie za pomocą EventTriggera i animacji, jednak nie potrafię dobrać odpowiedniego RoutedEventu. Wtedy sztucznie w setterze ustawiałbym focusa czy coś, ale to mało profesjonalne. Macie jakieś sugestie? I dlaczego w zwykłym triggerze nie można robić animacji?

2

Żeby zrobić animację znikania i pojawiania się kontrolki możesz zrobić taki mały myk. Ze zwykłym Visibility się nie da.

XAML:

<Window x:Class="WPF_4Prog.MainWindow"
        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:local="clr-namespace:WPF_4Prog"
        mc:Ignorable="d"
        Title="MainWindow" 
        WindowStartupLocation="CenterScreen" SizeToContent="Height"
        Width="400" ResizeMode="NoResize">
  <Grid Height="{Binding InnerGridHeight, UpdateSourceTrigger=PropertyChanged}">
    <Grid.ColumnDefinitions>
      <ColumnDefinition Width="*"/>
    </Grid.ColumnDefinitions>
    <Grid.RowDefinitions>
      <RowDefinition Height="*"/>
    </Grid.RowDefinitions>
    <DockPanel Grid.Row="0" Grid.Column="0">
      <Button Content="Up" Command="{Binding UpPressed}" Height="30"
              VerticalAlignment="Top" DockPanel.Dock="Top"/>
      <Button Content="Down" Command="{Binding DownPressed}"
              VerticalAlignment="Bottom" DockPanel.Dock="Top"
              Height="{Binding LowerButtonHeight, UpdateSourceTrigger=PropertyChanged}"/>
    </DockPanel>
  </Grid>
</Window>

ViewModel:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

using System.Collections.ObjectModel;
using System.ComponentModel;
using System.Windows.Input;
using System.Windows;
using System.Timers;
using WPF_4Prog.Commands;
using WPF_4Prog.Helpers;
using WPF_4Prog.Interfaces;

namespace WPF_4Prog.ViewModel
{
    public class MainWindowVM : ViewModelBase
    {
        private enum Action
        {
            Folding,
            Expanding
        }

        private int innerGridHeight;
        public int InnerGridHeight
        {
            get { return this.innerGridHeight; }
            set
            {
                this.innerGridHeight = value;
                this.OnPropertyChanged(nameof(this.InnerGridHeight));
            }
        }

        private int lowerButtonHeight;
        public int LowerButtonHeight
        {
            get { return this.lowerButtonHeight; }
            set
            {
                this.lowerButtonHeight = value;
                this.OnPropertyChanged(nameof(this.LowerButtonHeight));
            }
        }

        public MainWindowVM()
        {
            this.InnerGridHeight = 200;
            this.LowerButtonHeight = 0;
        }

        public ICommand UpPressed
        {
            get
            {
                return new RelayCommand(() =>
                {
                    this.ProcessLowerButton(Action.Expanding);
                });
            }
        }

        public ICommand DownPressed
        {
            get
            {
                return new RelayCommand(() =>
                {
                    this.ProcessLowerButton(Action.Folding);
                });
            }
        }

        private void ProcessLowerButton(Action action)
        {
            var upperButtonHeight = 30;
            var timer = new Timer(5);
            timer.Elapsed += (sender, e) =>
            {
                switch (action)
                {
                    case Action.Folding:
                        {
                            if (this.LowerButtonHeight > 0) this.LowerButtonHeight--;
                            else timer.Stop();
                            break;
                        }
                    case Action.Expanding:
                        {
                            if (this.LowerButtonHeight < this.InnerGridHeight - upperButtonHeight) this.LowerButtonHeight++;
                            else timer.Stop();
                            break;
                        }
                }
            };
            timer.Start();
        }
    }
}

ViewModelBase:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.ComponentModel;

namespace WPF_4Prog.Helpers
{
    public class ViewModelBase : INotifyPropertyChanged
    {
        public event PropertyChangedEventHandler PropertyChanged;
        public void OnPropertyChanged(string propertyName)
        {
            var handler = this.PropertyChanged;
            if (handler != null) handler(this, new PropertyChangedEventArgs(propertyName));
        }
    }
}

I kontrolka ładnie się rozwija. Trzeba by tylko pilnować żeby się nie odpalał więcej niż jeden timer i takie tam inne rzeczy, bo to przykład pisany na szybko.
Ale działa.

0

Faktycznie tak to można zrobić. Ale czytam o animacjach i chcę w zależności od triggera zmieniać opacity usercontrola. Jednak animacje mogę ustawiać tylko w eventtriggerze, trigger zwykły tego nie obsługuje. Da się to jakoś obejść? Chodzi tu o sam WPF, to musi być możliwe do zrobienia :)

0

@grzesiek51114 wiem jak zrobić to w c#, ale mi chodzi jak to zrobić w WPF. Chodzi mi o wykorzystanie do tego animacji. Np. nie mam problemu z płynną zmianą rozmiaru tekstu "Zarejestruj się", ale nie wiem jak Wywołać animację w momencie zmiany zmiennej typu bool.
112e2441f8.png

1

Triggery jak najbardziej obsługują animacje ;)

 
<Grid  Margin="0,85,0,0">
            <Grid.Resources>
                <Style TargetType="Grid">
                    <Setter Property="Background" Value="Blue"/>
                    <Style.Triggers>
                        <DataTrigger Binding="{Binding IsCurrentlyLogged}" Value="True">
                            <DataTrigger.EnterActions>
                                <BeginStoryboard>
                                    <Storyboard>
                                        <DoubleAnimation Storyboard.TargetProperty="Opacity" From="1.0" To="0.0" Duration="0:0:2"/>
                                    </Storyboard>
                                </BeginStoryboard>
                            </DataTrigger.EnterActions>
                            <DataTrigger.ExitActions>
                                <BeginStoryboard>
                                    <Storyboard>
                                        <DoubleAnimation Storyboard.TargetProperty="Opacity" From="0.0" To="1.0" Duration="0:0:2"/>
                                    </Storyboard>
                                </BeginStoryboard>
                            </DataTrigger.ExitActions>
                        </DataTrigger>
                    </Style.Triggers>
                </Style>
            </Grid.Resources>            
        </Grid>

1 użytkowników online, w tym zalogowanych: 0, gości: 1