将焦点从Grid / TextBlock切换到TextBox

时间:2017-12-14 01:01:30

标签: c# wpf xaml

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

enter image description here

然而,我遇到的问题是,如果鼠标位于文本块之上,并且我单击,则无法让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>

1 个答案:

答案 0 :(得分:0)

我在阅读this page后想出来了。我不知道为什么这段代码会起作用......就像其实一样。看起来我正在使用向后,迂回的方式进入控件以避免线程问题......这不是Dispatcher的用途吗?因此可以安全地假设.Focus()方法什么也不做,除非它像下面那样使用?不管怎样,我想,现在减少头发拉动,以及更多编码。这是适合我的代码。我所要做的就是将它添加到父网格的MouseDown事件:

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

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