C# 当父窗口折叠时,如何关闭弹出窗口? 背景
我有一个C# 当父窗口折叠时,如何关闭弹出窗口? 背景,c#,wpf,popup,C#,Wpf,Popup,我有一个HeaderedContentControl的控件模板,其中包含一个作为标题的按钮,单击时会打开一个包含主要内容的弹出窗口(通过EventTrigger) 这和我预期的一样,直到我尝试在弹出窗口中添加一个按钮以折叠控件。主按钮(标题)消失,但弹出窗口(内容)保持在原来的位置,直到我(通过单击某个地方)从中获取鼠标焦点 下面是一个简短的示例,演示了该问题: 在我的真实代码中,ControlTemplate与控件的用法不在同一位置。它完全在另一个地方的ResourceDictionary
HeaderedContentControl
的控件模板,其中包含一个作为标题的按钮,单击时会打开一个包含主要内容的弹出窗口(通过EventTrigger
)
这和我预期的一样,直到我尝试在弹出窗口中添加一个按钮以折叠控件。主按钮(标题)消失,但弹出窗口(内容)保持在原来的位置,直到我(通过单击某个地方)从中获取鼠标焦点
下面是一个简短的示例,演示了该问题:
在我的真实代码中,ControlTemplate
与控件的用法不在同一位置。它完全在另一个地方的ResourceDictionary
中,不应该知道它弹出窗口的任何内容-它直接将它传递给ContentPresenter
问题:
理想情况下,是否有一种方法可以在不让ControlTemplate
知道弹出窗口包含“隐藏”按钮的可能性的情况下,在HeaderedContentControl
折叠时使弹出窗口消失
我试过的
- 将另一个触发器添加到
以监视HeaderedContentControl
更改。没有合适的是否可见
,其他触发器不能包含元素名称EventTrigger
- 在
的子类中将事件处理程序添加到HeaderedContentControl
。事件将触发,但设置为IsVisibleChanged
后,IsOpen仍保持false
true
- 这里的基本问题是,您正在使用
情节提要来控制弹出状态。这意味着当发生单击
事件时,您正在告诉WPF开始一个动画,在该动画中,它将弹出窗口的IsOpen
属性设置为true
请注意,动画没有固定的持续时间,因此实际上从不停止。尝试将Popup.IsOpen
设置为false
失败,因为WPF仍在为属性设置动画,因此会立即将其设置回“true”
作为概念证明,请尝试在启动动画后立即暂停动画:
<EventTrigger RoutedEvent="Button.Click" >
<BeginStoryboard Name="ShowPopupStoryBoard">
<Storyboard>
<BooleanAnimationUsingKeyFrames Storyboard.TargetName="Popup"
Storyboard.TargetProperty="(Popup.IsOpen)" >
<DiscreteBooleanKeyFrame KeyTime="0" Value="True" />
</BooleanAnimationUsingKeyFrames>
</Storyboard>
</BeginStoryboard>
<PauseStoryboard BeginStoryboardName="ShowPopupStoryBoard"/>
</EventTrigger>
通过暂停动画,可以防止WPF重置Popup.IsOpen
属性。因此,您可以继续并对IsVisibleChanged
(或其他适当的事件)做出反应,设置Popup.IsOpen
属性false
,并使其实际生效
不幸的是,这只会暂停动画。在重复测试中,上述方法并不一致——也就是说,它总是在第一次单击时起作用,但在随后的单击中(我更改了演示代码以不隐藏按钮),有时起作用,有时不起作用——我认为这是与调用各种EventTrigger
子级有关的时间问题
在任何情况下,情节提要
似乎都是一个沉重的负担,至少在某些明显的方面,显示弹出窗口的机制不合适。我知道的一个持续工作的替代方法是,只需将事件处理程序添加到模板的按钮
控件的单击
事件,然后将Popup.IsOpen
属性设置为true
。在这种情况下,您只需对其进行切换,而不是对其设置动画,因此WPF不会做任何事情来强制它在稍后将其设置回false
时保持设置为true
不过,最重要的是要在可用的机制中选择某种机制,以确保Popup.IsOpen
属性不会持续被设置动画。只要WPF将属性动画设置为true
值,将其设置为false
就不会有任何效果(的确,弹出窗口消失有点令人惊讶,即使它失去焦点……我猜缺少焦点比IsOpen
属性值更重要)
不幸的是,因为这里的主要问题与模板的当前实现有关,我认为与您声明的偏好相反,任何正确的修复都需要您修改模板。我想你可以在弹出窗口的内容对象中添加逻辑来追踪它的故事板并实际阻止它。但在这种情况下,治疗似乎比疾病更糟糕。它可能不符合您的要求,但我想我更喜欢约翰·梅尔维尔的方法:。没有故事板,更简单的绑定。太棒了-我没有想到动画会造成问题。在阅读您的答案时,我意识到我对不修改模板的限制有点过度。我的意思是,我不想在模板中添加任何特定于“隐藏”按钮的内容,但添加一对事件处理程序,以便在单击时打开,在不可见时关闭是可以的。谢谢你非常详尽的回答!