WPF TextBox MenuItem 在移动鼠标时失去焦点

问题描述 投票:0回答:4

在我的 WPF 应用程序中,我希望菜单项有一个文本框。我已经设法使用以下代码来做到这一点:

<Menu Height="23" HorizontalAlignment="Stretch" Name="MainMenu" VerticalAlignment="Top">
    <MenuItem Header="File">
        <MenuItem Header="Exit" Click="menuItemExit_Click" />
    </MenuItem>
    <MenuItem Header="Settings">
        <MenuItem Header="Some setting" IsCheckable="True" />
        <Separator />
        <MenuItem>
            <MenuItem.Header>
                <Grid>
                    <Grid.ColumnDefinitions>
                        <ColumnDefinition Width="Auto" />
                        <ColumnDefinition />
                    </Grid.ColumnDefinitions>
                    <Label Content="Some value:" Margin="0,3,6,0" Padding="0" />
                    <TextBox Margin="0,0,0,6" Grid.Column="1" />
                </Grid>
            </MenuItem.Header>
        </MenuItem>
    </MenuItem>
</Menu>

此代码按我的预期显示菜单项,但如果我开始在文本框中输入一些值,然后将鼠标(而不是单击)移离文本框菜单项,则文本框将失去焦点,并且我无法继续输入,直到我再次单击文本框。如何实现与 WinForms 中的文本框菜单项相同的行为?也就是说,只有当用户在文本框外部单击或按 Tab 键时,文本框才会失去焦点。

提前致谢。

wpf textbox menuitem lost-focus
4个回答
7
投票

正如我所写,我不确定您如何使用菜单控件。 但也许这段代码可以帮助你或给你一个提示:

<TextBox Margin="0,0,0,6" Grid.Column="1" PreviewLostKeyboardFocus="OnPreviewLostKeyboardFocus"/>

以及相应的方法:

private void OnPreviewLostKeyboardFocus(object sender, KeyboardFocusChangedEventArgs e)
  {
     if (MainMenu.IsKeyboardFocusWithin)
     {
        e.Handled = true;
     }
  }

2
投票

我知道这个答案可能为时已晚,无法帮助您,但也许它会帮助任何寻找此问题解决方案的人。

在菜单项上设置

Focusable=false

 也可以。  它仍然允许单击它们并允许它们包含的控件获得焦点。  但是,它禁用了仅使用键盘导航菜单的功能,从而引入了可访问性问题。

可访问性问题可以通过一点创意来解决,方法是为每个菜单项提供一个可聚焦的元素。 例如:

<MenuItem Focusable="False"> <MenuItem.Header> <StackPanel Orientation="Horizontal" Focusable="True" FocusVisualStyle="{x:Null}"> <TextBlock Text="Do something!" /> </StackPanel> </MenuItem.Header> </MenuItem>

需要

FocusVisualStyle="{x:Null}"

 代码来隐藏否则会出现的虚线焦点(并且在菜单中看起来不合适)。


0
投票
也许这有帮助:

<MenuItem StaysOpenOnClick="True"> <MenuItem.Header> <Grid> <Grid.ColumnDefinitions> <ColumnDefinition Width="Auto" /> <ColumnDefinition /> </Grid.ColumnDefinitions> <Label Content="Some value:" Margin="0,3,6,0" Padding="0" /> <TextBox Margin="0,0,0,6" Grid.Column="1" /> </Grid> </MenuItem.Header> </MenuItem>
    

0
投票
自定义

ComboBox

 项目也面临同样的问题。在我的例子中,这个问题的根本原因是 
ComboBoxItem
 事件的 
MouseEnter
 处理程序:

e.Handled = true; this.ParentComboBox?.NotifyComboBoxItemEnter(this); base.OnMouseEnter(e);
而且

NotifyComboBoxItemEnter

看起来像

if (!this.IsDropDownOpen || Mouse.Captured != this || !this.DidMouseMove()) return; this.HighlightedInfo = this.ItemInfoFromContainer((DependencyObject) item); if (this.IsEditable || item.IsKeyboardFocusWithin) return; item.Focus();
所以它确实将焦点集中在鼠标输入上。我怀疑菜单项中可能有类似的东西(例如扩展子菜单)。

我通过重写自定义组合框项类上的

OnMouseEnter

 来避免调用基本方法解决了这个问题。

接受的解决方案有效,但会阻止键盘导航。

© www.soinside.com 2019 - 2024. All rights reserved.