10

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

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

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

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

知道如何获得我想要的行为吗?

4

3 回答 3

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;
    }
}

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

于 2011-04-28T16:20:52.140 回答
7

上述两种解决方案都有问题。这是另一个使用事件处理程序而不是绑定的解决方案,但确实避免了 svick 在 MyPopup 解决方案中指出的单击丢失问题以及 ClickMode=Press 的问题。xml 看起来像:

<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;
    }
于 2013-11-05T14:26:46.963 回答
1

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

于 2012-11-19T10:28:03.420 回答