Change TabIndex with Storyboard - wpf

Is there a way to change the TabIndex (in XAML only) when a button is clicked.
Below is my try following this article and one on my own which is commented.
Thanks!
<StackPanel>
<Button x:Name="Button" Content="Go" />
<TabControl x:Name="Tab">
<TabItem Header="First">
<TextBlock Text="First" />
</TabItem>
<TabItem Header="Second">
<TextBlock Text="Second" />
</TabItem>
<TabControl.Triggers>
<EventTrigger RoutedEvent="Button.PreviewMouseLeftButtonDown">
<BeginStoryboard>
<Storyboard>
<Int32AnimationUsingKeyFrames
Duration="0"
Storyboard.TargetName="Tab"
Storyboard.TargetProperty="TabIndex">
<DiscreteInt32KeyFrame
KeyTime="0"
Value="1" />
</Int32AnimationUsingKeyFrames>
<!--<Int32Animation
Duration="0"
Storyboard.TargetName="Tab"
Storyboard.TargetProperty="TabIndex"
FillBehavior="HoldEnd"
By="1"
From="0"
To="1" />-->
</Storyboard>
</BeginStoryboard>
</EventTrigger>
</TabControl.Triggers>
</TabControl>
</StackPanel>
Edit: Use SelectedIndex instead of TabIndex to change the current tab.

Your event trigger is misplaced. Instead of placing the trigger on TabControl, place trigger on StackPanel.
<StackPanel.Triggers>
<EventTrigger RoutedEvent="Button.PreviewMouseLeftButtonDown">
<BeginStoryboard>
<Storyboard>
<Int32AnimationUsingKeyFrames Duration="0"
Storyboard.TargetName="Tab"
Storyboard.TargetProperty="TabIndex">
<DiscreteInt32KeyFrame KeyTime="0"
Value="1" />
</Int32AnimationUsingKeyFrames>
</Storyboard>
</BeginStoryboard>
</EventTrigger>
</StackPanel.Triggers>
Reason:
Button.PreviewMouseLeftButtonDown is a tunnelling routed attached event i.e. it will start from root element and continue to tunnel until it reaches actual sender. So, it will start from window or UserControl and will continue to tunnel until it reaches Go button. It won't tunnel to TabControl since it is sibling of button and not a parent of TabControl.
But it will work if you place it on StackPanel since StackPanel is parent of TabControl and Button. Before tunnelling to GO Button, it will pass via StackPanel. Hence, your storyBoard will work.

Related

Animation triggering on property change doesn't seem to fire

I'm trying to make a status textblock that will display things like "Database updated" and other information for which a dialog would be overkill. It should flash on the screen and then fade away within 2 seconds or so. The goal is that it will sit at opacity 0 until its binding is updated, then 1 opacity and fade out. Problem is, what I came up with doesn't seem to trigger at all. Here's my code:
<TextBlock Text="{Binding AppState.Feedback}" x:Name="feedbackBlock"
Opacity="0" FontSize="100" Foreground="Black">
<TextBlock.Triggers>
<EventTrigger RoutedEvent="Binding.TargetUpdated">
<BeginStoryboard>
<Storyboard>
<DoubleAnimation Storyboard.TargetName="feedbackBlock"
Storyboard.TargetProperty="Opacity" To="1" Duration="0:0:2" />
</Storyboard>
</BeginStoryboard>
</EventTrigger>
</TextBlock.Triggers>
</TextBlock>
Not really sure where to start in debugging this, I don't get an error, it just doesn't show.
You haven't told the Binding to fire the TargetUpdated event. Add NotifyOnTargetUpdated=True to the Binding expression. Besides that, you don't need to set Storyboard.TargetName:
<TextBlock x:Name="feedbackBlock"
Text="{Binding AppState.Feedback, NotifyOnTargetUpdated=True}"
Opacity="0" FontSize="100" Foreground="Black">
<TextBlock.Triggers>
<EventTrigger RoutedEvent="Binding.TargetUpdated">
<BeginStoryboard>
<Storyboard>
<DoubleAnimation Storyboard.TargetProperty="Opacity"
To="1" Duration="0:0:2" />
</Storyboard>
</BeginStoryboard>
</EventTrigger>
</TextBlock.Triggers>
</TextBlock>

Button appearance animation in Datatemplate

I have a button inside a DataTemplate of a ListBox.
Whenever a button is added to the Listbox,I want to animate the appearance of the new button by setting the opacity from minimum to maximum.
How do I do this?
You could listen to Loaded event. When Loaded wpf will trigger your animation.
Here is an example how you could achieve that:
<Button Height="23" Margin="102,95,100,0" Name="button3" VerticalAlignment="Top" Content="Opacity">
<Button.Triggers>
<EventTrigger RoutedEvent="Loaded">
<BeginStoryboard>
<Storyboard>
<DoubleAnimation
Storyboard.TargetProperty="Opacity"
From="1"
To="0"
Duration="0:0:1"/>
</Storyboard>
</BeginStoryboard>
</EventTrigger>
</Button.Triggers>
</Button>

Event for MouseOver action in WPF

I want to handle mouse over and mouse out events for a grid. Does WPF have events for this.
Note: I dont want to use IsMouseOver property in my style.
i have used MouseEnter and MouseLeave method but without much success.
You can use EventTriggers to capture MouseEnter and MouseLeave events in XAML.
Here is a simple example that changes the background of a StackPanel in a Grid:
<Grid>
<Grid.RowDefinitions>
<RowDefinition/>
<RowDefinition/>
</Grid.RowDefinitions>
<StackPanel Grid.Row="1" Background="Blue">
<StackPanel.Style>
<Style>
<Style.Triggers>
<EventTrigger RoutedEvent="StackPanel.MouseEnter">
<EventTrigger.Actions>
<BeginStoryboard>
<Storyboard>
<ColorAnimation
AutoReverse="False"
Duration="0:0:1"
From="Blue" To="Red"
AccelerationRatio="1"
Storyboard.TargetProperty="(StackPanel.Background).(SolidColorBrush.Color)"
FillBehavior="HoldEnd">
</ColorAnimation>
</Storyboard>
</BeginStoryboard>
</EventTrigger.Actions>
</EventTrigger>
<EventTrigger RoutedEvent="StackPanel.MouseLeave">
<EventTrigger.Actions>
<BeginStoryboard>
<Storyboard>
<ColorAnimation
AutoReverse="False"
Duration="0:0:1"
From="Red" To="Blue"
AccelerationRatio="1"
Storyboard.TargetProperty="(StackPanel.Background).(SolidColorBrush.Color)"
FillBehavior="HoldEnd">
</ColorAnimation>
</Storyboard>
</BeginStoryboard>
</EventTrigger.Actions>
</EventTrigger>
</Style.Triggers>
</Style>
</StackPanel.Style>
</StackPanel>
</Grid>
A WPF Grid control supports both the MouseEnter and MouseLeave events. You should be able to hook up event handlers for both.
More simple :
You can implement the two events PointerMoved and PointerExited. It worked for me.
MouseEnter and MouseLeave events may be handled , you can check your code set e.handled = false;

Blinking TextBlock

Hi iam trying to make an Wpf TextBlock to blink. I want like when im clicking on an button then the textblock blinks. How can i achive this.
I have tried the following.
<TextBlock Name="txtBlockScannerText" Margin="10,0,0,0" Style="{StaticResource TextBlockNormal}" Text="Skanna Inleverans listan">
<TextBlock.Triggers>
<EventTrigger RoutedEvent="TextBlock.MouseEnter">
<EventTrigger.Actions>
<BeginStoryboard>
<Storyboard BeginTime="00:00:00" RepeatBehavior="Forever" Storyboard.TargetName="txtBlockScannerText" Storyboard.TargetProperty="(Foreground).(SolidColorBrush.Color)">
<ColorAnimation From="Black" To="Red" Duration="0:0:1"/>
</Storyboard>
</BeginStoryboard>
</EventTrigger.Actions>
</EventTrigger>
</TextBlock.Triggers>
</TextBlock>
But with this code it only blinks when my mouse enter it. How can i trigger the blink in an button click event. Or how do i call the event to blink. Thanks for help
Here is the solution
<TextBlock Name="txtBlockScannerText" Margin="10,0,0,0" Text="WELCOME"> </TextBlock>
<Button Content="Click Me" Height="23" HorizontalAlignment="Left" Margin="225,43,0,0" Name="button1" VerticalAlignment="Top" Width="75">
<Button.Triggers>
<EventTrigger RoutedEvent="Button.Click">
<EventTrigger.Actions>
<BeginStoryboard>
<Storyboard BeginTime="00:00:00"
RepeatBehavior="Forever"
Storyboard.TargetName="txtBlockScannerText"
Storyboard.TargetProperty="(Foreground).(SolidColorBrush.Color)">
<ColorAnimation From="Black" To="Blue" Duration="0:0:1"/>
</Storyboard>
</BeginStoryboard>
</EventTrigger.Actions>
</EventTrigger>
</Button.Triggers>
</Button>
There's no click event on a TextBlock. If you use a button with the textblock as content you can hook up your animation to the button's click event. You may need to style the button to remove 3D look or what else you may choose as default style for your buttons.
Make your trigger listen to the Loaded event rather than the MouseEnter event...
<EventTrigger RoutedEvent="TextBlock.Loaded">

Validation adorner does not completely disappear in Animation

I have a WPF Window that contains a ContentPresenter that has Height and Width set to 0 by default.
When a user clicks a button, I run an animation to transform the ContentPresenter's Height and Width properties to 896,1024 (actually it does 3 rotations whilst its growing, too) and this is all good...
The DataContext for the User control implements IDataErrorInfo and if the user does not click the 'I have read and understand these Health & Safety instructions" checkbox, then a red border is shown around the checkbox...
My problem is that if the user clicks 'Cancel', and I run the animation that shrinks the Height & Width back down to 0,0, then the UserControl shrinks as required, but the red border does not completely disappear - it leaves a single red pixel in the middle of my Window
Anybody any ideas what I'm doing wrong? The 'red-border', I'm assuming is just an Adorner being rendered by WPF for me, so I'm not sure how to change this behaviour...
All help much appreciated!
Update - I tried Abe's excellent suggestion, but unfortunately it didn't work, but it did get me trying other stuff... So now I have (temporarily) commented out the 'shrinking' animations, and simply set the visibility to Collapsed at KeyTime="0:0:0.9"... when I press cancel, just less than a second later, the UserControl disappears but the red adorner stubbornly remains :(
As an extra bit of info (not sure if relevant?) the UserControl being shown in the ContentPresenter also contains a ContentPresenter to render a UserControl, and its the inner content that contains the validation adorner...
code sample:
<Button
Name="signInButton"
Grid.Row="0" Grid.Column="0"
Margin="30"
HorizontalAlignment="Right" VerticalAlignment="Bottom"
Style="{StaticResource LargeButtonStyle}"
Content="Sign In"
Command="{Binding SignInCommand}">
<Button.Triggers>
<EventTrigger
RoutedEvent="Button.Click">
<BeginStoryboard
Storyboard="{DynamicResource openViewAnimation}" />
</EventTrigger>
</Button.Triggers>
</Button>
<ContentPresenter
Name="mainView"
Grid.RowSpan="2" Grid.ColumnSpan="2"
HorizontalAlignment="Center" VerticalAlignment="Center"
Opacity="0.9"
Content="{Binding CurrentContent}">
<ContentPresenter.RenderTransform>
<RotateTransform
Angle="0" />
</ContentPresenter.RenderTransform>
</ContentPresenter>
<Storyboard x:Key="closeViewAnimation">
<DoubleAnimation
Storyboard.TargetName="mainView" Storyboard.TargetProperty="Height"
From="896" To="0" Duration="0:0:0.9"
AutoReverse="False" RepeatBehavior="1x" />
<DoubleAnimation
Storyboard.TargetName="mainView" Storyboard.TargetProperty="Width"
From="1024" To="0" Duration="0:0:0.9"
AutoReverse="False" RepeatBehavior="1x" />
</Storyboard>
Thanks, Ian
If you add an ObjectAnimationUsingKeyFrames that sets the Visibility of the element to Collapsed at the time that the other animations complete, the adorner will go away also.
<Storyboard x:Key="closeViewAnimation">
<DoubleAnimation
Storyboard.TargetName="mainView" Storyboard.TargetProperty="Height"
From="896" To="0" Duration="0:0:0.9"
AutoReverse="False" RepeatBehavior="1x" />
<DoubleAnimation
Storyboard.TargetName="mainView" Storyboard.TargetProperty="Width"
From="1024" To="0" Duration="0:0:0.9"
AutoReverse="False" RepeatBehavior="1x" />
<ObjectAnimationUsingKeyFrames
Storyboard.TargetName="mainView"
Storyboard.TargetProperty="Visibility">
<DiscreteObjectKeyFrame Value="{x:Static Visibility.Collapsed}"
KeyTime="0:0:0.9" />
</ObjectAnimationUsingKeyFrames>
</Storyboard>
Obviously, you would need to do the reverse operation at KeyTime 0 for the openViewAnimation.

Resources