Creating a search box using WPF - c#

I'm trying to create a search box with the controls TextBox and ListBox.
When I'm on the TextBox starting to type an event handler GotFocus open the ListBox.
I want the ListBox to be closed when the TextBox not on focus. I tried to use the LostFocus event in the TextBox, but it didn't work.
In which event handler should I use? I didn't find a good example implements this mechanism.
Edit:
I have something like that:
<Canvas Name="m_MainCanvas" Grid.ColumnSpan="2" >
<Rectangle MouseDown="Canvas_MouseDown" Fill="White" Height="280" HorizontalAlignment="Left" Margin="256,12,0,0" x:Name="m_MainRectangle" RadiusX="0" RadiusY="0" Stroke="Black" StrokeThickness="3" VerticalAlignment="Top" Width="238" />
<TextBox Height="23" Margin="10,0,0,210" Name="m_SearchTextBox" VerticalAlignment="Bottom" BorderThickness="0.5" BorderBrush="#69000000" TextChanged="m_SearchTextBox_TextChanged" FontFamily="Kristen ITC" Text="" FontSize="14" FontWeight="Black" HorizontalAlignment="Left" Width="165" Canvas.Top="86" Canvas.Left="274" LostFocus="m_SearchTextBox_LostFocus"/>
<ListBox ItemTemplate="{DynamicResource ListBoxItemDataTemplate}" ItemsSource="{Binding}" Name="m_FriendsSearchList" Visibility="Hidden" Background="#FFBCEB85" Width="181" Height="193" Canvas.Left="283" Canvas.Top="118">
<ListBox.ItemContainerStyle>
<Style TargetType="{x:Type ListBoxItem}">
<EventSetter Event="MouseDoubleClick" Handler="HandleDoubleClickItemToSelect" />
</Style>
</ListBox.ItemContainerStyle>
</ListBox>
The MouseDown event in the Rectangle control is used to get the TextBox out of focus, but it isn't working.

something like:
<StackPanel>
<TextBox>
<TextBox.Triggers>
<EventTrigger RoutedEvent="GotFocus">
<BeginStoryboard>
<Storyboard>
<DoubleAnimation Duration="0:0:0"
Storyboard.TargetName="lb"
Storyboard.TargetProperty="(ListBox.Opacity)"
To="1" />
</Storyboard>
</BeginStoryboard>
</EventTrigger>
<EventTrigger RoutedEvent="LostFocus">
<BeginStoryboard>
<Storyboard>
<DoubleAnimation Duration="0:0:0"
Storyboard.TargetName="lb"
Storyboard.TargetProperty="(ListBox.Opacity)"
To="0" />
</Storyboard>
</BeginStoryboard>
</EventTrigger>
</TextBox.Triggers>
</TextBox>
<ListBox x:Name="lb"
Opacity="0">
<ListBoxItem Content="A" />
<ListBoxItem Content="B" />
</ListBox>
</StackPanel>
However in the above approach the ListBox is still holding the space it resides in. if we instead toggle Visibility to Collapsed, every-time the ListBox becomes Visible other control's are going to start moving to accomodate that.
To avoid both these cases, such things are normally implemented via a Popup
<StackPanel>
<TextBox x:Name="tb" />
<Popup Width="{Binding RelativeSource={RelativeSource Self},
Path=PlacementTarget.ActualWidth}"
Placement="Bottom"
PlacementTarget="{Binding ElementName=tb}">
<Popup.Style>
<Style TargetType="{x:Type Popup}">
<Setter Property="IsOpen"
Value="False" />
<Style.Triggers>
<DataTrigger Binding="{Binding ElementName=tb,
Path=IsFocused}"
Value="True">
<Setter Property="IsOpen"
Value="True" />
</DataTrigger>
</Style.Triggers>
</Style>
</Popup.Style>
<ListBox>
<ListBoxItem Content="A" />
<ListBoxItem Content="B" />
</ListBox>
</Popup>
</StackPanel>
^^ You'll still see the same output however you no longer have any control's that have to change position due to the popup changing open / close states.
Update:
Download Link
Remember the Trigger is set based on the TextBox having / losing focus. IF you click somewhere that does not take focus, then you will not see the Popup(ListBox) disappear.

Related

ContentPresenter loads resource only first occurence [WPF]

I have WPF view, where I use buttons with style that I created by myself. In this style I use some icon from resources, that I pass by TemplateBinding.
Unfortunately I faced strange problem: the resource is shown only at first occurrence of button with this style. In next buttons I have empty box.
Style:
<Style x:Key="TransparentStyle" TargetType="{x:Type Button}">
<Setter Property="BorderBrush" Value="LightSlateGray"/>
<Setter Property="Template">
<Setter.Value>
<ControlTemplate>
<Grid>
<Rectangle Width="13" Height="15" x:Name="IconBrush">
<Rectangle.Fill>
<SolidColorBrush Color="DarkGray"></SolidColorBrush>
</Rectangle.Fill>
<Rectangle.OpacityMask>
<VisualBrush Stretch="Fill">
<VisualBrush.Visual>
<ContentPresenter Content="{TemplateBinding Button.Content}" />
</VisualBrush.Visual>
</VisualBrush>
</Rectangle.OpacityMask>
</Rectangle>
</Grid>
<ControlTemplate.Triggers>
<EventTrigger RoutedEvent="Mouse.MouseEnter">
<BeginStoryboard>
<Storyboard>
<ColorAnimation Duration="0:0:0.1" Storyboard.TargetName="IconBrush"
Storyboard.TargetProperty="Fill.(SolidColorBrush.Color)"
To="Black" />
</Storyboard>
</BeginStoryboard>
</EventTrigger>
<EventTrigger RoutedEvent="Mouse.MouseLeave">
<BeginStoryboard>
<Storyboard>
<ColorAnimation Duration="0:0:0.1" Storyboard.TargetName="IconBrush"
Storyboard.TargetProperty="Fill.(SolidColorBrush.Color)"
To="DarkGray" />
</Storyboard>
</BeginStoryboard>
</EventTrigger>
</ControlTemplate.Triggers>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
Usege:
<WrapPanel Grid.Column="2" Margin="20 0">
<Button Height="35" Width="35" Margin="3 3" Content="{StaticResource trash}" Style ="{StaticResource TransparentStyle}"/>
<Button Height="35" Width="35" Margin="3 3" Content="{StaticResource trash}" Style ="{StaticResource TransparentStyle}" />
</WrapPanel>
What is interesting, when I use another resources, they work at their first occurrences. So if I use another_res instead of trash, it works at first time.
How do I fix it?
EDIT:
Next tests show, that when I use any resource in style and problem repeats:
<VisualBrush.Visual>
<ContentPresenter Content="{DynamicResource some_resource}" />
</VisualBrush.Visual>
EDIT2:
The resource is defined in external source:
<Window.Resources>
<ResourceDictionary>
<ResourceDictionary.MergedDictionaries>
<ResourceDictionary Source="/Resources/Icons.xaml" />
</ResourceDictionary.MergedDictionaries>
</ResourceDictionary>
</Window.Resources>
As canvas:
<Canvas x:Key="trash" Width="24" Height="24">
<Path Data="M19,4H15.5L14.5,3H9.5L8.5,4H5V6H19M6,19A2,2 0 0,0 8,21H16A2,2 0 0,0 18,19V7H6V19Z" Fill="Black" />
</Canvas>
Don't define your Icons like(I hope this is your problem as this is what people usually do, and Image is a FrameworkElement):
<Image Source="Resources/SOF.gif" x:Key="trash"/>
Define them like:
<ImageBrush ImageSource="Resources/SOF.gif" x:Key="trash"/>
and use ImageBrush like(in your style):
<Rectangle Width="113" Height="95" x:Name="IconBrush" Fill="{Binding RelativeSource={RelativeSource Mode=TemplatedParent},Path=Content}"/>
your Icons will be repeated on buttons like below:
Update:
try it like:
<VisualBrush x:Key="trash" >
<VisualBrush.Visual>
<Canvas Width="24" Height="24" >
<Path Data="M19,4H15.5L14.5,3H9.5L8.5,4H5V6H19M6,19A2,2 0 0,0 8,21H16A2,2 0 0,0 18,19V7H6V19Z" Fill="Black" />
</Canvas>
</VisualBrush.Visual>
</VisualBrush>
OutPut:(make sure to use Rectangle fill correctly as I have mentioned above)

Why won't my Template's TextBox bind

I am trying to do some binding. For the most part, my MVVM application is working fine but I now want to use a Template. In this case, I'm using XCeed chart which expose a SeriesTemplate.
My code is:
<UserControl
xmlns:xctk="http://schemas.xceed.com/wpf/xaml/toolkit"
x:Class="MyApp.AppUi.View.Graph.GraphView"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:converter="clr-namespace:MyApp.AppUi.Converters"
>
<Grid>
<Grid.Resources>
<converter:MyIntConverter x:Key="MyIntConverter" />
<DataTemplate x:Key="MyLabelTemplate">
<TextBlock Text="{Binding Path=Text, Converter={StaticResource MyIntConverter}}" />
</DataTemplate>
<!--give it a name, Bind to above, choose property -->
<CollectionViewSource x:Key="GraphDataCollection" Source="{Binding GraphDataList}" />
<Style x:Key="TextBoxTextStyle" TargetType="TextBlock">
<Setter Property="HorizontalAlignment" Value="Center" />
<Setter Property="FontFamily" Value="Comic Sans MS"/>
<Setter Property="FontSize" Value="12"/>
<Style.Triggers>
<EventTrigger RoutedEvent="Mouse.MouseEnter">
<EventTrigger.Actions>
<BeginStoryboard>
<Storyboard>
<DoubleAnimation Storyboard.TargetProperty="FontSize" To="19" Duration="0:0:0.4"/>
</Storyboard>
</BeginStoryboard>
</EventTrigger.Actions>
</EventTrigger>
<EventTrigger RoutedEvent="Mouse.MouseLeave">
<EventTrigger.Actions>
<BeginStoryboard>
<Storyboard>
<DoubleAnimation Storyboard.TargetProperty="FontSize" To="12" Duration="0:0:0.4" />
</Storyboard>
</BeginStoryboard>
</EventTrigger.Actions>
</EventTrigger>
</Style.Triggers>
</Style>
<Style TargetType="Button">
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="Button">
<ContentPresenter/>
</ControlTemplate>
</Setter.Value>
</Setter>
<Setter Property="ContentTemplate">
<Setter.Value>
<DataTemplate>
<Grid Width="{Binding Path=ActualWidth, RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type Button}}}"
Height="{Binding Path=ActualHeight, RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type Button}}}">
<Rectangle RadiusX="5" RadiusY="5" >
<Rectangle.Triggers>
<EventTrigger RoutedEvent="Mouse.MouseEnter">
<EventTrigger.Actions>
<BeginStoryboard>
<Storyboard>
<DoubleAnimation Storyboard.TargetProperty="Opacity" To="0.8" Duration="0:0:0.4"/>
</Storyboard>
</BeginStoryboard>
</EventTrigger.Actions>
</EventTrigger>
<EventTrigger RoutedEvent="Mouse.MouseLeave">
<EventTrigger.Actions>
<BeginStoryboard>
<Storyboard>
<DoubleAnimation Storyboard.TargetProperty="Opacity" To="1" Duration="0:0:0.4" />
</Storyboard>
</BeginStoryboard>
</EventTrigger.Actions>
</EventTrigger>
</Rectangle.Triggers>
<Rectangle.Fill>
<LinearGradientBrush StartPoint="0,0" EndPoint="1,1">
<GradientStop Color="#FFffcf26" Offset="0.0" />
<GradientStop Color="#FFff7f04" Offset="1.0" />
</LinearGradientBrush>
</Rectangle.Fill>
</Rectangle>
<ContentPresenter VerticalAlignment="Center" Content="{Binding Path=Content, RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type Button}}}"/>
</Grid>
</DataTemplate>
</Setter.Value>
</Setter>
</Style>
<DataTemplate x:Key="SeriesTemplate">
<Button>
<StackPanel>
<TextBlock Text="{Binding GraphData.ShortDate}" Style="{StaticResource TextBoxTextStyle}" />
</StackPanel>
</Button>
</DataTemplate>
</Grid.Resources>
<GroupBox Header="{Binding Title}">
<GroupBox.Background>
<LinearGradientBrush EndPoint="0,1" StartPoint="0,0" >
<GradientStop Offset="0" Color="#FF9d9d9d" />
<GradientStop Offset="1" Color="#FF666666" />
</LinearGradientBrush>
</GroupBox.Background>
<xctk:Chart Height="400" Width="400" ShowLegend="False">
<xctk:Chart.Areas>
<xctk:Area >
<xctk:Area.XAxis>
<xctk:Axis Title="Date"
GraduationMode="Manual"
LabelsType="DateTime"
ScaleMode="Automatic"
TitleMargin="10"
AxisLabelsLayout="ShowAll"
ShowArrow="False"
ShowAxis="True"
ShowGridLines="True"
ShowTicks="True"
ShowTickLabels="True"
ShowAxisLabel="True"
Reversed="False"
/>
</xctk:Area.XAxis>
<xctk:Area.YAxis>
<xctk:Axis Title="Google position"
ScaleMode="Manual"
TitleMargin="10"
AxisLabelsLayout="ShowAll"
ShowArrow="False"
ShowAxis="True"
ShowGridLines="True"
CustomRangeStart="1.00"
CustomRangeEnd="111.00"
ShowTicks="True"
ShowTickLabels="True"
ShowAxisLabel="True"
Reversed="False"
LabelTemplate="{StaticResource MyLabelTemplate}"
/>
</xctk:Area.YAxis>
<xctk:Area.Series>
<xctk:Series DataPointsSource="{Binding Source={StaticResource GraphDataCollection}}"
Template="{StaticResource SeriesTemplate}"
ShowPointsInLegend="true">
<xctk:Series.DataPointBindings>
<xctk:BindingInfo PropertyName="Y">
<xctk:BindingInfo.Binding>
<Binding Path="Position"/>
</xctk:BindingInfo.Binding>
</xctk:BindingInfo>
<xctk:BindingInfo PropertyName="X">
<xctk:BindingInfo.Binding>
<Binding Path="Date"/>
</xctk:BindingInfo.Binding>
</xctk:BindingInfo>
<xctk:BindingInfo PropertyName="Label">
<xctk:BindingInfo.Binding>
<Binding Path="ShortDate"/>
</xctk:BindingInfo.Binding>
</xctk:BindingInfo>
</xctk:Series.DataPointBindings>
</xctk:Series>
</xctk:Area.Series>
</xctk:Area>
</xctk:Chart.Areas>
</xctk:Chart>
</GroupBox>
</Grid>
and my ViewModel
public class GraphViewModel : BaseViewModel
{
public GraphViewModel(List<GraphData> data, string title )
{
this.GraphDataList = data;
this.Title = title;
}
public string Title { get; private set; }
public List<GraphData> GraphDataList { get; private set; }
}
And the DataContext is set in the Resource Dictionary
<ResourceDictionary xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:graphView="clr-namespace:MyApp.AppUi.View.Graph"
xmlns:graphViewModel="clr-namespace:MyApp.AppUi.ViewModel.Graph"
xmlns:converter="clr-namespace:MyApp.AppUi.Converters"
>
<DataTemplate DataType="{x:Type graphViewModel:GraphViewModel}">
<graphView:GraphView />
</DataTemplate>
The chart displays as desired but, the SeriesTemplate does not bind. There is an error message in the ouput window, which I understand what the message is saying, but not how to fix it.
The error message is
System.Windows.Data Error: 40 : BindingExpression path error: 'ShortDate' property not found on 'object' ''ColumnPrimitiveInfo' (HashCode=39288004)'. BindingExpression:Path=ShortDate; DataItem='ColumnPrimitiveInfo' (HashCode=39288004); target element is 'TextBlock' (Name=''); target property is 'Text' (type 'String')
How do I get the binding to work for
<DataTemplate x:Key="SeriesTemplate">
<Button x:Name="Bar">
<StackPanel>
<TextBlock Text="{Binding GraphData.ShortDate}" Style="{StaticResource TextBoxTextStyle}" /> <!--THIS IS WHERE THE FAULT IS -->
</StackPanel>
</Button>
</DataTemplate>
XCeed have a working demo with source code, if you download the application, click on Charts -> Styling -> Column Series you can see that my code is very very similar. There's works, but mine does not and I can't see why. Please note, the graph itself displays, it's just the textbox is not showing. However, if I don't use binding, and just use Text="SomeWords" then it works fine
After a few hours of voodoo programming (where I just try different things at random) I found the solution.
<TextBlock Text="{Binding Path=Content.ShortDate}" Style="{StaticResource TextBoxTextStyle}" />
I think this is because of (see the Button Setter in code of OP)
<ContentPresenter VerticalAlignment="Center" Content="{Binding Path=Content, RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type Button}}}"/>
Try this:
<DataTemplate x:Key="SeriesTemplate">
<Button>
<StackPanel>
<TextBlock Text="{Binding Path=ShortDate}" Style="{StaticResource TextBoxTextStyle}" />
</StackPanel>
</Button>
</DataTemplate>
From looking at the documentation hereon the XCeed documentation site it appears that you are adding an extra layer of indirection to the binding. Try binding directly to the GraphDataList
<xctk:Series DataPointsSource="{Binding Source={StaticResource GraphDataList}}"
Template="{StaticResource SeriesTemplate}"
ShowPointsInLegend="true">
and then in the series
<DataTemplate x:Key="SeriesTemplate">
<Button>
<StackPanel>
<TextBlock Text="{Binding Path=ShortDate}" Style="{StaticResource TextBoxTextStyle}" />
</StackPanel>
</Button>
</DataTemplate>

WPF Expander to expand on far right side of application

I would like to alter my program so that when an image is clicked it reveals a sidebar on the far right side of the application.
I have currently been trying to achieve this using an Expander. This is what it looks like so far:
<Expander>
<Expander.Header>
<Image Width="200" Height="300" Source="{Binding image}"/>
</Expander.Header>
<i:Interaction.Behaviors>
<local:UniqueNameBehavior ID="{Binding id}"/>
</i:Interaction.Behaviors>
<StackPanel Margin="10,4,0,0">
<ToggleButton Margin="4" Content="Option 1" Template="{StaticResource SimpleExpanderButtonTemp}"/>
<ListView>
<TextBox Text="Search" />
</ListView>
</StackPanel>
</Expander>
The idea is that whenever any movie is clicked, a sidebar on the far right side of the app is revealed containing info about the movie. If another movie is subsequently clicked, the sidebar will now contain info about the new movie.
I know that it is possible to change the ExpandDirection, but this only results in the content appearing beside the image as opposed to the far right of the application.
I've also tried adjusting the Margin of StackPanel but this results in the surrounding movies being pushed aside.
Could someone please help me out with how I can achieve this?
Thank you for your help!
I don't believe this kind of behaviour can be achieved using expanders the way you are using.
Why don't you create a grid on the far right side of your app with its width set to 0 and when you click/select a movie it sets the grid width to a new value and change its content based on the movie?
<Grid HorizontalAlignment="Right">
<Grid.Style>
<Style TargetType="Grid">
<Setter Property="Width" Value="0"/>
<Style.Triggers>
<DataTrigger Binding="{Binding ShowMovieForm}" Value="True">
<DataTrigger.EnterActions>
<BeginStoryboard>
<Storyboard>
<DoubleAnimation Duration="0:0:0.1" Storyboard.TargetProperty="Width" To="400" />
</Storyboard>
</BeginStoryboard>
</DataTrigger.EnterActions>
<DataTrigger.ExitActions>
<BeginStoryboard>
<Storyboard>
<DoubleAnimation Duration="0:0:0.1" Storyboard.TargetProperty="Width" To="0" />
</Storyboard>
</BeginStoryboard>
</DataTrigger.ExitActions>
</DataTrigger>
</Style.Triggers>
</Style>
</Grid.Style>
</Grid>

Trying to get the StoryBoard object that is inside a ControlTemplate

What I am trying to achieve is to close the window when the Storyboard completes it's job, I tried to set the x:Key attribute in the Storyboard object but I get the following error:
"key attribute can be used only on a tag contained in an IDictionary (such as a ResourceDictionary)"
Here's my code:
<Window.Resources>
<ControlTemplate x:Key="MyErrorMessage"
TargetType="{x:Type Label}">
<StackPanel Orientation="Horizontal"
Name="ErrorMessage">
<Border CornerRadius="4" Width="Auto"
BorderThickness="0"
VerticalAlignment="Center"
Margin="4,0"
Background="#FF404040"
BorderBrush="Transparent">
<Label Foreground="White"
VerticalAlignment="Center"
Padding="4,2"
Margin="4"
FontWeight="Bold" FontSize="15"
Name="Part1"
Visibility="Visible" HorizontalAlignment="Center" Content="{Binding Message}" />
</Border>
<!-- This TextBlock accepts the content from the parent 'label'. It is not actually displayed, just used to bind data-->
<TextBlock Name="Part3"
Text="{TemplateBinding Content}"
Visibility="Collapsed"></TextBlock>
<!-- This TextBlock binds to the one above and triggers an animation when it gets updated. -->
<!-- Its required because TemplateBinding does not allow NotifyOnTargetUpdate -->
<TextBlock Margin="2"
Name="Part2"
Foreground="Red"
Padding="3"
Visibility="Collapsed"
Text="{Binding ElementName=Part3, Path=Text,NotifyOnTargetUpdated=True}"
VerticalAlignment="Center"></TextBlock>
</StackPanel>
<ControlTemplate.Triggers>
<!-- When Text property of Part2 is blank hide entire control-->
<Trigger SourceName="Part3"
Property="Text"
Value="">
<Setter TargetName="ErrorMessage"
Property="Visibility"
Value="Hidden"></Setter>
</Trigger>
<!-- This trigger is called when Part2 updates which in turn is updated by Part3's databind.
It uses animation to make the label fade away after a few seconds. -->
<EventTrigger SourceName="Part2"
RoutedEvent="Binding.TargetUpdated">
<BeginStoryboard>
<Storyboard TargetName="ErrorMessage" x:Key="gridFadeStoryBoard">
<DoubleAnimation Storyboard.TargetProperty="Opacity" Name="FadeOutAnimation"
Duration="0:0:1.50"
From="1.0"
To="0.0"
BeginTime="0:0:0.50" />
</Storyboard>
</BeginStoryboard>
</EventTrigger>
</ControlTemplate.Triggers>
</ControlTemplate>
</Window.Resources>
<StackPanel Orientation="Vertical">
<Label Template="{StaticResource MyErrorMessage}" Name="Label1" />
</StackPanel>
code-behind:
private Storyboard gridFadeStoryBoard;
public ToastPopup(string Message)
{
InitializeComponent();
Label1.Content = DateTime.Now.ToString();
gridFadeStoryBoard = this.Label1.Template.Resources["gridFadeStoryBoard"] as Storyboard;
gridFadeStoryBoard.Completed += new EventHandler(gridFadeStoryBoard_Completed);
}
void gridFadeStoryBoard_Completed(object sender, EventArgs e)
{
this.Close();
}

Storyboard Completed Event from Style?

I'm new to Storyboard animations but I think this might be a problem I can't workaround the easy way. Nevertheless I try my luck here, maybe some of you guys know how to help me.
My Scenario : I want to show a popup in my Application that has a fadein effect. I also want to do this via MVVM so my control that wraps the fadein effect and the popup should no use codebehind and my application should just need to reset the datacontext of this control to a new viewmodel to show a new message.
My Problem is that I cannot determine when the animation is finished because I need to set the fadein Animation in the style.
My XAML looks like this :
<UserControl.Resources>
<Style x:Key="popupStyle" TargetType="{x:Type Border}" >
<Style.Triggers>
<Trigger Property="Visibility" Value="Visible">
<Trigger.EnterActions>
<BeginStoryboard>
<Storyboard x:Name="FadingStoryBoard">
<DoubleAnimation Storyboard.TargetProperty="Opacity" From="0.05" To="1" BeginTime="0:0:1" Duration="0:0:2.5" >
<DoubleAnimation.EasingFunction>
<ExponentialEase Exponent="5" EasingMode="EaseIn" />
</DoubleAnimation.EasingFunction>
</DoubleAnimation>
<DoubleAnimation Storyboard.TargetProperty="Opacity" From="1" To="0" BeginTime="0:0:6" Duration="0:0:8.5" >
<DoubleAnimation.EasingFunction>
<ExponentialEase Exponent="15" EasingMode="EaseOut" />
</DoubleAnimation.EasingFunction>
</DoubleAnimation>
</Storyboard>
</BeginStoryboard>
</Trigger.EnterActions>
</Trigger>
</Style.Triggers>
</Style>
</UserControl.Resources>
<Popup Name="Popup" IsOpen="{Binding IsVisible}" Height="{Binding PopupHeight}" Width="{Binding PopupWidth}" VerticalOffset="{Binding PopupVerticalOffset}" HorizontalOffset="{Binding PopupHorizontalOffset}" PopupAnimation="Fade" AllowsTransparency="True">
<Border Style="{StaticResource popupStyle}" Name="PopupContent" Padding="1" BorderBrush="#000000" Background="AliceBlue" CornerRadius="5" BorderThickness="3,3,3,3">
<!-- Events -->
<interact:Interaction.Triggers>
<interact:EventTrigger EventName="PreviewMouseDown">
<cmd:EventToCommand Command="{Binding Path=PopupMouseDownCommand}" PassEventArgsToCommand="True" />
</interact:EventTrigger>
</interact:Interaction.Triggers>
<DockPanel Name="ContentContainer" Background="Black" LastChildFill="True">
<Image Source="{Binding MessageIcon}" DockPanel.Dock="Left" Margin="5,0,5,0" Width="32" Height="32" />
<StackPanel Background="Transparent" DockPanel.Dock="Right" Margin="3">
<TextBlock Name="PopupHeaderTextBlock" Margin="0,3,0,5" TextWrapping="Wrap" FontSize="10" Text="{Binding PopupHeaderText}" Foreground="White" Background="Transparent" />
<TextBlock Name="PopupTextBlock" Text="{Binding PopupText}" TextWrapping="Wrap" FontSize="10" Foreground="White" Background="Transparent" />
</StackPanel>
</DockPanel>
</Border>
</Popup>
Anyone any ideas how I can get a notification in my ViewModel when the Storyboard has finished ?
You can handle the Completed event on the storyboard.
Documentation Here: http://msdn.microsoft.com/en-us/library/system.windows.media.animation.timeline.completed.aspx
Here's the code to attach the event from the codebehind:
call from the constructor:
private void AttachToCompletedEvent()
{
Style popupStyle = Resources["popupStyle"];
TriggerBase trigger = popupStyle.Triggers[0];
BeginStoryboard action = trigger.EnterActions[0] as BeginStoryboard;
Storyboard storyboard = action.Storyboard;
storyboard.Completed += CompletedEventHandler;
}
I think that should work for the code you provided.

Categories

Resources