C# 弹出窗口在动画WPF中显示一次,但不会再次显示
我有一个右边有4个按钮的窗口。当我点击其中一个按钮时,我想显示4个弹出窗口中的1个。我只差一步就完成了第一个,但我遇到了一个我似乎无法理解的绊脚石。由于4个弹出窗口需要几乎相同,我决定为C# 弹出窗口在动画WPF中显示一次,但不会再次显示,c#,wpf,animation,popup,C#,Wpf,Animation,Popup,我有一个右边有4个按钮的窗口。当我点击其中一个按钮时,我想显示4个弹出窗口中的1个。我只差一步就完成了第一个,但我遇到了一个我似乎无法理解的绊脚石。由于4个弹出窗口需要几乎相同,我决定为ContentControl创建一个模板,然后在其中设置我的内容,并将内容控件放入弹出窗口。我的ContentControl模板中的一项是关闭按钮。我使用故事板将IsOpen属性设置为false。所以这部分起作用了。(这花了很长时间才弄明白……)但当我再次点击按钮打开相同的弹出窗口时,它没有显示出来,我不知道为什
ContentControl
创建一个模板,然后在其中设置我的内容,并将内容控件放入弹出窗口。我的ContentControl模板中的一项是关闭按钮。我使用故事板将IsOpen
属性设置为false。所以这部分起作用了。(这花了很长时间才弄明白……)但当我再次点击按钮打开相同的弹出窗口时,它没有显示出来,我不知道为什么。这是我的ContentControl的模板
<Style x:Key="PopupContentStyle" TargetType="ContentControl">
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="ContentControl">
<Grid>
<Rectangle Fill="WhiteSmoke" Opacity=".50" Width="{Binding RelativeSource={RelativeSource Mode=FindAncestor, AncestorType=Window}, Path=Width}" Height="{Binding RelativeSource={RelativeSource Mode=FindAncestor, AncestorType=Window}, Path=Height}" />
<Button Height="50" Style="{DynamicResource CloseButton}" HorizontalAlignment="Right" VerticalAlignment="Top" >
<Button.Triggers>
<EventTrigger RoutedEvent="Button.Click">
<BeginStoryboard>
<Storyboard>
<BooleanAnimationUsingKeyFrames
Storyboard.Target="{Binding RelativeSource={RelativeSource AncestorLevel=1, AncestorType=Popup,Mode=FindAncestor}}"
Storyboard.TargetProperty="(Popup.IsOpen)" Duration="0:0:0">
<DiscreteBooleanKeyFrame KeyTime="0:0:0" Value="False" />
</BooleanAnimationUsingKeyFrames>
</Storyboard>
</BeginStoryboard>
</EventTrigger>
</Button.Triggers>
</Button>
<ContentPresenter />
</Grid>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
在我的UserControl
中,我有一个弹出窗口
:
<Popup x:Name="popuptest" Opened="popuptest_Opened" Closed="popuptest_Opened" Style="{DynamicResource PopupStyle}" >
<ContentControl Style="{DynamicResource PopupContentStyle}">
<b:BrightnessControl />
</ContentControl>
</Popup>
这里是我的xaml中的另外两个事件
public event PopupIsOpenedChangedHandler PopupIsOpenedChanged;
public delegate void PopupIsOpenedChangedHandler(bool isOpen);
private void OnPopupIsOpenedChanged(bool isOpen)
{
if (PopupIsOpenedChanged != null)
PopupIsOpenedChanged(isOpen);
}
private void popuptest_Opened(object sender, System.EventArgs e)
{
OnPopupIsOpenedChanged(popuptest.IsOpen);
}
请帮忙:)。哦,我和WPF只合作了大约一个月,所以如果你看到一些我应该改变的东西,一定要提出建议。谢谢。当动画用于特定属性时,由于优先级列表(),只能通过动画进一步指定属性。引用自MSDN
:
为了产生任何实际效果,特性的动画必须能够优先于基本(无动画)值,即使该值是在本地设置的
来自同一来源:
对于动画,如果该动画没有为某些行为同时指定“从”和“到”,或者如果动画在完成时故意恢复到基准值,则基准值可能会对动画值产生影响。要在实践中看到这一点,请运行From、To和By动画目标值示例。尝试在示例中设置矩形高度的局部值,使初始局部值不同于动画中的任何“from”。您将注意到,动画立即开始使用“From”值,并在开始后替换基值。动画可以通过指定停止填充行为指定在动画完成后返回到动画之前找到的值。之后,正常优先级用于确定基值
因此,由于这一点,动画的属性是第一优先权,但是其他源(如代码)不会指定
有哪些替代方案
I.
如文档中所述,使用FillBehavior=“Stop”
。由于您在动画中没有从
、到
和持续时间
,因此这不是您的选项
II.
在这两种情况下都使用EventTrigger
,即:
<EventTrigger SourceName="CloseButton" RoutedEvent="Button.Click">
<BeginStoryboard>
<Storyboard>
<BooleanAnimationUsingKeyFrames Storyboard.TargetName="MyPopup"
Storyboard.TargetProperty="(Popup.IsOpen)"
Duration="0:0:0">
<DiscreteBooleanKeyFrame KeyTime="0:0:0" Value="False" />
</BooleanAnimationUsingKeyFrames>
</Storyboard>
</BeginStoryboard>
</EventTrigger>
<EventTrigger SourceName="OpenButton" RoutedEvent="Button.Click">
<BeginStoryboard>
<Storyboard>
<BooleanAnimationUsingKeyFrames Storyboard.TargetName="MyPopup"
Storyboard.TargetProperty="(Popup.IsOpen)"
Duration="0:0:0">
<DiscreteBooleanKeyFrame KeyTime="0:0:0" Value="True" />
</BooleanAnimationUsingKeyFrames>
</Storyboard>
</BeginStoryboard>
</EventTrigger>
代码隐藏
private void OpenButton_Click(object sender, RoutedEventArgs e)
{
MyPopup.BeginAnimation(Popup.IsOpenProperty, null);
MyPopup.IsOpen = true;
}
如果你设置AutoReverse=true会发生什么?@GarryVass我对你的魔法一无所知:)我没有提交我的代码,所以我必须等到明天才能测试你说的话。@GarryVass我使用关键帧将AutoReverse放入我的
布尔动画中,但没有骰子。我希望有一种方法来调试它,看看发生了什么。我最终制作了一个UserControl,然后将它从UserControl更改为弹出窗口,添加了我的矩形、按钮和内容演示器。创建了一个方法来设置内容演示者的子级。我使用代码隐藏关闭弹出窗口。但这些信息对未来非常有用,因为我可能会再次这样做。感谢您对此进行的辛勤研究。
<EventTrigger SourceName="CloseButton" RoutedEvent="Button.Click">
<BeginStoryboard>
<Storyboard>
<BooleanAnimationUsingKeyFrames Storyboard.TargetName="MyPopup"
Storyboard.TargetProperty="(Popup.IsOpen)"
Duration="0:0:0">
<DiscreteBooleanKeyFrame KeyTime="0:0:0" Value="False" />
</BooleanAnimationUsingKeyFrames>
</Storyboard>
</BeginStoryboard>
</EventTrigger>
<EventTrigger SourceName="OpenButton" RoutedEvent="Button.Click">
<BeginStoryboard>
<Storyboard>
<BooleanAnimationUsingKeyFrames Storyboard.TargetName="MyPopup"
Storyboard.TargetProperty="(Popup.IsOpen)"
Duration="0:0:0">
<DiscreteBooleanKeyFrame KeyTime="0:0:0" Value="True" />
</BooleanAnimationUsingKeyFrames>
</Storyboard>
</BeginStoryboard>
</EventTrigger>
<Grid>
<Grid.Triggers>
<EventTrigger SourceName="CloseButton" RoutedEvent="Button.Click">
<BeginStoryboard>
<Storyboard>
<BooleanAnimationUsingKeyFrames Storyboard.TargetName="MyPopup"
Storyboard.TargetProperty="(Popup.IsOpen)"
Duration="0:0:0">
<DiscreteBooleanKeyFrame KeyTime="0:0:0" Value="False" />
</BooleanAnimationUsingKeyFrames>
</Storyboard>
</BeginStoryboard>
</EventTrigger>
</Grid.Triggers>
<Popup x:Name="MyPopup" Width="200" Height="200" IsOpen="True">
<Grid Background="Azure">
<Label Content="Test label" />
</Grid>
</Popup>
<Button Name="OpenButton" Content="OpenButtonFromCode" Width="140" Height="30" Click="OpenButton_Click" />
<Button Name="CloseButton" Content="CloseButtonfromEventTrigger" Width="180" Height="30" Margin="0,80,0,0" />
</Grid>
private void OpenButton_Click(object sender, RoutedEventArgs e)
{
MyPopup.BeginAnimation(Popup.IsOpenProperty, null);
MyPopup.IsOpen = true;
}