【问题标题】:Switching Focus from Grid/TextBlock to TextBox将焦点从 Grid/TextBlock 切换到 TextBox
【发布时间】:2018-05-28 00:22:15
【问题描述】:

我正在制作一个数字文本框,它还可以包含各种附加符号,以表示控件中包含的数据是否为百分位数、半径等。为此,我有一个网格,左侧有一个文本框,还有一个右侧的文本块。这是一张图片:

然而,我遇到的问题是,如果鼠标悬停在文本块上,然后单击,我无法让 TextBox 获得焦点。我已经在文本块的鼠标按下以及父网格上尝试了_textbox.Focus()。这不起作用。

经过一番谷歌搜索,我读到我可以将FocusManager.FocusedElement="{Binding ElementName=_textbox}" 放在父网格上,这将解决我的问题。但是,即使这样,文本框仍然没有获得焦点。我什至尝试过使文本框或文本块都不可命中测试,而是使用网格本身作为命中测试,但即使这样,文本框本身仍然不会获得焦点。我不知道该怎么做。 有谁知道当点击父网格或点击文本块时如何使文本框获得焦点?还是两者都有?

这是我的 XAML:

<UserControl
    x:Class="VoidwalkerEngine.Editor.Controls.NumericTextBox"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
    xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
    Height="32"
    d:DesignWidth="80"
    BorderThickness="0"
    mc:Ignorable="d">
    <UserControl.Resources>
        <Style x:Key="ButtonTop" TargetType="Button">
            <Setter Property="Background" Value="White" />
            <Setter Property="TextBlock.TextAlignment" Value="Center" />
            <Setter Property="Template">
                <Setter.Value>
                    <ControlTemplate TargetType="Button">
                        <Border
                            x:Name="ButtonBackground"
                            Background="{DynamicResource Voidwalker_Gradient_Button}"
                            BorderBrush="{DynamicResource Voidwalker_Brush_Border}"
                            BorderThickness="1,0,0,1"
                            CornerRadius="0,2,0,0">
                            <ContentPresenter
                                x:Name="contentPresenter"
                                Margin="{TemplateBinding Padding}"
                                HorizontalAlignment="{TemplateBinding HorizontalContentAlignment}"
                                VerticalAlignment="{TemplateBinding VerticalContentAlignment}"
                                Content="{TemplateBinding Content}"
                                ContentTemplate="{TemplateBinding ContentTemplate}" />
                        </Border>
                        <ControlTemplate.Triggers>
                            <Trigger Property="IsMouseOver" Value="True">
                                <Setter TargetName="ButtonBackground" Property="Background" Value="{DynamicResource Voidwalker_Gradient_ButtonPressed}" />
                            </Trigger>
                            <Trigger Property="IsPressed" Value="True">
                                <Setter TargetName="ButtonBackground" Property="Background" Value="{DynamicResource VoidwalkerButtonBrush}" />
                            </Trigger>
                        </ControlTemplate.Triggers>
                    </ControlTemplate>
                </Setter.Value>
            </Setter>
        </Style>
        <Style x:Key="ButtonBottom" TargetType="Button">
            <Setter Property="Background" Value="White" />
            <Setter Property="TextBlock.TextAlignment" Value="Center" />
            <Setter Property="Template">
                <Setter.Value>
                    <ControlTemplate TargetType="Button">
                        <Border
                            x:Name="ButtonBackground"
                            Background="{DynamicResource Voidwalker_Gradient_Button}"
                            BorderBrush="{DynamicResource Voidwalker_Brush_Border}"
                            BorderThickness="1,1,0,0"
                            CornerRadius="0,0,2,0">
                            <ContentPresenter
                                x:Name="contentPresenter"
                                Margin="{TemplateBinding Padding}"
                                HorizontalAlignment="{TemplateBinding HorizontalContentAlignment}"
                                VerticalAlignment="{TemplateBinding VerticalContentAlignment}"
                                Content="{TemplateBinding Content}"
                                ContentTemplate="{TemplateBinding ContentTemplate}" />
                        </Border>
                        <ControlTemplate.Triggers>
                            <Trigger Property="IsMouseOver" Value="True">
                                <Setter TargetName="ButtonBackground" Property="Background" Value="{DynamicResource Voidwalker_Gradient_ButtonPressed}" />
                            </Trigger>
                            <Trigger Property="IsPressed" Value="True">
                                <Setter TargetName="ButtonBackground" Property="Background" Value="{DynamicResource VoidwalkerButtonBrush}" />
                            </Trigger>
                        </ControlTemplate.Triggers>
                    </ControlTemplate>
                </Setter.Value>
            </Setter>
        </Style>
    </UserControl.Resources>
    <Border
        Background="{DynamicResource Voidwalker_Brush_ContextArea}"
        BorderBrush="{DynamicResource Voidwalker_Brush_Border}"
        BorderThickness="1"
        CornerRadius="3">
        <Grid Focusable="False">
            <Grid.ColumnDefinitions>
                <ColumnDefinition />
                <ColumnDefinition Width="23" />
            </Grid.ColumnDefinitions>
            <Grid.RowDefinitions>
                <RowDefinition />
                <RowDefinition />
            </Grid.RowDefinitions>
            <Border
                Grid.Row="0"
                Grid.RowSpan="2"
                Grid.Column="0"
                BorderThickness="0"
                CornerRadius="2,0,0,2">
                <Grid
                    Cursor="IBeam"
                    FocusManager.FocusedElement="{Binding ElementName=_textbox}"
                    MouseDown="_backAreaGrid_OnClick">
                    <Grid.ColumnDefinitions>
                        <ColumnDefinition Width="50*" />
                        <ColumnDefinition Width="50*" />
                    </Grid.ColumnDefinitions>
                    <TextBox
                        x:Name="_textbox"
                        Grid.Column="0"
                        Margin="0"
                        HorizontalAlignment="Stretch"
                        VerticalAlignment="Center"
                        VerticalContentAlignment="Center"
                        Background="{DynamicResource VoidwalkerContextBrush}"
                        BorderThickness="0"
                        CommandManager.PreviewExecuted="_numericDisplayTextBox_OnPreviewExecuted"
                        Foreground="{DynamicResource Voidwalker_Brush_ActiveTextForeground}"
                        GotFocus="_textbox_OnGotFocus"
                        LostFocus="_numericDisplayTextBox_OnLostFocus"
                        MouseDoubleClick="_textbox_OnMouseDoubleClick"
                        PreviewKeyDown="_numericDisplayTextBox_OnPreviewKeyDown"
                        PreviewMouseWheel="_numericDisplayTextBox_OnPreviewMouseWheel"
                        Text="0"
                        TextAlignment="Right"
                        TextChanged="_numericDisplayTextBox_OnTextChanged" />
                    <TextBlock
                        x:Name="OperatorDisplayTextBox"
                        Grid.Column="1"
                        VerticalAlignment="Center"
                        Cursor="IBeam"
                        Foreground="{DynamicResource Voidwalker_Brush_ActiveTextForeground}"
                        Text="%" />
                </Grid>

            </Border>

            <Button
                Grid.Row="0"
                Grid.Column="1"
                BorderThickness="1,0,0,0"
                Click="Increment_Button_OnClick"
                Style="{DynamicResource ButtonTop}">
                <Path Data="M 1,4.5  L 4.5,1  L 8,4.5" Fill="{DynamicResource Voidwalker_Brush_ActiveTextForeground}" />
            </Button>
            <Button
                Grid.Row="1"
                Grid.Column="1"
                BorderThickness="1,0,0,0"
                Click="Decrement_Button_OnClick"
                Style="{DynamicResource ButtonBottom}">
                <Path
                    ClipToBounds="True"
                    Data="M 1,1.5 L 4.5,5 L 8,1.5"
                    Fill="{DynamicResource Voidwalker_Brush_ActiveTextForeground}" />
            </Button>
        </Grid>
    </Border>
</UserControl>

【问题讨论】:

  • 另外,我已经完全清除了代码隐藏,在尝试解决这个困境时徒劳无功,所以我确定这个问题不是由于任何原因造成的。
  • 应该注意的是,我最初尝试只使用一个只接受数字和附加符号的文本框,但这确实是一个 clusterf**k。它有效,但我想以不同的方式来做,这就是我现在向你展示的。

标签: c# wpf xaml


【解决方案1】:

我在阅读this page 后发现了这一点。我不知道为什么这段代码可以工作……实际上,就像。似乎我正在使用一种向后的、迂回的方式进入控件以避免线程问题……这不是 Dispatcher 的用途吗?那么假设一个 .Focus() 方法什么都不做,除非它像下面这样使用它是安全的吗?无论如何,我想,现在少拉头发,多编码。这是对我有用的代码。我所要做的就是将它添加到父网格的 MouseDown 事件中:

        private void _backAreaGrid_OnMouseDown(object sender, MouseButtonEventArgs e)
        {
            Dispatcher.BeginInvoke(
                DispatcherPriority.ContextIdle,
                new Action(delegate
                {
                    _textbox.Focus();
                }));
        }

无论我在周围的网格中单击什么,文本框都会获得焦点。

【讨论】:

    猜你喜欢
    • 2022-07-09
    • 2018-09-02
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-11-02
    相关资源
    最近更新 更多