Reputation: 2373
I have an application in WPF that is using a popup to show additional data to a user (in this case a link to some help). I have it positioned how I want it; the link to open it is in the top right so it comes down right justified below the link. However I would also like to animate it flying out basically from the top right corner of the popup.
I have this sort of working, but it's not quite what I want. By animating the width and the horizontal offset I was able to get the overall popup to come in diagonally like I want. However, the content inside is still based on the top left for its layout, so as the popup moves left it keeps redrawing the popup content as if it's moving too. What I would like is for the popup content to remain static and the edges of the popup to 'reveal' the content as it opens (and 'cover' it as it closes). Here is my code for the popup:
<Popup PlacementTarget="{Binding ElementName=ImgHelp}" Placement="Left" VerticalOffset="48"
x:Name="PuHelp" AllowsTransparency="True" IsOpen="True">
<Popup.Tag>
<system:Double>0.0</system:Double>
</Popup.Tag>
<Popup.Width>
<MultiBinding Converter="{StaticResource CvMultiply}">
<Binding Path="ActualWidth" ElementName="GdHelpContent" />
<Binding Path="Tag" RelativeSource="{RelativeSource Self}" />
</MultiBinding>
</Popup.Width>
<Popup.Height>
<MultiBinding Converter="{StaticResource CvMultiply}">
<Binding Path="ActualHeight" ElementName="GdHelpContent" />
<Binding Path="Tag" RelativeSource="{RelativeSource Self}" />
</MultiBinding>
</Popup.Height>
<Popup.HorizontalOffset>
<MultiBinding Converter="{StaticResource CvNegate}">
<Binding Path="ActualWidth" ElementName="GdHelpContent" />
<Binding Path="Tag" RelativeSource="{RelativeSource Self}" />
</MultiBinding>
</Popup.HorizontalOffset>
<Popup.Style>
<Style TargetType="Popup">
<Style.Triggers>
<DataTrigger Binding="{Binding IsHelpOpen, RelativeSource={RelativeSource AncestorType={x:Type local:UC_ApplicationWindow}}}" Value="True">
<DataTrigger.EnterActions>
<BeginStoryboard>
<Storyboard>
<DoubleAnimation Duration="0:0:0.25" To="1" Storyboard.TargetProperty="Tag" />
</Storyboard>
</BeginStoryboard>
</DataTrigger.EnterActions>
<DataTrigger.ExitActions>
<BeginStoryboard>
<Storyboard>
<DoubleAnimation Duration="0:0:0.25" To="0" Storyboard.TargetProperty="Tag" />
</Storyboard>
</BeginStoryboard>
</DataTrigger.ExitActions>
</DataTrigger>
</Style.Triggers>
</Style>
</Popup.Style>
<Grid x:Name="GdHelpContent" RenderTransformOrigin="1,1">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="Auto" />
</Grid.ColumnDefinitions>
<Grid.RowDefinitions>
<RowDefinition Height="Auto" />
</Grid.RowDefinitions>
<Grid.RenderTransform>
<TranslateTransform x:Name="tfGrid" X="0" Y="0" />
</Grid.RenderTransform>
<Grid Background="{StaticResource BrApplicationHeader}">
<ContentControl Margin="15" Content="{Binding HelpContent, RelativeSource={RelativeSource AncestorType={x:Type local:UC_ApplicationWindow}}}" />
</Grid>
</Grid>
</Popup>
Is there a good way to do this?
Upvotes: 1
Views: 67
Reputation: 2373
Ok after much frustrating toil I got this to work in a completely different way. You can use the opacity mask property to set the opacity of parts of the control at render time to any shape, in this case I just want a rectangle. However, since a straight rect size, etc. is not dependency properties you can't animate them...
What I ended up having to do was to create another border behind the main content border and animate that. Then set the opacity mask for the main one to a visual brush using that border as the visual. Not only that, it won't set opacity for things outside the border, so I had to have an outside border that is transparent, then an internal one that is a solid color, then you animate the scale of the internal one...
Here is the code:
<Grid x:Name="GdHelpContent" HorizontalAlignment="Right" VerticalAlignment="Top" Margin="0,45,20,0">
<Border x:Name="RectHelpClip" Background="Transparent">
<Border Background="{StaticResource BrHelpBackground}" RenderTransformOrigin="1,0">
<Border.RenderTransform>
<ScaleTransform ScaleX="0" ScaleY="0" />
</Border.RenderTransform>
<Border.Style>
<Style TargetType="Border">
<Style.Triggers>
<DataTrigger Binding="{Binding IsHelpOpen, RelativeSource={RelativeSource AncestorType={x:Type local:UC_ApplicationWindow}}}" Value="True">
<DataTrigger.EnterActions>
<BeginStoryboard>
<Storyboard>
<DoubleAnimation Duration="0:0:0.25" To="1"
Storyboard.TargetProperty="RenderTransform.ScaleX" />
<DoubleAnimation Duration="0:0:0.25" To="1"
Storyboard.TargetProperty="RenderTransform.ScaleY" />
</Storyboard>
</BeginStoryboard>
</DataTrigger.EnterActions>
<DataTrigger.ExitActions>
<BeginStoryboard>
<Storyboard>
<DoubleAnimation Duration="0:0:0.25" To="0"
Storyboard.TargetProperty="RenderTransform.ScaleX" />
<DoubleAnimation Duration="0:0:0.25" To="0"
Storyboard.TargetProperty="RenderTransform.ScaleY" />
</Storyboard>
</BeginStoryboard>
</DataTrigger.ExitActions>
</DataTrigger>
</Style.Triggers>
</Style>
</Border.Style>
</Border>
</Border>
<Border Style="{StaticResource StHelpPanel}">
<Border.OpacityMask>
<VisualBrush Visual="{Binding ElementName=RectHelpClip}" />
</Border.OpacityMask>
<ContentControl Margin="15" Content="{Binding HelpContent, RelativeSource={RelativeSource AncestorType={x:Type local:UC_ApplicationWindow}}}" />
</Border>
</Grid>
Hope that helps someone...
Upvotes: 0