Взаимодействие Popup и Togglebutton в wpf - PullRequest
9 голосов
/ 28 апреля 2011

У меня есть элемент управления, который содержит кнопку переключения и всплывающее окно. При нажатии кнопки ToggleButton появляется всплывающее окно. Когда кнопка ToggleButton снята, всплывающее окно должно закрыться. Кроме того, если щелкнуть мышью вдали от всплывающего окна, оно должно закрыться и снять флажок с кнопки-переключателя.

Я установил это, установив для свойства StaysOpen всплывающего окна значение false, а для свойства IsChecked кнопки-переключателя была установлена ​​двусторонняя привязка к свойству IsOpen всплывающего окна.

Все хорошо, за исключением одного случая - при установленной кнопке и открытом всплывающем окне нажатие кнопки не приводит к закрытию всплывающего окна или возвращению кнопки в непроверенное состояние.

Я полагаю, что это должно быть потому, что нажатие кнопки заставляет логику StaysOpen всплывающего окна устанавливать для свойства IsOpen всплывающего окна значение false. В свою очередь, это устанавливает Togglebutton на непроверенный. Это должно произойти до того, как будет обработан мой щелчок по кнопке, поэтому щелчок повторно проверяет кнопку, то есть состояние гонки.

Есть идеи, как мне добиться желаемого поведения?

Ответы [ 3 ]

10 голосов
/ 28 апреля 2011

Если ваше предположение верно, вам понадобится специальный класс Popup, например:

public class MyPopup : Popup {
    protected override void OnPreviewMouseLeftButtonDown(MouseButtonEventArgs e) {
        bool isOpen = this.IsOpen;
        base.OnPreviewMouseLeftButtonDown(e);

        if (isOpen && !this.IsOpen)
            e.Handled = true;
    }
}

Возможно, вам придется удалить !this.IsOpen из оператора if.Если вместо этого вы используете MyPopup, это не позволит событию MouseLeftButtonDown достигнуть ToggleButton.

7 голосов
/ 05 ноября 2013

Оба решения выше имеют проблемы.Вот еще одно решение, которое использует обработчики событий вместо привязки, но избегает проблемы потерянных кликов, на которую svick указал с помощью решения MyPopup, и проблем с ClickMode = Press.XAML выглядит так:

<ToggleButton Name="OptionsButton" Checked="OptionsButton_OnChecked" Unchecked="OptionsButton_OnUnchecked" />
<Popup Name="OptionsPopup" StaysOpen="False" Closed="OptionsPopup_OnClosed"/>

И код:

    void OptionsPopup_OnClosed(object sender, EventArgs e)
    {
        if (OptionsButton != Mouse.DirectlyOver)
            OptionsButton.IsChecked = false;
    }

    void OptionsButton_OnChecked(object sender, RoutedEventArgs e)
    {
        OptionsPopup.IsOpen = true;
    }

    void OptionsButton_OnUnchecked(object sender, RoutedEventArgs e)
    {
        OptionsPopup.IsOpen = false;
    }
1 голос
/ 19 ноября 2012

Решение состоит в том, чтобы установить привязку TwoWay между свойством IsOpen всплывающего окна и свойством IsChecked свойства ToggleButton. Затем установите свойство ClickMode длякнопка переключения на Нажмите .Вуаля!

...