Где вы на самом деле закрываете Popup
? Я вижу только, что вы устанавливаете IsOpen
в true
. Текущее поведение: первый щелчок по PopupButton
откроет Popup
. Теперь, когда для StaysOpen
установлено значение false
, повторное нажатие кнопки (которая находится за пределами Popup
) приведет к закрытию Popup
, поскольку popup
потерял фокус, поскольку он перемещен из Popup
до PopupButton
. IsOpen
возвращается сейчас false
. Этот второй щелчок затем вызывает обработчик события ButtonClickAsync
, который снова устанавливает IsOpen
в значение true, что снова открывает Popup
.
Ваш код слишком сложен, потому что вы используете C# вместо XAML.
PopupButton
должен быть ToggleButton
или основан на нем.
<Window>
<StackPanel>
<ToggleButton x:Name="PopupButton" />
<Popup IsOpen="{Binding ElementName=PopupButton, Path=IsChecked}">
<ElementTreeControl Tag="pmButton" />
</Popup>
</StackPanel>
</Window>
Использование EventTrigger
Альтернативный подход заключается в использовании EventTrigger
. Это может быть проще в ситуациях, когда у вас нет доступа к управляющему элементу запуска, например, PopupButton
, поскольку он может быть определен вне области видимости, например, внутри какого-либо другого шаблона. В этом примере все еще предполагается, что PopupButton
является производным от ToggleButton
:
Window
, в котором находится Popup
(ToggleButton
, который открывает / закрывает Popup
, определяется в отдельном элементе управления ControlWithPopupButton
, см. ниже)
<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>
UserControl, который содержит PopupButton
<ControlWithPopupButton>
<!--
PopupButton must derive from ToggleButton
or raise both Routed Events ToggleButon.Check and ToggleButton.Unchecked.
-->
<PopupButton x:Name="PopupButton" />
</ControlWithPopupButton>
Замечания
Затем такие методы, как ElementTreeControl.Init
, должны вызываться из обработчика событий ElementTreeControl.Loaded
внутри класса ElementTreeControl
. Я не знаю, что такое StarElement
, но оно должно связываться с DependencyProperty
из ElementTreeControl
. У меня недостаточно контекста, но я думаю, вам следует добавить override
из ElementTreeControl.OnSelectionChanged
, чтобы вы могли переместить код PopupListBoxSelectionChangedAsync
в ElementTreeControl
.