问题描述
假设您有一个ToggleButton
用于打开Popup
,其行为与所有已知元素(如ComboBox
等)相同.
Suppose you have a ToggleButton
for opening a Popup
, same behaviour as all known elements as ComboBox
etc.
...这是这段代码:
... which is this code:
<ToggleButton x:Name="PART_OpenToggleButton"
Focusable="False"
IsChecked="False"
Template="{StaticResource MyToggleButton}">
<Grid>
<Popup x:Name="PART_PopupControl"
Style="{StaticResource MyPopupStyle}"
StaysOpen="False"
VerticalAlignment="Bottom"
IsOpen="False"
PlacementTarget="{Binding RelativeSource={RelativeSource Mode=FindAncestor, AncestorType=ToggleButton, AncestorLevel=1}}" />
</Grid>
</ToggleButton>
然后在您后面的代码中使用.IsOpen
表示Popup
,使用.IsChecked
表示ToggleButton
.一切正常,但是当您打开Popup
并在边界外单击时,问题就出现了.Popup
将关闭,但ToggleButton
保持选中状态.
Then in code behind you work with .IsOpen
for Popup
and .IsChecked
for ToggleButton
.Everything works, but the problem arrives when you Open the Popup
and click outside the borders.The Popup
will be closed but the ToggleButton
stays checked.
您不能在PopupOnClosed
处理程序中设置ToggleButton.IsChecked = false
,因为单击ToggleButton
关闭Popup
时,Popup
会自行关闭,设置ToggleButton.IsChecked = false
,但是在sime时间,点击ToggleButton
,它再次尝试打开 Popup
.因此您无法将其关闭.
You cannot set in the PopupOnClosed
Handler that ToggleButton.IsChecked = false
, because when you Click on the ToggleButton
to close the Popup
, the Popup
closes itself, sets ToggleButton.IsChecked = false
but at the sime time you clicked on the ToggleButton
and it tries to Open the Popup
again. So you cannot close it.
第一个ToggleButtonClick:
1st ToggleButtonClick:
-> ToggleButton IsChecked = true
第二个ToggleButtonClick:
2nd ToggleButtonClick:
-> ToggleButton IsChecked = false
-> ToggleButton IsChecked = true
因此,如果在打开弹出窗口时单击切换"按钮,它将闪烁但保持打开状态.
So if you click on the Toggle Button while Popup being open, it blinks but stays open.
请问您将如何解决这个问题?
How would you solve this problem, please ?
已编辑
在MyWindow.XAML中尝试此操作,然后添加依赖项属性IsDropDownOpen在后面的代码中,请:
Try this in a MyWindow.XAML and add the dependency property IsDropDownOpenin the code behind, please:
<Grid>
<ToggleButton x:Name="PART_OpenToggleButton"
Focusable="False"
Height="20"
Width="50"
IsChecked="{Binding ElementName=TestWindow, Mode=TwoWay, Path=IsDropDownOpen}">
<Grid>
<Popup x:Name="PART_PopupControl"
Width="100"
Height="100"
StaysOpen="False"
Focusable="False"
VerticalAlignment="Bottom"
IsOpen="{Binding ElementName=TestWindow, Path=IsDropDownOpen}"
PlacementTarget="{Binding RelativeSource={RelativeSource Mode=FindAncestor, AncestorType=ToggleButton, AncestorLevel=1}}">
</Popup>
</Grid>
</ToggleButton>
</Grid>
public bool IsDropDownOpen
{
get { return (bool)GetValue(IsDropDownOpenProperty); }
set { SetValue(IsDropDownOpenProperty, value); }
}
public static readonly DependencyProperty IsDropDownOpenProperty =
DependencyProperty.Register("IsDropDownOpen", typeof(bool), typeof(Window), new UIPropertyMetadata(false));
推荐答案
我在这篇文章中找到了解决方案: https://stackoverflow .com/a/5821819/651161
I found the solution on this post : https://stackoverflow.com/a/5821819/651161
使用以下类将允许在按下切换按钮之前处理单击.由于单击而关闭了弹出窗口,但是随后处理了该单击,因此它不会触发ToggleButton单击.
Using the following class will permit to handle the click before the togglebutton is pressed. The popup is closed because of the click but the click is then handled, so it doesn't trigger the ToggleButton click.
public class MyPopup : Popup {
protected override void OnPreviewMouseLeftButtonDown(MouseButtonEventArgs e) {
bool isOpen = this.IsOpen;
base.OnPreviewMouseLeftButtonDown(e);
if (isOpen && !this.IsOpen)
e.Handled = true;
}
}
这篇关于WPF弹出窗口隐藏问题的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!