WPF Popup follow mouse in DataTemplate - c#

I'm fighting with making popup follow mouse within DataTemplate
I have following DataTemplate:
<DataTemplate>
<StackPanel x:Name="MyPanel">
<Popup x:Name="MyPopup" Visibility="Visible" AllowsTransparency="True" Placement="MousePoint">
something here
</Popup>
<controls1:ImageLoader x:Name="MyImage" Margin="10,10,0,0" Source="{Binding ImageUri}" Width="100" Height="100">
</controls1:ImageLoader>
</StackPanel>
<DataTemplate.Triggers>
<EventTrigger RoutedEvent="MyImage.MouseEnter" >
<BeginStoryboard>
<Storyboard>
<BooleanAnimationUsingKeyFrames
Storyboard.TargetName="MyPopup"
Storyboard.TargetProperty="IsOpen"
Duration="0:0:0.5">
<DiscreteBooleanKeyFrame Value="True" KeyTime="100%"/>
</BooleanAnimationUsingKeyFrames>
</Storyboard>
</BeginStoryboard>
</EventTrigger>
<EventTrigger RoutedEvent="MyPanel.MouseLeave" >
<BeginStoryboard>
<Storyboard>
<BooleanAnimationUsingKeyFrames
Storyboard.TargetName="MyPopup"
Storyboard.TargetProperty="IsOpen"
Duration="0:0:0.01">
<DiscreteBooleanKeyFrame Value="False" KeyTime="100%"/>
</BooleanAnimationUsingKeyFrames>
</Storyboard>
</BeginStoryboard>
</EventTrigger>
</DataTemplate.Triggers>
</DataTemplate>
Right now popup is working : I mean it shows after 500ms and hides (almost correctly)
I'm trying to make a popup follows my mouse pointer while moving around MyImage control.
How to do it?

Related

Animate when another wrap panel is clicked

I have a list view that is being populated with wrap panels through my binding. My code currently will animate the opacity on MouseEnter (opacity up to 1.0) and MouseLeave (opacity down to {Binding PanelOpacity}) just fine. However, when I select a different wrap panel, I need the storyboard for MouseLeave to fire to reduce the opacity.
Snippet:
<ListView.ItemTemplate>
<DataTemplate>
<WrapPanel x:Name="panelObject" Orientation="Horizontal" Margin="5,7">
<WrapPanel.InputBindings>
<MouseBinding MouseAction="LeftClick"
Command="{Binding DataContext.GridClickCmd, RelativeSource={RelativeSource AncestorType=Grid}}"
CommandParameter="{Binding Server}"/>
</WrapPanel.InputBindings>
<WrapPanel.Style>
<Style TargetType="{x:Type WrapPanel}">
<Style.Resources>
<SolidColorBrush x:Key="{x:Static SystemColors.HighlightBrushKey}" Color="Red" />
</Style.Resources>
<Setter Property="Opacity" Value="{Binding PanelOpacity}" />
<Style.Triggers>
<Trigger Property="IsMouseOver" Value="True">
<Setter Property="Opacity" Value="1.0" />
</Trigger>
</Style.Triggers>
</Style>
</WrapPanel.Style>
<WrapPanel.Triggers>
<EventTrigger RoutedEvent="MouseEnter">
<BeginStoryboard>
<Storyboard x:Name="FadeIn">
<DoubleAnimation
Storyboard.TargetProperty="Opacity"
To="1.0" Duration="0:0:0.2" />
</Storyboard>
</BeginStoryboard>
</EventTrigger>
<EventTrigger RoutedEvent="MouseLeave">
<BeginStoryboard>
<Storyboard x:Name="FadeOut">
<DoubleAnimation
Storyboard.TargetProperty="Opacity"
To="{Binding PanelOpacity}" Duration="0:0:0.2" />
</Storyboard>
</BeginStoryboard>
</EventTrigger>
<EventTrigger RoutedEvent="SourceUpdated">
<BeginStoryboard>
<Storyboard x:Name="ChangeSelection">
<DoubleAnimation
Storyboard.TargetProperty="Opacity"
To="{Binding PanelOpacity}" Duration="0:0:0.2" />
</Storyboard>
</BeginStoryboard>
</EventTrigger>
</WrapPanel.Triggers>
</WrapPanel>
</DataTemplate>
</ListView.ItemTemplate>
I've tried using a few different Routed Events and none of them seem to fire when a different wrap panel is clicked.
Last thing I tried was this:
<EventTrigger RoutedEvent="SourceUpdated">
<BeginStoryboard>
<Storyboard x:Name="ChangeSelection">
<DoubleAnimation
Storyboard.TargetProperty="Opacity"
To="{Binding PanelOpacity}" Duration="0:0:0.2" />
</Storyboard>
</BeginStoryboard>
</EventTrigger>
Edit: I've got this in my C#. It works fine currently, without animation:
_viewModel.MainPanel.ToList().Find(x => x.Server == (string)parameter).PanelOpacity = 1.0;
_viewModel.MainPanel.ToList().FindAll(x => x.Server != (string)parameter).ForEach(x => x.PanelOpacity = 0.5);
Second Edit: Added more tags to show location of code.
Final Edit: full ItemTemplate code added.

Need to only fire EventTrigger one time

So I have an ItemsControl in which I'm animating newly added items with the following code:
EDIT, I have added more code as requested.
<ItemsControl Name="taskBox" ItemsSource="{Binding TaskList, Mode=OneWay}">
<ItemsControl.Resources>
<Storyboard x:Key="ItemEnterAnimation" AutoReverse="False">
<DoubleAnimationUsingKeyFrames Storyboard.TargetName="container" Storyboard.TargetProperty="(UIElement.Opacity)">
<EasingDoubleKeyFrame KeyTime="0" Value="0" />
<EasingDoubleKeyFrame KeyTime="0:0:0.3" Value="1" />
</DoubleAnimationUsingKeyFrames>
<DoubleAnimation BeginTime="00:00:00" Duration="00:00:00.3" Storyboard.TargetName="container" Storyboard.TargetProperty="(UIElement.RenderTransform).(TransformGroup.Children)[0].(TranslateTransform.X)" From="-30" To="0">
<DoubleAnimation.EasingFunction>
<CubicEase EasingMode="EaseOut"/>
</DoubleAnimation.EasingFunction>
</DoubleAnimation>
</Storyboard>
</ItemsControl.Resources>
<ItemsControl.ItemTemplate>
<DataTemplate>
<DataTemplate.Triggers>
<EventTrigger RoutedEvent="FrameworkElement.Loaded" >
<BeginStoryboard Storyboard="{StaticResource ItemEnterAnimation}" />
</EventTrigger>
</DataTemplate.Triggers>
<Grid Name="container">
<Grid.RenderTransform>
<TransformGroup>
<TranslateTransform/>
</TransformGroup>
</Grid.RenderTransform>
</Grid>
</DataTemplate>
</ItemsControl.ItemTemplate>
</ItemsControl>
The problem is that there are certain things that can cause the underlying ObservableCollection (TaskList in the sample) to send a CollectionChanged(Reset) event, which causes all of the elements to reload. As a result, the enter animation will get called for every single item again.
Is there a way to only perform this animation one time when the item is first loaded?

WinrtTrigger to change grid visibility

I am using this xaml to control visibility of grid on loaded event.
<Grid Grid.RowSpan="2" x:Name="grdStartup">
<trigger:Interactions.Triggers>
<trigger:EventTrigger EventName="Loaded" >
<trigger:SetPropertyAction PropertyName="Visibility" Value="Collapsed"/>
</trigger:EventTrigger>
</trigger:Interactions.Triggers>
</Grid>
This is not working, no error and no result.
Right now it's collapsed but later on I'll bind it to some property.
Hope this helps. for more details Visit
<Grid x:Name="Gd" Visibility="Visible">
<Grid.Triggers>
<EventTrigger>
<BeginStoryboard>
<Storyboard>
<ObjectAnimationUsingKeyFrames Storyboard.TargetName="Gd" Storyboard.TargetProperty="Visibility">
<DiscreteObjectKeyFrame Value="Collapsed" KeyTime="0"/>
</ObjectAnimationUsingKeyFrames>
</Storyboard>
</BeginStoryboard>
</EventTrigger>
</Grid.Triggers>
</Grid>

Animated Expander - Animates in only one direction

Can anyone tell me what might be wrong with this template. the expander only animates when expanding, not collapsing.
<ControlTemplate x:Key="ExpanderExTemplate" TargetType="{x:Type Expander}" >
<StackPanel Margin="0">
<Border BorderThickness="1" >
<Expander Name="expanderEx" Header="{TemplateBinding Header}" IsExpanded="{TemplateBinding IsExpanded}" BorderThickness="0">
<Border BorderThickness="0" >
<ContentPresenter x:Name="ExpandSite" Margin="5,5,5,5" >
<ContentPresenter.LayoutTransform>
<ScaleTransform x:Name="scaleTransform" ScaleX="1" ScaleY="1" />
</ContentPresenter.LayoutTransform>
</ContentPresenter>
</Border>
<Expander.Triggers>
<EventTrigger RoutedEvent="Expander.Expanded">
<EventTrigger.Actions>
<BeginStoryboard>
<Storyboard >
<DoubleAnimation From="0" To="1" Duration="0:0:0.25"
Storyboard.TargetName="ExpandSite"
Storyboard.TargetProperty="(FrameworkElement.LayoutTransform).(ScaleTransform.ScaleY)" />
</Storyboard>
</BeginStoryboard>
</EventTrigger.Actions>
</EventTrigger>
<EventTrigger RoutedEvent="Expander.Collapsed">
<EventTrigger.Actions>
<BeginStoryboard>
<Storyboard>
<DoubleAnimation From="1" To="0" Duration="0:0:0.25"
Storyboard.TargetName="ExpandSite"
Storyboard.TargetProperty="(FrameworkElement.LayoutTransform).(ScaleTransform.ScaleY)" />
</Storyboard>
</BeginStoryboard>
</EventTrigger.Actions>
</EventTrigger>
</Expander.Triggers>
</Expander>
</Border>
</StackPanel>
</ControlTemplate>

Reset the animation of user control when mouse leave

I want to display a user control on a rectangle with some animation when mouse move over the rectangle, reset the animation and collapse the user control when mouse leave.
My question is how should I "reset" the animation as my current approached is just collapses the user control when mouse leave. Below is my demo code.
EDITTED:
ControlLibrary.xaml
<UserControl.Style>
<Style>
<Style.Triggers>
<EventTrigger RoutedEvent="FrameworkElement.Loaded">
<BeginStoryboard Name="opacityStoryBoard">
<Storyboard >
<DoubleAnimation Storyboard.TargetProperty="Opacity" Duration="00:00:10" From="0" To="2" />
</Storyboard>
</BeginStoryboard>
</EventTrigger>
<EventTrigger RoutedEvent="FrameworkElement.MouseLeave">
<SeekStoryboard BeginStoryboardName="opacityStoryBoard" Offset="00:00:00"> </SeekStoryboard>
</EventTrigger>
<Trigger Property="FrameworkElement.Visibility" Value="Collapsed">
<Setter Property="FrameworkElement.Opacity" Value="0"/>
</Trigger>
</Style.Triggers>
</Style>
</UserControl.Style>
<StackPanel Orientation="Vertical">
<Label Content="Welcome" HorizontalAlignment="Stretch" VerticalAlignment="Top"
HorizontalContentAlignment="Center" VerticalContentAlignment="Center"
Foreground="White" Background="Transparent" FontSize="25" Height="300" Margin="10,0" />
<!--<Image Height="300" x:Name="qr" Margin="10,0" />-->
</StackPanel>
mainWindow.xaml
<myToolTip:UserControl1 Visibility="Collapsed"
x:Name="customToolTip" />
<Rectangle Fill="Transparent" HorizontalAlignment="Left" Height="322" Stroke="Black"
VerticalAlignment="Top" Width="518" MouseMove="Rectangle_MouseMove_1" MouseLeave="Rectangle_MouseLeave_1">
</Rectangle>
mainWindow.cs
private void Rectangle_MouseMove_1(object sender, MouseEventArgs e)
{
customToolTip.Visibility = System.Windows.Visibility.Visible;
}
private void Rectangle_MouseLeave_1(object sender, MouseEventArgs e)
{
customToolTip.Visibility = System.Windows.Visibility.Collapsed;
}
Please guide me..Thank you.
Use the SeekStoryBoard class to reset the animation time when the mouse leaves the rectangle.
For example:
<Style.Triggers>
<EventTrigger RoutedEvent="FrameworkElement.Loaded">
<BeginStoryboard Name="opacityStoryBoard">
<Storyboard >
<DoubleAnimation Storyboard.TargetProperty="Opacity" Duration="00:00:10" From="0" To="2" />
</Storyboard>
</BeginStoryboard>
</EventTrigger>
<Trigger Property="FrameworkElement.Visibility" Value="Collapsed">
<Setter Property="FrameworkElement.Opacity" Value="0"/>
<Trigger.EnterActions>
<SeekStoryboard BeginStoryboardName="opacityStoryBoard" Offset="00:00:00"></SeekStoryboard>
</Trigger.EnterActions>
</Trigger>
</Style.Triggers>

Categories

Resources