c# – Popup在动画WPF中显示一次但不再显示

我有一个窗口,右边有4个按钮.当我点击其中一个按钮时,我想要显示4个弹出窗口中的一个.我刚刚完成了第一个,但我遇到了一个我似乎无法弄清楚的绊脚石.由于4个弹出窗口几乎完全相同,我决定为ContentControl创建一个模板,然后在其中设置我的内容并将内容控件放在弹出窗口中.我的ContentControl模板中的一个项目是关闭按钮.我使用故事板将IsOpen属性设置为false.这部分是有效的. (花了很长时间才弄明白……)但是当我再次点击按钮打开同样的Popup时它没有显示,我不知道为什么.这是我的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>

虽然这没关系,但我的Popup风格是:

<Style x:Key="PopupStyle" TargetType="{x:Type Popup}">
    <Setter Property="AllowsTransparency" Value="True"/>
    <Setter Property="PopupAnimation" Value="Fade"/>
    <Setter Property="Placement" Value="Center"/>
    <Setter Property="PlacementTarget" Value="{Binding RelativeSource={RelativeSource Mode=FindAncestor, AncestorType=Window}}"/>
</Style>

在我的UserControl中,我有这个弹出窗口:

<Popup x:Name="popuptest" Opened="popuptest_Opened" Closed="popuptest_Opened" Style="{DynamicResource PopupStyle}" >
    <ContentControl Style="{DynamicResource PopupContentStyle}">
        <b:BrightnessControl />
    </ContentControl>
</Popup>

我用来打开亮度按钮的代码并不复杂:

private void brightButton_Click(object sender, RoutedEventArgs e)
{
    popuptest.IsOpen = true;
}

在这里,我的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合作了大约一个月,所以如果你看到我应该改变的东西,建议它.谢谢.

解决方法:

当动画用于特定属性时,由于优先级列表(link),只能通过动画进一步分配属性.从MSDN引用:

In order to have any practical effect, an animation of a property must be able to have precedence over the base (unanimated) value, even if that value was set locally.

来自同一来源:

For an animation, the base value can have an effect on the animated value, if that animation does not specify both “From” and “To” for certain behaviors, or if the animation deliberately reverts to the base value when completed. To see this in practice, run the From, To, and By Animation Target Values Sample. Try setting the local values of the rectangle height in the example, such that the initial local value differs from any “From” in the animation. You will note that the animations start right away using the “From” values and replace the base value once started. The animation might specify to return to the value found before animation once it is completed by specifying the Stop FillBehavior. Afterwards, normal precedence is used for the base value determination.

因此,因此动画的属性是第一优先级,然而其他来源,例如代码,指定不会.

有哪些替代方案?

I.如文档中所述,使用FillBehavior =“Stop”.既然你没有动画From,To和Duration,那么这不是一个选择.

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>

III.在处理程序(代码中)中,在设置新值之前,删除动画,如下所示:

XAML

<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;
}     
上一篇:sqlserver跨数据库使用事务更新报错 链接服务器的 OLE DB 访问接口 “SQLNCLI11“


下一篇:C++数据库编程简介