The animation of previous selected tabitem and selected tabitem started working fine, then it didn't work fine.
It seems to me that the code should work correctly. I don't know why the animation is not correct now.
MainWindow.xaml:
<Window.Resources>
<local:TestViewModel x:Key="vm"/>
<Style TargetType="{x:Type Rectangle}">
<Setter Property="Visibility" Value="Visible"/>
<Setter Property="IsEnabled" Value="True"/>
<Style.Triggers>
<MultiDataTrigger>
<MultiDataTrigger.Conditions>
<Condition Binding="{Binding PreviousSelected }" Value="0"/>
<Condition Binding="{Binding ElementName=TestTabs, Path=SelectedIndex}" Value="1"/>
</MultiDataTrigger.Conditions>
<MultiDataTrigger.EnterActions>
<BeginStoryboard Name="MyBeginStoryboard1">
<Storyboard>
<DoubleAnimation Storyboard.TargetProperty="(Canvas.Left)" From="0" To="40" Duration="0:0:0.2"></DoubleAnimation>
</Storyboard>
</BeginStoryboard>
</MultiDataTrigger.EnterActions>
</MultiDataTrigger>
<MultiDataTrigger>
<MultiDataTrigger.Conditions>
<Condition Binding="{Binding PreviousSelected }" Value="0"/>
<Condition Binding="{Binding ElementName=TestTabs, Path=SelectedIndex}" Value="2"/>
</MultiDataTrigger.Conditions>
<MultiDataTrigger.EnterActions>
<BeginStoryboard Name="MyBeginStoryboard3">
<Storyboard>
<DoubleAnimation Storyboard.TargetProperty="(Canvas.Left)" From="0" To="75" Duration="0:0:0.2"></DoubleAnimation>
</Storyboard>
</BeginStoryboard>
</MultiDataTrigger.EnterActions>
</MultiDataTrigger>
<MultiDataTrigger>
<MultiDataTrigger.Conditions>
<Condition Binding="{Binding PreviousSelected }" Value="0"/>
<Condition Binding="{Binding ElementName=TestTabs, Path=SelectedIndex}" Value="3"/>
</MultiDataTrigger.Conditions>
<MultiDataTrigger.EnterActions>
<BeginStoryboard Name="MyBeginStoryboard5">
<Storyboard>
<DoubleAnimation Storyboard.TargetProperty="(Canvas.Left)" From="0" To="115" Duration="0:0:0.2"></DoubleAnimation>
</Storyboard>
</BeginStoryboard>
</MultiDataTrigger.EnterActions>
</MultiDataTrigger>
<MultiDataTrigger>
<MultiDataTrigger.Conditions>
<Condition Binding="{Binding PreviousSelected }" Value="1"/>
<Condition Binding="{Binding ElementName=TestTabs, Path=SelectedIndex}" Value="0"/>
</MultiDataTrigger.Conditions>
<MultiDataTrigger.EnterActions>
<BeginStoryboard Name="MyBeginStoryboard11">
<Storyboard>
<DoubleAnimation Storyboard.TargetProperty="(Canvas.Left)" From="40" To="0" Duration="0:0:0.2"></DoubleAnimation>
</Storyboard>
</BeginStoryboard>
</MultiDataTrigger.EnterActions>
</MultiDataTrigger>
<MultiDataTrigger>
<MultiDataTrigger.Conditions>
<Condition Binding="{Binding PreviousSelected }" Value="1"/>
<Condition Binding="{Binding ElementName=TestTabs, Path=SelectedIndex}" Value="2"/>
</MultiDataTrigger.Conditions>
<MultiDataTrigger.EnterActions>
<BeginStoryboard Name="MyBeginStoryboard7">
<Storyboard>
<DoubleAnimation Storyboard.TargetProperty="(Canvas.Left)" From="40" To="75" Duration="0:0:0.2"></DoubleAnimation>
</Storyboard>
</BeginStoryboard>
</MultiDataTrigger.EnterActions>
</MultiDataTrigger>
<MultiDataTrigger>
<MultiDataTrigger.Conditions>
<Condition Binding="{Binding PreviousSelected }" Value="1"/>
<Condition Binding="{Binding ElementName=TestTabs, Path=SelectedIndex}" Value="3"/>
</MultiDataTrigger.Conditions>
<MultiDataTrigger.EnterActions>
<BeginStoryboard Name="MyBeginStoryboard9">
<Storyboard>
<DoubleAnimation Storyboard.TargetProperty="(Canvas.Left)" From="40" To="115" Duration="0:0:0.2"></DoubleAnimation>
</Storyboard>
</BeginStoryboard>
</MultiDataTrigger.EnterActions>
</MultiDataTrigger>
<MultiDataTrigger>
<MultiDataTrigger.Conditions>
<Condition Binding="{Binding PreviousSelected }" Value="2"/>
<Condition Binding="{Binding ElementName=TestTabs, Path=SelectedIndex}" Value="0"/>
</MultiDataTrigger.Conditions>
<MultiDataTrigger.EnterActions>
<BeginStoryboard Name="MyBeginStoryboard13">
<Storyboard>
<DoubleAnimation Storyboard.TargetProperty="(Canvas.Left)" From="70" To="0" Duration="0:0:0.2"></DoubleAnimation>
</Storyboard>
</BeginStoryboard>
</MultiDataTrigger.EnterActions>
</MultiDataTrigger>
<MultiDataTrigger>
<MultiDataTrigger.Conditions>
<Condition Binding="{Binding PreviousSelected }" Value="2"/>
<Condition Binding="{Binding ElementName=TestTabs, Path=SelectedIndex}" Value="1"/>
</MultiDataTrigger.Conditions>
<MultiDataTrigger.EnterActions>
<BeginStoryboard Name="MyBeginStoryboard15">
<Storyboard>
<DoubleAnimation Storyboard.TargetProperty="(Canvas.Left)" From="70" To="40" Duration="0:0:0.2"></DoubleAnimation>
</Storyboard>
</BeginStoryboard>
</MultiDataTrigger.EnterActions>
</MultiDataTrigger>
<MultiDataTrigger>
<MultiDataTrigger.Conditions>
<Condition Binding="{Binding PreviousSelected }" Value="2"/>
<Condition Binding="{Binding ElementName=TestTabs, Path=SelectedIndex}" Value="3"/>
</MultiDataTrigger.Conditions>
<MultiDataTrigger.EnterActions>
<BeginStoryboard Name="MyBeginStoryboard17">
<Storyboard>
<DoubleAnimation Storyboard.TargetProperty="(Canvas.Left)" From="70" To="115" Duration="0:0:0.2"></DoubleAnimation>
</Storyboard>
</BeginStoryboard>
</MultiDataTrigger.EnterActions>
</MultiDataTrigger>
</Style.Triggers>
</Style>
</Window.Resources>
<Grid DataContext="{StaticResource vm}" >
<Grid.RowDefinitions>
<RowDefinition Height="*"/>
<RowDefinition Height="50"/>
</Grid.RowDefinitions>
<TabControl SelectedIndex="{Binding Selected,Mode=TwoWay,UpdateSourceTrigger=PropertyChanged}" Grid.Row="0" x:Name="TestTabs">
<TabItem Name="Tab1" Header="News" />
<TabItem Name="Tab2" Header="DLC" />
<TabItem Name="Tab3" Header="Settings"/>
</TabControl>
<DockPanel x:Name="rp" Grid.Row="0" LastChildFill="False" HorizontalAlignment="Stretch">
<Canvas DockPanel.Dock="Left" >
<Rectangle x:Name="Rect1" Fill="#ff0000" VerticalAlignment="Top" Height="4" Margin="0,25,0,0"
SnapsToDevicePixels="True" UseLayoutRounding="True" RenderOptions.EdgeMode="Aliased"
Width="{Binding ElementName=TestTabs, Path=SelectedItem.ActualWidth}" RenderOptions.BitmapScalingMode="HighQuality" />
</Canvas>
</DockPanel>
<StackPanel Orientation="Horizontal" Grid.Row="1">
<Label Content="selected" Width="100" Height="40" />
<TextBox x:Name="sele" Text="{Binding Selected}" Width="100" Height="40" Background="AliceBlue" Margin="5"/>
<Label Content="previousSelected" Width="100" Height="40"/>
<TextBox x:Name="prev" Text="{Binding PreviousSelected,Mode=OneWay}" Width="100" Height="40" Background="AliceBlue" Margin="5"/>
</StackPanel>
</Grid>
MainWindow.xaml.cs:
using System.ComponentModel;
using System.Windows;
namespace TabControlBindSlide
{
public partial class MainWindow : Window
{
public MainWindow()
{
InitializeComponent();
}
}
class TestViewModel : INotifyPropertyChanged
{
private int _selected;
public int Selected
{
get { return _selected; }
set
{
int temp = _selected;
_selected = value;
_previousSelected = temp;
NotifyPropertyChanged("Selected", temp, value);
NotifyPropertyChanged("PreviousSelected", temp, temp);
}
}
int _previousSelected = 0;
public int PreviousSelected
{
get { return _previousSelected; }
}
public event PropertyChangedEventHandler PropertyChanged;
protected void NotifyPropertyChanged<T>(string propertyName, T oldvalue, T newvalue)
{
OnPropertyChanged(this, new PropertyChangedExtendedEventArgs<T>(propertyName, oldvalue, newvalue));
}
public virtual void OnPropertyChanged(object sender, PropertyChangedEventArgs e)
{
PropertyChangedEventHandler handler = PropertyChanged;
if (handler != null)
handler(sender, e);
}
}
public class PropertyChangedExtendedEventArgs<T> : PropertyChangedEventArgs
{
public virtual T OldValue { get; private set; }
public virtual T NewValue { get; private set; }
public PropertyChangedExtendedEventArgs(string propertyName, T oldValue, T newValue)
: base(propertyName)
{
OldValue = oldValue;
NewValue = newValue;
}
}
}
The result: The animation starts working fine, then it doesn't work.
CodePudding user response:
Problem; You should not delete the Storyboard
you created, you should remove it when you are done with the Storyboard
. Because an already existing Storyboard
is not rebuilt, it will only succeed the first time. It will work properly if you render all Storyboards
as below.
<Window.Resources>
<local:TestViewModel x:Key="vm"/>
<Style TargetType="{x:Type Rectangle}">
<Setter Property="Visibility" Value="Visible"/>
<Setter Property="IsEnabled" Value="True"/>
<Style.Triggers>
<MultiDataTrigger>
<MultiDataTrigger.Conditions>
<Condition Binding="{Binding PreviousSelected }" Value="0"/>
<Condition Binding="{Binding ElementName=TestTabs, Path=SelectedIndex}" Value="1"/>
</MultiDataTrigger.Conditions>
<MultiDataTrigger.EnterActions>
<BeginStoryboard Name="MyBeginStoryboard1">
<Storyboard>
<DoubleAnimation Storyboard.TargetProperty="(Canvas.Left)" From="0" To="40" Duration="0:0:0.2"></DoubleAnimation>
</Storyboard>
</BeginStoryboard>
</MultiDataTrigger.EnterActions>
<MultiDataTrigger.ExitActions>
<RemoveStoryboard BeginStoryboardName="MyBeginStoryboard1" />
</MultiDataTrigger.ExitActions>
</MultiDataTrigger>
<MultiDataTrigger>
<MultiDataTrigger.Conditions>
<Condition Binding="{Binding PreviousSelected }" Value="0"/>
<Condition Binding="{Binding ElementName=TestTabs, Path=SelectedIndex}" Value="2"/>
</MultiDataTrigger.Conditions>
<MultiDataTrigger.EnterActions>
<BeginStoryboard Name="MyBeginStoryboard3">
<Storyboard>
<DoubleAnimation Storyboard.TargetProperty="(Canvas.Left)" From="0" To="75" Duration="0:0:0.2"></DoubleAnimation>
</Storyboard>
</BeginStoryboard>
</MultiDataTrigger.EnterActions>
<MultiDataTrigger.ExitActions>
<RemoveStoryboard BeginStoryboardName="MyBeginStoryboard3" />
</MultiDataTrigger.ExitActions>
</MultiDataTrigger>
<MultiDataTrigger>
<MultiDataTrigger.Conditions>
<Condition Binding="{Binding PreviousSelected }" Value="0"/>
<Condition Binding="{Binding ElementName=TestTabs, Path=SelectedIndex}" Value="3"/>
</MultiDataTrigger.Conditions>
<MultiDataTrigger.EnterActions>
<BeginStoryboard Name="MyBeginStoryboard5">
<Storyboard>
<DoubleAnimation Storyboard.TargetProperty="(Canvas.Left)" From="0" To="115" Duration="0:0:0.2"></DoubleAnimation>
</Storyboard>
</BeginStoryboard>
</MultiDataTrigger.EnterActions>
<MultiDataTrigger.ExitActions>
<RemoveStoryboard BeginStoryboardName="MyBeginStoryboard5" />
</MultiDataTrigger.ExitActions>
</MultiDataTrigger>
<MultiDataTrigger>
<MultiDataTrigger.Conditions>
<Condition Binding="{Binding PreviousSelected }" Value="1"/>
<Condition Binding="{Binding ElementName=TestTabs, Path=SelectedIndex}" Value="0"/>
</MultiDataTrigger.Conditions>
<MultiDataTrigger.EnterActions>
<BeginStoryboard Name="MyBeginStoryboard11">
<Storyboard>
<DoubleAnimation Storyboard.TargetProperty="(Canvas.Left)" From="40" To="0" Duration="0:0:0.2"></DoubleAnimation>
</Storyboard>
</BeginStoryboard>
</MultiDataTrigger.EnterActions>
<MultiDataTrigger.ExitActions>
<RemoveStoryboard BeginStoryboardName="MyBeginStoryboard11" />
</MultiDataTrigger.ExitActions>
</MultiDataTrigger>
<MultiDataTrigger>
<MultiDataTrigger.Conditions>
<Condition Binding="{Binding PreviousSelected }" Value="1"/>
<Condition Binding="{Binding ElementName=TestTabs, Path=SelectedIndex}" Value="2"/>
</MultiDataTrigger.Conditions>
<MultiDataTrigger.EnterActions>
<BeginStoryboard Name="MyBeginStoryboard7">
<Storyboard>
<DoubleAnimation Storyboard.TargetProperty="(Canvas.Left)" From="40" To="75" Duration="0:0:0.2"></DoubleAnimation>
</Storyboard>
</BeginStoryboard>
</MultiDataTrigger.EnterActions>
<MultiDataTrigger.ExitActions>
<RemoveStoryboard BeginStoryboardName="MyBeginStoryboard7" />
</MultiDataTrigger.ExitActions>
</MultiDataTrigger>
<MultiDataTrigger>
<MultiDataTrigger.Conditions>
<Condition Binding="{Binding PreviousSelected }" Value="1"/>
<Condition Binding="{Binding ElementName=TestTabs, Path=SelectedIndex}" Value="3"/>
</MultiDataTrigger.Conditions>
<MultiDataTrigger.EnterActions>
<BeginStoryboard Name="MyBeginStoryboard9">
<Storyboard>
<DoubleAnimation Storyboard.TargetProperty="(Canvas.Left)" From="40" To="115" Duration="0:0:0.2"></DoubleAnimation>
</Storyboard>
</BeginStoryboard>
</MultiDataTrigger.EnterActions>
<MultiDataTrigger.ExitActions>
<RemoveStoryboard BeginStoryboardName="MyBeginStoryboard9" />
</MultiDataTrigger.ExitActions>
</MultiDataTrigger>
<MultiDataTrigger>
<MultiDataTrigger.Conditions>
<Condition Binding="{Binding PreviousSelected }" Value="2"/>
<Condition Binding="{Binding ElementName=TestTabs, Path=SelectedIndex}" Value="0"/>
</MultiDataTrigger.Conditions>
<MultiDataTrigger.EnterActions>
<BeginStoryboard Name="MyBeginStoryboard13">
<Storyboard>
<DoubleAnimation Storyboard.TargetProperty="(Canvas.Left)" From="70" To="0" Duration="0:0:0.2"></DoubleAnimation>
</Storyboard>
</BeginStoryboard>
</MultiDataTrigger.EnterActions>
<MultiDataTrigger.ExitActions>
<RemoveStoryboard BeginStoryboardName="MyBeginStoryboard13" />
</MultiDataTrigger.ExitActions>
</MultiDataTrigger>
<MultiDataTrigger>
<MultiDataTrigger.Conditions>
<Condition Binding="{Binding PreviousSelected }" Value="2"/>
<Condition Binding="{Binding ElementName=TestTabs, Path=SelectedIndex}" Value="1"/>
</MultiDataTrigger.Conditions>
<MultiDataTrigger.EnterActions>
<BeginStoryboard Name="MyBeginStoryboard15">
<Storyboard>
<DoubleAnimation Storyboard.TargetProperty="(Canvas.Left)" From="70" To="40" Duration="0:0:0.2"></DoubleAnimation>
</Storyboard>
</BeginStoryboard>
</MultiDataTrigger.EnterActions>
<MultiDataTrigger.ExitActions>
<RemoveStoryboard BeginStoryboardName="MyBeginStoryboard15" />
</MultiDataTrigger.ExitActions>
</MultiDataTrigger>
<MultiDataTrigger>
<MultiDataTrigger.Conditions>
<Condition Binding="{Binding PreviousSelected }" Value="2"/>
<Condition Binding="{Binding ElementName=TestTabs, Path=SelectedIndex}" Value="3"/>
</MultiDataTrigger.Conditions>
<MultiDataTrigger.EnterActions>
<BeginStoryboard Name="MyBeginStoryboard17">
<Storyboard>
<DoubleAnimation Storyboard.TargetProperty="(Canvas.Left)" From="70" To="115" Duration="0:0:0.2"></DoubleAnimation>
</Storyboard>
</BeginStoryboard>
</MultiDataTrigger.EnterActions>
</MultiDataTrigger>
</Style.Triggers>
</Style>
</Window.Resources>
<Grid DataContext="{StaticResource vm}" >
<Grid.RowDefinitions>
<RowDefinition Height="*"/>
<RowDefinition Height="50"/>
</Grid.RowDefinitions>
<TabControl SelectedIndex="{Binding Selected,Mode=TwoWay,UpdateSourceTrigger=PropertyChanged}" Grid.Row="0" x:Name="TestTabs">
<TabItem Name="Tab1" Header="News" />
<TabItem Name="Tab2" Header="DLC" />
<TabItem Name="Tab3" Header="Settings"/>
</TabControl>
<DockPanel x:Name="rp" Grid.Row="0" LastChildFill="False" HorizontalAlignment="Stretch">
<Canvas DockPanel.Dock="Left" >
<Rectangle x:Name="Rect1" Fill="#ff0000" VerticalAlignment="Top" Height="4" Margin="0,25,0,0"
SnapsToDevicePixels="True" UseLayoutRounding="True" RenderOptions.EdgeMode="Aliased"
Width="{Binding ElementName=TestTabs, Path=SelectedItem.ActualWidth}" RenderOptions.BitmapScalingMode="HighQuality" />
</Canvas>
</DockPanel>
<StackPanel Orientation="Horizontal" Grid.Row="1">
<Label Content="selected" Width="100" Height="40" />
<TextBox x:Name="sele" Text="{Binding Selected}" Width="100" Height="40" Background="AliceBlue" Margin="5"/>
<Label Content="previousSelected" Width="100" Height="40"/>
<TextBox x:Name="prev" Text="{Binding PreviousSelected,Mode=OneWay}" Width="100" Height="40" Background="AliceBlue" Margin="5"/>
</StackPanel>
</Grid>