WPF - Animation to make an error message disappear - wpf

I have the following xaml in my window:
<Border Height="100" BorderBrush="Black" BorderThickness="2" CornerRadius="10" Background="PaleVioletRed" HorizontalAlignment="Center" VerticalAlignment="Center">
<TextBlock Margin="10" HorizontalAlignment="Center" VerticalAlignment="Center" FontSize="17" FontWeight="Bold">Error Message Here</TextBlock>
</Border>
Which basically displays this:
alt text http://xs.to/thumb-4CB2_4B69F8E6.jpg
I plan to bind it's Visibility to an error state variable so it shows when an error occurs.
But I don't want to show it for a long time. I would like it to disappear/fade after 2 seconds. Is there a way to do this via XAML? Or a nice WPF way?
Something like this psudo code logic:
when (ErrorMessage.Visibility == Visible )
{
Wait(2000); // Wait 2 seconds
ErrorMessage.Visibility == Collapsed;
}
but preferable done with XAML.
My instincts tell me there is a way to do this with an animation, but I am not an animation expert and could use some help.
The other option is to try and setup a timer and control it with that.

use something like this....
<EventTrigger RoutedEvent="Page.Loaded">
<BeginStoryboard>
<Storyboard BeginTime="0:0:1">
<ObjectAnimationUsingKeyFrames Storyboard.TargetName="image1" Storyboard.TargetProperty="Visibility">
<DiscreteObjectKeyFrame Value="{x:Static Visibility.Visible}" />
</ObjectAnimationUsingKeyFrames>
</Storyboard>
</BeginStoryboard>
</EventTrigger>
change the routed event to match your needs, set the BeginTime on the storyboard to 2 mins ( or whatever ), set the targetname to your border element.

Related

Prevent automatic resize of window when content changes

I have made a picture viewer which is a Window with SizeToContent="Width". This looks just the way I want it when I open it with the first picture in a series.
When I go the next picture in the series, which happens to be wider than the previous one, the Window is resized to fit this new picture. The left edge of the Window stays in the same place, but the right edge of the Window is now outside the edge of the screen.
How can I prevent an automatic resize like this?
I do not want to use ResizeMode="NoResize" because I want the user to be able to manually change the size of the Window should he or she want to.
XAML
<Window SizeToContent="Width" WindowStartupLocation="CenterOwner">
<Grid>
<DockPanel>
<Button DockPanel.Dock="Left"
Content="Previous" />
<Button DockPanel.Dock="Right"
Content="Next" />
<Image Source="{Binding CurrentImage}"
Stretch="Uniform"
StretchDirection="DownOnly"
RenderOptions.BitmapScalingMode="Fant" />
</DockPanel>
</Grid>
</Window>
Reset the SizeToContent property in a Loaded event handler:
public MainWindow()
{
InitializeComponent();
Loaded += (o, e) => SizeToContent = SizeToContent.Manual;
}
Or if you don't like code behind:
<Window.Triggers>
<EventTrigger RoutedEvent="Loaded">
<BeginStoryboard>
<Storyboard>
<ObjectAnimationUsingKeyFrames Storyboard.TargetProperty="SizeToContent">
<DiscreteObjectKeyFrame KeyTime="0"
Value="{x:Static SizeToContent.Manual}"/>
</ObjectAnimationUsingKeyFrames>
</Storyboard>
</BeginStoryboard>
</EventTrigger>
</Window.Triggers>

Change Visual State On PropertyChanged

Is it possible to add a behaviour in Blend to switch to a different visual state in response to a property changed event on a binding? It would need to switch to this state for a few seconds and then back out.
I'm trying to change the background colour of a control everytime a count value on the datacoontext changes. I've tried using a GoToStateAction and EventTrigger/DataTrigger but can't quite get the trigger setup right - I suspect that I need to approach this in a different way but I'm not sure how.
Any help would be appreciated -
Here is the xaml for the border - I'm stuck on how to set up the trigger to change the visual state - I want to switch to BrightState for a few seconds and back to NormalState everytime the Value of Count on the viewmodel changes
<Border x:Name="border" Grid.Row="2" Background="CadetBlue">
<StackPanel Orientation="Horizontal" VerticalAlignment="Center" HorizontalAlignment="Center">
<TextBlock><Run Text="Count:"/></TextBlock>
<TextBlock x:Name="textBlock" Text="{Binding Count}" MinWidth="30">
<i:Interaction.Triggers>
<!--<i:EventTrigger EventName="MouseLeftButtonDown" SourceName="textBlock">
<ei:GoToStateAction/>
</i:EventTrigger>-->
</i:Interaction.Triggers>
</TextBlock>
</StackPanel>
</Border>
Here are the visual states defined to change the background colour of the border:
<VisualStateManager.VisualStateGroups>
<VisualStateGroup x:Name="FlickerStateGroup">
<VisualState x:Name="NormalState"/>
<VisualState x:Name="BrightState">
<Storyboard>
<ColorAnimationUsingKeyFrames Storyboard.TargetProperty="(Panel.Background).(SolidColorBrush.Color)" Storyboard.TargetName="border">
<EasingColorKeyFrame KeyTime="0" Value="#FF6CD9DC"/>
</ColorAnimationUsingKeyFrames>
</Storyboard>
</VisualState>
</VisualStateGroup>
</VisualStateManager.VisualStateGroups>

WPF: Show and persist ToolTip for a Textbox based on the cursor

The purpose of this tooltip is to show, the format of the string which must be entered.
The features I would like to achieve are:
The tooltip should be shown when the user places the cursor in the textbox, i.e. when the user tabs into the control.
The tooltip should update based on user input into the textbox (this can be achieved by binding).
The tooltip must persist until the user tabs out of the control.
I wanted to know if the standard tooltip as provided has configuration settings, properties, that can be used to achieve this,... in my research thus far I haven't found any. If the existing tooltip is not up to the task, which is very likely, I'd like some pointers, sample code to achieve this...
Thanks
Hasanain
Using a combination of event triggers, bindings, and minimal code-behind I managed to implement a behavior which would update the ToolTip while the user types into textbox; when the keyboard focus is lost the tooltip disappears.
Here is the xaml for the textbox:
<TextBox Grid.Column="0" x:Name="txtBxQckTkt" Margin="5,5,0,0" Width="250" ToolTipService.IsEnabled="True"
Text="{Binding QuickTicketText}">
<TextBox.Triggers>
<EventTrigger RoutedEvent="TextBox.GotKeyboardFocus">
<BeginStoryboard>
<Storyboard>
<BooleanAnimationUsingKeyFrames
Storyboard.TargetName="txtBxQckTktToolTip"
Storyboard.TargetProperty="IsOpen">
<DiscreteBooleanKeyFrame KeyTime="0:0:0" Value="False"/>
<DiscreteBooleanKeyFrame KeyTime="0:0:0.0001" Value="True" />
</BooleanAnimationUsingKeyFrames>
<ObjectAnimationUsingKeyFrames Storyboard.TargetName="txtBxQckTktToolTip"
Storyboard.TargetProperty="Placement">
<DiscreteObjectKeyFrame Value="{x:Static PlacementMode.Bottom}"/>
</ObjectAnimationUsingKeyFrames>
</Storyboard>
</BeginStoryboard>
</EventTrigger>
<EventTrigger RoutedEvent="TextBox.LostKeyboardFocus">
<BeginStoryboard>
<Storyboard>
<BooleanAnimationUsingKeyFrames
Storyboard.TargetName="txtBxQckTktToolTip"
Storyboard.TargetProperty="IsOpen">
<DiscreteBooleanKeyFrame KeyTime="0:0:0" Value="True"/>
<DiscreteBooleanKeyFrame KeyTime="0:0:0.0001" Value="False" />
</BooleanAnimationUsingKeyFrames>
</Storyboard>
</BeginStoryboard>
</EventTrigger>
</TextBox.Triggers>
<TextBox.ToolTip>
<ToolTip x:Name="txtBxQckTktToolTip" Placement="Bottom" Content="{Binding ToolTip}">
</ToolTip>
</TextBox.ToolTip>
</TextBox>
Here is the code-behind:
txtBxQckTktToolTip.PlacementTarget = txtBxQckTkt;
_handler = (s, e) =>
{
var viewModel = DataContext as SingleTradeEntryViewModel;
if (viewModel == null) return;
viewModel.OnKeyup.Execute(txtBxQckTkt.Text);
};
txtBxQckTkt.KeyUp -= _handler;
txtBxQckTkt.KeyUp += _handler;
When the command (OnKeyup) executes, it raises a change notification for the ToolTip property bound as seen in the xaml.
Thanks
Hasanain
You might have to implement your own using the Popup Control. Here is some sample XAML to get you started:
<Button Width="120" Height="30" Name="btn">
<Popup IsOpen="True" StaysOpen="True" PlacementTarget="{Binding ElementName=btn}" Placement="Bottom">
<Button Width="120" Height="30" Content="Button In ToolTip"/>
</Popup>
</Button>
And here is some example code to get you started:
http://social.msdn.microsoft.com/forums/en-US/wpf/thread/845ffad0-4abf-4830-b206-03f7fe53f74b
2. ToolTip="{Binding Text, ElementName=textBox1, UpdateSourceTrigger=PropertyChanged}"
Here textBox1 is your textbox name and I have changed UpdateSourceTrigger to PropertyChanged so it updates your tooltip as you type.
3. ToolTipService.ShowDuration="12000"
Give this property a random time which is long enough to suit your needs.
I don't fully understand your first point but I think you need the tooltip to show in your gotfocus eventhandler. This can be achieved by something like in the gotfocus event.
ToolTip toolTip = ToolTipService.GetToolTip(textBox1) as ToolTip;
toolTip.IsOpen = true;
You could create a trigger that sets the ToolTip based on if the control has focus or not

Button click changes visibility of a DataGrid with a Trigger in WPF

Hi i am trying to find some way to when a button is clicked changes the visibility of other control, like a DataGrid with a Trigger in XAML.
The button only changes the visibility of the DataGrid to Visible, it does other things in Code Behind, but this is something that i think that can be done in a Style with a Trigger.
I tried to find a solution and it seems to be possible to do but i can't understand how.
Thanks in advance.
<Button Content="Button!">
<Button.Triggers>
<EventTrigger RoutedEvent="Button.Click">
<BeginStoryboard>
<Storyboard>
<ObjectAnimationUsingKeyFrames Storyboard.Target="{x:Reference dataGrid}"
Storyboard.TargetProperty="Visibility">
<DiscreteObjectKeyFrame KeyTime="0:0:0"
Value="{x:Static Visibility.Visible}"/>
</ObjectAnimationUsingKeyFrames>
</Storyboard>
</BeginStoryboard>
</EventTrigger>
</Button.Triggers>
</Button>
{x:Reference dataGrid} references a DataGrid with the name dataGrid, alternatively you could just use Storyboard.TargetName. You would normally use the Storyboard.Target property if you do binding or references to resources.
Just a suggestion, but how about, for something more understandable, having a Checkbox enabling/disabling the DataGrid display? This is what I usually do:
<DockPanel LastChildFill="True">
<CheckBox DockPanel.Dock="Right" VerticalAlignment="Center" x:Name="DisplayBox"
Content="Display grid" Margin="4" IsChecked="False"/>
<DataGrid Visibility="{Binding ElementName=DisplayBox, Path=IsChecked, Converter={StaticResource BoolToVisibilityConverter}}" />
</DockPanel>
And of course, you'll have to implement the appropriate converter

WPF ToolTip disappears on mouse down

I've got tooltip on an element that I want to stay open even when the user clicks or holds the mouse button down while over my element.
Is there anyway to do this?
There is a StaysOpen tooltip property, but according to this book you are better off using a Popup control (just make it look like a tool tip).
Here is a quote from the book:
Has no effect in practice. The
intended purpose of this property is
to allow you to create a tooltip that
remains open until the user clicks
somewhere else. However, the
ToolTipService.ShowDuration property
overrides the StaysOpen property. As a
result, tooltips always disappear
after a configurable amount of time
(usually about 5 seconds) or when the
user moves the mouse away. If you want
to create a tooltip-like window that
stays open indefinitely, the easiest
approach is to use the Popup control.
The simplest way is to use Popup. Look to the code sample.
<!--Your ToolTip-->
<Popup x:Name="InfoPopup" PlacementTarget="{Binding ElementName=yourElement}" AllowsTransparency="True" StaysOpen="False" Placement="Mouse" PopupAnimation="Fade">
<Border BorderBrush="White" BorderThickness="1" Background="#FFFFFFFF" >
<Label Content="Your text here" />
</Border>
</Popup>
<!--Your element. Border, Button etc..-->
<Border x:Name="yourElement" Background="#FFFFFF" MinWidth="20" Height="20">
<Border.Triggers>
<EventTrigger RoutedEvent="Mouse.MouseDown">
<BeginStoryboard>
<Storyboard>
<BooleanAnimationUsingKeyFrames Duration="0:0:0:0" Storyboard.TargetProperty="IsOpen" Storyboard.TargetName="InfoPopup">
<DiscreteBooleanKeyFrame Value="True"></DiscreteBooleanKeyFrame>
</BooleanAnimationUsingKeyFrames>
</Storyboard>
</BeginStoryboard>
</EventTrigger>
<EventTrigger RoutedEvent="Mouse.MouseUp">
<BeginStoryboard>
<Storyboard>
<BooleanAnimationUsingKeyFrames Duration="0:0:0:0" Storyboard.TargetProperty="IsOpen" Storyboard.TargetName="InfoPopup">
<DiscreteBooleanKeyFrame Value="False"></DiscreteBooleanKeyFrame>
</BooleanAnimationUsingKeyFrames>
</Storyboard>
</BeginStoryboard>
</EventTrigger>
</Border.Triggers>
</Border>

Resources