How to target a group of controls in a storyboard WPF - wpf

<Storyboard x:Key="OnClick1">
<DoubleAnimation Storyboard.TargetName="{StaticResource test}"
Storyboard.TargetProperty="Opacity"
From="1"
To="0"
RepeatBehavior="2000"
AutoReverse="True"
Duration="0:0:0.7"/>
</Storyboard>
<Window.Triggers>
<EventTrigger RoutedEvent="ButtonBase.Loaded" SourceName="button">
<BeginStoryboard Storyboard="{StaticResource OnClick1}"/>
</EventTrigger>
</Window.Triggers>
<Button x:Name="button2" x:key="test" Content="Button" Margin="234,140,164,0" Height="37" VerticalAlignment="Top"/>
<Button x:Name="button3" x:key="test" Content="Button" Margin="234,140,164,0" Height="37" VerticalAlignment="Top"/>
I am trying to add this double animation to multiple buttons without duplicating the double animation. Initially, I had the TargetName set to the name of the first button and it works but if added key to the button I get this message "The property "key" does not exist in WinFX namespace.

Give ButtonA the storyboard that drives its Opacity. For each other button,
<Button
x:Name="button3"
Opacity="{Binding Opacity, ElementName=button2}"
...
/>
Alternatively, put all the buttons inside a StackPanel (or Grid, or whatever), and animate the parent's Opacity.

The sample markup you have posted doesn't provide a reproducible sample of your issue but you could add a trigger to each Button that you want to animate:
<Window x:Class="WpfApplication1.Window1"
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"
mc:Ignorable="d"
Title="Window1" Height="300" Width="300">
<Window.Resources>
<Storyboard x:Key="OnClick1">
<DoubleAnimation
Storyboard.TargetProperty="Opacity"
From="1"
To="0"
RepeatBehavior="2000"
AutoReverse="True"
Duration="0:0:0.7"/>
</Storyboard>
</Window.Resources>
<StackPanel>
<Button x:Name="button2" Content="Button" Height="37" VerticalAlignment="Top">
<Button.Triggers>
<EventTrigger RoutedEvent="Loaded">
<BeginStoryboard Storyboard="{StaticResource OnClick1}"/>
</EventTrigger>
</Button.Triggers>
</Button>
<Button x:Name="button3" Content="Button" Height="37" VerticalAlignment="Top">
<Button.Triggers>
<EventTrigger RoutedEvent="Loaded">
<BeginStoryboard Storyboard="{StaticResource OnClick1}"/>
</EventTrigger>
</Button.Triggers>
</Button>
</StackPanel>
</Window>

Related

Binding to DoubleAnimation.To

I wish to bind DoubleAnimation.To to a dependency property and trigger the animation when that property changes. I can get the basic animation to work, but cannot figure out how to trigger it when the property changes.
The example shows me trying to animate Rectangle's Canvas.Left property. Note that I have bound DoubleAnimation.To to Position. I want the animation to run and move my rectangle when Position changes. Can someone help me figure out the correct trigger?
<Viewbox>
<Canvas Height="200" Width="200">
<Rectangle Name="MyRectangle" Canvas.Left="50" Canvas.Top="50" Width="100" Height="100" Fill="Blue">
<Rectangle.Triggers>
<EventTrigger RoutedEvent="Rectangle.Loaded">
<BeginStoryboard>
<Storyboard Name="MyStoryboard">
<DoubleAnimation Storyboard.TargetName="MyRectangle"
Storyboard.TargetProperty="(Canvas.Left)"
To="{Binding Position}" Duration="0:0:5" />
</Storyboard>
</BeginStoryboard>
</EventTrigger>
</Rectangle.Triggers>
</Rectangle>
</Canvas>
The answer is to use an EventTrigger and set its RoutedEvent property to Binding.TargetUpdated. Also, you must add NotifyOnTargetUpdated=True to your binding (Position, in my case).
<Viewbox>
<Canvas Height="200" Width="200">
<Rectangle Name="MyRectangle" Canvas.Left="50" Canvas.Top="50" Width="100" Height="100" Fill="Blue">
<Rectangle.Triggers>
<EventTrigger RoutedEvent="Binding.TargetUpdated">
<BeginStoryboard>
<Storyboard Name="MyStoryboard">
<DoubleAnimation Storyboard.TargetName="MyRectangle"
Storyboard.TargetProperty="(Canvas.Left)"
To="{Binding Position, NotifyOnTargetUpdated=True}" Duration="0:0:5" />
</Storyboard>
</BeginStoryboard>
</EventTrigger>
</Rectangle.Triggers>
</Rectangle>
</Canvas>
</Viewbox>

Begin a StoryBoard when IsOpen property of a Popup is set to True

How to Begin a StoryBoard when IsOpen property of a Popup is set to True?
ex:
<EventTrigger RoutedEvent="{Binding IsOpen, ElementName=pop}">
<BeginStoryboard>
<Storyboard>
<DoubleAnimation Storyboard.TargetName="pop"
Storyboard.TargetProperty="Height"
Duration="0:0:1"
From="0.0"
To="200" />
<DoubleAnimation Storyboard.TargetName="pop"
Storyboard.TargetProperty="Width"
Duration="0:0:1"
From="0.0"
To="{Binding ElementName=root,Path=ActualWidth}" />
</Storyboard>
</BeginStoryboard>
</EventTrigger>
I know EventTrigger RoutedEvent="{Binding IsOpen, ElementName=pop} is not ok
Thank you!
Since you did not mark for Answer, I assumed you still need some help in this.
Here is a code snippet that will work your way (as per H.B.'s post)
<Window x:Class="WpfTestApp.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Title="MainWindow" Height="350" Width="525">
<Window.Resources>
<Style x:Key="PopupStyle" TargetType="{x:Type Popup}">
<Style.Triggers>
<Trigger Property="IsOpen" Value="True">
<Trigger.EnterActions>
<BeginStoryboard>
<Storyboard>
<DoubleAnimation
Storyboard.TargetProperty="Height"
Duration="0:0:1"
From="0.0"
To="200" />
<DoubleAnimation
Storyboard.TargetProperty="Width"
Duration="0:0:1"
From="0.0"
To="500" />
</Storyboard>
</BeginStoryboard>
</Trigger.EnterActions>
</Trigger>
</Style.Triggers>
</Style>
</Window.Resources>
<Grid>
<Button Content="Button" Height="29" HorizontalAlignment="Left" Margin="24,19,0,0" Name="button1" VerticalAlignment="Top" Width="90" Click="button1_Click" />
<Popup Name="pop" Style="{StaticResource PopupStyle}" >
<Grid Background="Red">
<TextBlock Text="I am in pop up" />
</Grid>
</Popup>
</Grid>
and the button click event handler in code behind to open the pop up..
private void button1_Click(object sender, RoutedEventArgs e)
{
pop.PlacementTarget = (Button)sender;
pop.IsOpen = true;
}
Create a Style for the Popup.
Trigger on IsOpen -> true
Use Trigger.EnterActions to start a storyboard.

WPF - Setting usercontrol width using triggers and mouseenter event

I have a wrap panel full of usercontrols. When I hover the mouse over a usercontrol I want it to expand to show more details.
Some stripped down sample code:
<UserControl x:Class="WPFTestBed.UserControl1"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Height="300" Width="300">
<UserControl.Resources>
</UserControl.Resources>
<UserControl.Triggers>
<EventTrigger RoutedEvent="Mouse.MouseEnter">
<EventTrigger.Actions>
<Setter TargetName="WPFTestBed.UserControl1" Property="Control.Width" Value="200"/>
</EventTrigger.Actions>
</EventTrigger>
</UserControl.Triggers>
<Grid Height="95" Width="123">
<Button Height="23" HorizontalAlignment="Left" Margin="17,30,0,0" Name="button1" VerticalAlignment="Top" Width="75">Button</Button>
</Grid>
</UserControl>
I would appreciate it if someone could point out where I'm going wrong, and set me down the correct path.
Ideally, I want the usercontrol to delay for x seconds when there is a mouseover, before expanding and showing the extra details.
Here is a solution (tested):
Keep in mind that you have to set a Width manually on the UserControl for this to work.
Then add this to your UserControl's body:
<UserControl.Style>
<Style>
<Style.Triggers>
<EventTrigger RoutedEvent="Mouse.MouseEnter">
<EventTrigger.Actions>
<BeginStoryboard>
<Storyboard BeginTime="0:0:4.0" Storyboard.TargetProperty="Width">
<DoubleAnimation To="200" Duration="0:0:1.0"/>
</Storyboard>
</BeginStoryboard>
</EventTrigger.Actions>
</EventTrigger>
</Style.Triggers>
</Style>
</UserControl.Style>
It will start after 4 seconds, then animate the width from its current value to 200, over 1 second.
I've managed to get a bit further with what I want:
<UserControl x:Class="WPFTestBed.UserControl1"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Height="200" Width="170">
<UserControl.Resources>
<Storyboard x:Key="ExpandDisplay">
<DoubleAnimation Storyboard.TargetProperty="(UserControl.Width)"
From="200" To="380" Duration="0:0:0.25" AutoReverse="False"/>
<DoubleAnimation Storyboard.TargetProperty="(Border.Width)"
Storyboard.TargetName="mainBorder"
From="190" To="370" Duration="0:0:0.25" AutoReverse="False"/>
<ObjectAnimationUsingKeyFrames Storyboard.TargetName="button2"
Storyboard.TargetProperty="Visibility">
<DiscreteObjectKeyFrame Value="{x:Static Visibility.Visible}"/>
</ObjectAnimationUsingKeyFrames>
</Storyboard>
<Storyboard x:Key="CollapseDisplay">
<ObjectAnimationUsingKeyFrames Storyboard.TargetName="button2"
Storyboard.TargetProperty="Visibility">
<DiscreteObjectKeyFrame Value="{x:Static Visibility.Collapsed}"/>
</ObjectAnimationUsingKeyFrames>
<DoubleAnimation Storyboard.TargetProperty="(UserControl.Width)"
From="380" To="200" Duration="0:0:0.25" AutoReverse="False"/>
<DoubleAnimation Storyboard.TargetProperty="(Border.Width)"
Storyboard.TargetName="mainBorder"
From="370" To="190" Duration="0:0:0.25" AutoReverse="False"/>
</Storyboard>
</UserControl.Resources>
<UserControl.Triggers>
<EventTrigger RoutedEvent="Mouse.MouseDown">
<BeginStoryboard Storyboard="{StaticResource ExpandDisplay}"/>
</EventTrigger>
<EventTrigger RoutedEvent="Button.Click" SourceName="button2">
<BeginStoryboard Storyboard="{StaticResource CollapseDisplay}"/>
</EventTrigger>
</UserControl.Triggers>
<Border Name="mainBorder" Height="190" Width="160" Background="Black" CornerRadius="20,20,20,20">
<Border.BitmapEffect>
<DropShadowBitmapEffect Color="Black" Direction="320" ShadowDepth="10" Opacity=".5"
Softness="9"/>
</Border.BitmapEffect>
<Grid>
<Grid.RowDefinitions>
<RowDefinition/>
<RowDefinition/>
</Grid.RowDefinitions>
<Button Grid.Row="0" Height="23" Width="75" VerticalAlignment="Center" HorizontalAlignment="Center" Name="button1" >Details</Button>
<Button Grid.Row="1" Height="23" Width="23" VerticalAlignment="Center" HorizontalAlignment="Center" Name="button2" Visibility="Collapsed">-</Button>
</Grid>
</Border>
</UserControl>
This expands the usercontrol when I click, rather than mouseover, as I couldn't find a satisfactory way to wait for a second before beginning. I could delay the start and cancel on a mouseleave but this also cancelled the expand whenever the mouseleave was called.
I have a button to collapse the usercontrol, but I would prefer to switch which storyboard the usercontrol onclick event calls, can this be done?

WPF swing out an element

Say we have a standard WPF-application, and I want to show some UI-elements on the left side besides my main application window.
Is there a way to go "beyond the borders" of the window and show a visual element with buttons on the left besides my main window? If there is, can you point me to a tutorial / video / hint how to accomplish it?
Not sure if you're aiming to do all of this in code or in XAML, but using a Popup, you could do something like this?
<Window
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
x:Class="ButtonsOnPopup.MainWindow"
x:Name="Window"
Title="MainWindow"
Width="400" Height="300">
<Window.Resources>
<Storyboard x:Key="OnMouseLeftButtonDown1">
<BooleanAnimationUsingKeyFrames BeginTime="0" Storyboard.TargetName="popup" Storyboard.TargetProperty="(Popup.IsOpen)">
<DiscreteBooleanKeyFrame KeyTime="0" Value="True"/>
</BooleanAnimationUsingKeyFrames>
</Storyboard>
<Storyboard x:Key="OnClick1">
<BooleanAnimationUsingKeyFrames BeginTime="0" Storyboard.TargetName="popup" Storyboard.TargetProperty="(Popup.IsOpen)">
<DiscreteBooleanKeyFrame KeyTime="0" Value="True"/>
<DiscreteBooleanKeyFrame KeyTime="00:00:00.2" Value="False"/>
</BooleanAnimationUsingKeyFrames>
</Storyboard>
</Window.Resources>
<Window.Triggers>
<EventTrigger RoutedEvent="UIElement.MouseLeftButtonDown" SourceName="textBlock">
<BeginStoryboard Storyboard="{StaticResource OnMouseLeftButtonDown1}"/>
</EventTrigger>
<EventTrigger RoutedEvent="ButtonBase.Click" SourceName="button">
<BeginStoryboard x:Name="OnClick1_BeginStoryboard" Storyboard="{StaticResource OnClick1}"/>
</EventTrigger>
</Window.Triggers>
<Grid x:Name="LayoutRoot">
<Popup x:Name="popup" Placement="Left">
<StackPanel Background="White">
<TextBlock Text="Outside Window" TextWrapping="Wrap"/>
<Button x:Name="button" Width="75" Content="Close this"/>
</StackPanel>
</Popup>
<TextBlock x:Name="textBlock" HorizontalAlignment="Center" VerticalAlignment="Center" Text="MouseDown here" TextWrapping="Wrap" Background="#FFBFFFBD"/>
</Grid>
Hope this helps.
Popup maybe.
simple example:
<Window x:Class="WpfPopupTest.Window1"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Title="Window1" Height="300" Width="300">
<Grid>
<Popup HorizontalOffset="{Binding Path=ActualWidth, RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type Window}}}" IsOpen="True">
<StackPanel Background="HotPink">
<TextBlock Text="Hey from outside!" Foreground="Gold" />
<Button>Button!</Button>
</StackPanel>
</Popup>
</Grid>
Probably don't what you want to do, but i think that it could work for you.
You could use a non-modal dialog with no window border. It could then appear to be floating out in space if you want.
Cory

Style a WPF Button on right mouse click

Is it possible to add a style trigger in WPF to a Button to determine whether or not the ContextMenu has opened?
If so, I'd like to color the background of the corresponding button if the contextmenu is opened.
Can't find a regular way to do it...
Here's a solution:
<Grid ShowGridLines="True">
<Grid.RowDefinitions>
<RowDefinition Height="Auto" />
</Grid.RowDefinitions>
<Button Grid.Column="1" Margin="5" Content="Button" x:Name="theButton">
<Button.Background>
<SolidColorBrush x:Name="BackgroundBrush" Color="LightGray" />
</Button.Background>
<Button.ContextMenu>
<ContextMenu x:Name="contextMenu">
<MenuItem Header="Option 1" />
<MenuItem Header="Option 2" />
</ContextMenu>
</Button.ContextMenu>
<Button.Triggers>
<!-- This changed the color to red when the context menu is openning -->
<EventTrigger RoutedEvent="Button.ContextMenuOpening">
<BeginStoryboard>
<Storyboard>
<ColorAnimation Storyboard.TargetName="BackgroundBrush"
Storyboard.TargetProperty="Color" Duration="0:0:0" To="Red" />
</Storyboard>
</BeginStoryboard>
</EventTrigger>
<!-- This changed the color back to light gray when the context menu is closing -->
<EventTrigger RoutedEvent="Button.ContextMenuClosing">
<BeginStoryboard>
<Storyboard>
<ColorAnimation Storyboard.TargetName="BackgroundBrush"
Storyboard.TargetProperty="Color" Duration="0:0:0" To="LightGray" />
</Storyboard>
</BeginStoryboard>
</EventTrigger>
</Button.Triggers>
</Button>
</Grid>

Resources