wpf中的Popup和Togglebutton交互

时间:2011-04-28 16:12:29

标签: wpf binding popup togglebutton

我有一个包含Togglebutton和Popup的控件。单击ToggleButton时,将显示弹出窗口。取消选中ToggleButton时,弹出窗口应该关闭。此外,单击远离弹出窗口会导致它关闭,并导致Togglebutton取消选中。

我通过将Popup的StaysOpen属性设置为false并将切换按钮的IsChecked属性设置为与Popup的IsOpen属性双向绑定来设置它。

一切都很好,除了一个案例 - 选中按钮并弹出窗口,单击按钮不会导致弹出窗口关闭,或者按钮返回未选中状态。

我相信这一定是因为单击该按钮会导致Popup的StaysOpen逻辑将Popup的IsOpen属性设置为false。反过来,这会将Togglebutton设置为未选中状态。这必须在我点击按钮处理之前发生 - 所以点击会重新检查按钮,即竞争条件。

知道我怎么能得到我想要的行为吗?

3 个答案:

答案 0 :(得分:10)

如果您的假设是正确的,您需要一个自定义的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;
    }
}

您可能需要从if语句中删除!this.IsOpen。如果您使用MyPopup,它将阻止MouseLeftButtonDown事件到达ToggleButton。

答案 1 :(得分:7)

上述两种解决方案都存在问题。这是使用事件处理程序而不是绑定的另一种解决方案,但确实避免了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;
    }

答案 2 :(得分:1)

解决方案是在Popup的 IsOpen 属性和ToggleButton的 IsChecked 属性之间设置TwoWay绑定 - 然后设置 ClickMode ToggleButton的属性为。瞧!