在WPF中检测点击和弹出按钮外部
我对WPF中的弹出按钮有问题。 当我按下它一次,弹出窗口显示一些项目来选择ElementTreeControl。在我按下相同的弹出按钮后,它应该会关闭,但它会关闭并再次打开。 我解决了这个问题,它也工作了,但是当我在这个控件之外单击,它关闭了StayOpen=false,我无法再次打开它-需要按两次PopupButton 在如何检测控件何时被按下以及何时处于其外部区域方面,是否有一些属性或解决方法 我希望弹出按钮是: 关闭时: 单击即可打开 打开时: 通过第二次单击弹出按钮关闭 通过单击外部区域关闭 弹出按钮单击操作:在WPF中检测点击和弹出按钮外部,wpf,Wpf,我对WPF中的弹出按钮有问题。 当我按下它一次,弹出窗口显示一些项目来选择ElementTreeControl。在我按下相同的弹出按钮后,它应该会关闭,但它会关闭并再次打开。 我解决了这个问题,它也工作了,但是当我在这个控件之外单击,它关闭了StayOpen=false,我无法再次打开它-需要按两次PopupButton 在如何检测控件何时被按下以及何时处于其外部区域方面,是否有一些属性或解决方法 我希望弹出按钮是: 关闭时: 单击即可打开 打开时: 通过第二次单击弹出按钮关闭 通过单击外部区域
private Popup rtWindowBoundsPopup;
private async void ButtonClickAsync(object pmSender, RoutedEventArgs pmE)
{
if (pmSender is PopupButton lcButton)
{
if (lcButton.Tag is StarElement lcStarElement)
{
if (!string.IsNullOrEmpty(DatabaseName))
{
lcStarElement = await rtStarHelper.AssureMetaData(lcStarElement, DatabaseName);
}
else
{
StarDim lcStarDim = rtStarHelper.GetDimFromDimId(lcStarElement.Dim.DimId, true);
lcStarElement.Dim = await rtStarHelper.AssureMetaData(lcStarDim);
}
ShowTreeViewPopup(lcButton, lcStarElement);
}
}
}
private void ShowTreeViewPopup(PopupButton pmButton, StarElement pmStarElement)
{
ElementTreeControl lcElementTreeControl;
if (rtWindowBoundsPopup == null)
{
rtWindowBoundsPopup = new Popup();// { IsLightDismissEnabled = true };
rtWindowBoundsPopup.Opened += WindowBoundsPopupOpened;
}
if (rtWindowBoundsPopup.Child is ElementTreeControl lcTreeControl)
{
lcElementTreeControl = lcTreeControl;
lcElementTreeControl.HideAddionalCols();
}
else
{
lcElementTreeControl = new ElementTreeControl { Tag = pmButton };
rtWindowBoundsPopup.Child = lcElementTreeControl;
lcElementTreeControl.SelectionChanged += PopupListBoxSelectionChangedAsync;
}
Point lcPoint = UiHelper.CalcOffsets(pmButton);
Rect lcCurrentwindowbounds = CurrentWindow.RestoreBounds;
if (lcPoint.Y < lcCurrentwindowbounds.Height / 2)
{
lcElementTreeControl.MaxHeight = lcCurrentwindowbounds.Height - lcPoint.Y - pmButton.ActualHeight;
}
else
{
lcElementTreeControl.MaxHeight = lcPoint.Y - pmButton.ActualHeight;
}
lcElementTreeControl.Width = Math.Max(pmButton.ActualWidth, 400);
lcElementTreeControl.MaxWidth = lcCurrentwindowbounds.Width;
lcElementTreeControl.MinHeight = 150;
lcElementTreeControl.Init(rtStarCube, pmStarElement, rtStarHelper);
lcElementTreeControl.CaptionColWidth = lcElementTreeControl.Width;
rtWindowBoundsPopup.PlacementTarget = pmButton;
rtWindowBoundsPopup.Placement = PlacementMode.Bottom;
rtWindowBoundsPopup.StaysOpen = false;//false;
rtWindowBoundsPopup.Closed -= WindowBoundsPopupOnClosed;
rtWindowBoundsPopup.Closed += WindowBoundsPopupOnClosed;
rtWindowBoundsPopup.IsOpen = true;
}
在WindowBoundsPopupOnClosed中,什么都没有发生,我尝试过让它在那里工作,但没有这样做。在哪里关闭弹出窗口?我只看到你把IsOpen设置为true。当前行为:第一次单击PopupButton将打开弹出窗口。现在由于StaysOpen设置为false,再次单击弹出窗口外的按钮将关闭弹出窗口,因为弹出窗口已失去焦点,因为它已从弹出窗口移动到弹出按钮。IsOpen现在返回false。然后,第二次单击将调用事件处理程序ButtonClickAsync,它将IsOpen再次设置为true,从而重新打开弹出窗口 您的代码太复杂了,因为您使用的是C而不是XAML PopupButton应该是一个ToggleButton或者基于它
<Window>
<StackPanel>
<ToggleButton x:Name="PopupButton" />
<Popup IsOpen="{Binding ElementName=PopupButton, Path=IsChecked}">
<ElementTreeControl Tag="pmButton" />
</Popup>
</StackPanel>
</Window>
UserControl,其中包含PopupButton
评论
然后,应该从ElementTreeControl类内的ElementTreeControl.Loaded事件处理程序调用ElementTreeControl.Init等方法。我现在不知道StarElement是什么,但它应该绑定到ElementTreeControl的DependencyProperty。我没有足够的上下文,但我想您应该添加ElementTreeControl.OnSelectionChanged的覆盖,这样您就可以将PopUpplistBoxSelectionChangedAsync的代码移动到ElementTreeControl
为什么不能尝试在放置弹出窗口的视图中捕获单击事件。因此,当您在弹出窗口外单击时,事件将被触发。您好!这是来自遗留代码,这就是它如此复杂的原因。popupButton是从其他控件启动的,但我将尝试调整您使用toggleButton所说的内容。弹出窗口关闭,因为属性StaysOpen设置为false,并且在选择更改事件中-IsOpen设置为false。您仍然可以绑定到按钮,无论它定义在何处。您还可以使用EventTrigger。我更新了我的问题,展示了如何使用ÈventTrigger`,通过点击切换按钮来切换弹出窗口。这可能是您场景中的最佳解决方案。
<Window>
<Window.Triggers>
<!--
EventTriggers must be defined in the scope of the Popup "RtWindowBoundsPopup"
and in the routing path of the raised event.
-->
<EventTrigger RoutedEvent="ToggleButton.Unchecked"
Sourcename="PopupButton">
<BeginStoryboard>
<Storyboard>
<BooleanAnimationUsingKeyFrames Storyboard.TargetName="RtWindowBoundsPopup"
Storyboard.TargetProperty="IsOpen"
Duration="0">
<DiscreteBooleanKeyFrame Value="False" />
</BooleanAnimationUsingKeyFrames>
</Storyboard>
</BeginStoryboard>
</EventTrigger>
<EventTrigger RoutedEvent="ToggleButton.Checked"
Sourcename="PopupButton">
<BeginStoryboard>
<Storyboard>
<BooleanAnimationUsingKeyFrames Storyboard.TargetName="RtWindowBoundsPopup"
Storyboard.TargetProperty="IsOpen"
Duration="0">
<DiscreteBooleanKeyFrame Value="True" />
</BooleanAnimationUsingKeyFrames>
</Storyboard>
</BeginStoryboard>
</EventTrigger>
</Window.Triggers>
<StackPanel>
<ControlWithPopupButton />
<Popup x:Name="RtWindowBoundsPopup">
<ElementTreeControl Tag="pmButton" />
</Popup>
</StackPanel>
</Window>
<ControlWithPopupButton>
<!--
PopupButton must derive from ToggleButton
or raise both Routed Events ToggleButon.Check and ToggleButton.Unchecked.
-->
<PopupButton x:Name="PopupButton" />
</ControlWithPopupButton>