【问题标题】:How can I tell when the default textbox context menu is about to open or close?如何判断默认文本框上下文菜单何时打开或关闭?
【发布时间】:2011-04-15 04:38:50
【问题描述】:

如何判断默认文本框上下文菜单何时打开(打开之前)或关闭之后(不是之前,之后)?当我使用标准的内置菜单时,ContextMenuOpening 和 ContextMenuClosing 事件似乎没有触发。我猜我可以简单地重新创建菜单并使用标准命令填充它,但这似乎有点矫枉过正。

具体原因是,我有一个模板化控件,它在“编辑”模式下交换了一个文本框。当文本框失去焦点时,该控件会自动退出编辑模式。问题是当上下文菜单弹出时,文本框失去焦点,从而退出编辑模式,上下文菜单立即消失。

我想要做的是在上下文菜单打开之前,设置一个标志来短路文本框上的 LostFocus 事件代码。然后上下文菜单关闭后,我需要清除该标志,但我还需要检测现在具有焦点的控件是否仍然是文本框,如果不是,则处理代码,就好像它确实失去了焦点。 (或者,如果我知道哪个控件在关闭后 获得焦点,我可以在事件关闭之前对其进行测试。它会达到相同的效果。)

如果有人显示上下文菜单(因此文本框在技术上不再具有焦点)但随后单击 UI 中的其他位置会关闭上下文菜单,则需要处理特定情况,因为我需要检测文本框实际上已经失去焦点,因此控件应该退出编辑模式。但是,如果用户通过在文本框中单击返回来关闭上下文菜单,那么我不希望触发 LostFocus 事件。

有意义吗?

M


更新:从技术上讲,这个问题没有得到回答,尽管我将其标记为这样,因为响应者确实帮助我解决了我的问题。但至于这里的实际问题,答案似乎是“你不能”。

好消息是因为默认的文本框上下文菜单只有三个标准项目,通过将其添加到某处的资源中很容易复制...

<ContextMenu x:Key="DefaultTextBoxContextMenu">
    <MenuItem Command="ApplicationCommands.Cut" />
    <MenuItem Command="ApplicationCommands.Copy" />
    <MenuItem Command="ApplicationCommands.Paste" />
</ContextMenu>

...并像这样附加它...

<TextBox x:Name="EditTextBox"
    ContextMenu="{StaticResource DefaultTextBoxContextMenu}"
    ContextMenuOpening="EditTextBox_ContextMenuOpening"
    ContextMenuClosing="EditTextBox_ContextMenuClosing" />

...然后您的事件按您的预期工作。如果你问我仍然很奇怪,但无论如何都是一个微不足道的解决方法,所以我不会抱怨。

M

【问题讨论】:

  • 谢谢!我目前遇到了同样的问题,这是一个有效的解决方案。

标签: wpf events textbox


【解决方案1】:

当文本框的上下文菜单打开时,文本框失去键盘焦点,但保留逻辑焦点。换句话说,它的 LostKeyboardFocus 事件会触发,但它的 LostFocus 事件不会。当上下文菜单打开时,文本框的 IsFocused 属性保持为真。根据您对问题的描述,您应该能够依靠逻辑焦点来确定何时结束控件中的“编辑模式”。

【讨论】:

  • 欢迎来到 StackOverflow!期待更多精彩的答案。
  • 乔希,我倒读了时间戳。你是“12”,他是“11”,但我忘记了“之前”部分。我已经把答案转给你了!但是,请查看他的 cmets,了解我与此问题相关的其他一些问题。
  • @H.B.糟糕,我不知道“签名中没有链接”规则。我已将其从我的帖子中删除。
  • 嗨@Josh Smith 显然你在 WPF 方面很有名气!不知道你的情况,但正如他们所说,谷歌是我的朋友。所以......在这之间,还有一个类似的问题......@ 987654322@,我已经按照我的回答解决了这个问题。但是......虽然它确实有效,但对我来说似乎'hackish'!就是说,您能对此有所了解吗?有没有更好的办法?再一次,我解释了为什么 LostFocus 和 LostKeyboardFocus 本身都不会给我想要的东西,因此是冗长的解决方案。想法?
【解决方案2】:

默认情况下,TextBox 仍为 IsFocused 报告 true,而默认上下文菜单已打开,但为 IsKeyboardFocused 报告 false。也就是说,LostFocus 在上下文菜单打开时不会在TextBox 上引发,但如果通过选择其他控件关闭上下文菜单,则会引发LostFocus。这听起来正是您正在寻找的行为。

你可以用一个小的测试程序来展示这个默认行为:

<Grid>
    <StackPanel>
        <TextBox Text="Some text one"
                 GotFocus="TextBox_GotFocus"
                 LostFocus="TextBox_LostFocus"/>
        <TextBox Text="Some text two"/>
    </StackPanel>
</Grid>

和代码隐藏:

    private void TextBox_GotFocus(object sender, RoutedEventArgs e)
    {
        Debug.WriteLine("GotFocus");
    }

    private void TextBox_LostFocus(object sender, RoutedEventArgs e)
    {
        Debug.WriteLine("LostFocus");
    }

如果您在大型应用程序的上下文中没有获得此默认行为,则可能存在焦点范围问题干扰。

【讨论】:

  • 啊啊啊!我一直在使用 LostKeyboardFocus,而不是 LostFocus!该死的,这很简单!哈哈!!投票并接受!顺便说一句,你击败了乔希一分钟,所以你得到了答案,但我投票给你们两个。
  • 还有一个问题……如果只是默认的上下文菜单,上下文菜单事件不会触发,我是对的,还是我也遗漏了什么?
  • 我认为他领先我一分钟。你可以把答案转给他!
  • 更重要的是,我有一种使用 IsKeyboardFocusWithin 来设置自身样式的样式(文本框在里面),但是当上下文菜单打开时,由于切换的是键盘焦点,样式会发生变化也。我的解决方法是创建第二种样式,使用控件上的 IsEditing 来处理这种情况,但这对我来说有点不雅。想法?
  • 如果 IsKeyboardFocusWithin 样式很微妙,那么在上下文菜单打开时更改样式也不错。如果它不和谐,那么您需要一些其他状态,而您的 IsEditing 似乎是适合这项工作的工具。
猜你喜欢
  • 1970-01-01
  • 2020-08-10
  • 2021-09-11
  • 2012-11-13
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-05-07
  • 2015-06-24
相关资源
最近更新 更多