2

在 WPF MVVM 环境中,我试图确保将焦点放在 TextBox 上。发生的情况是光标出现在 TextBox 中但没有闪烁,并且 TextBox 没有焦点。代码是:

我有一个包含此 UserControl 的弹出窗口:

<UserControl x:Class="Rendevous.BusinessModules.AdministrationModule.LogonView"
         xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
         xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
         xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" 
         xmlns:d="http://schemas.microsoft.com/expression/blend/2008" 
         mc:Ignorable="d" 
         d:DesignHeight="100" d:DesignWidth="300"
         xmlns:my="clr-namespace:Csla.Xaml;assembly=Csla.Xaml"
         xmlns:ViewModels="clr-namespace:Rendevous.Common.ViewModels;assembly=Common"
         Visibility="{Binding Path=IsViewVisible}"
         FocusManager.FocusedElement="{Binding Path=passCodeTextBox}"
         ViewModels:FocusExtension.IsFocused="{Binding IsPassCodeFocused}">
    <Grid >
        <Grid.ColumnDefinitions>
            <ColumnDefinition Width="Auto" />
            <ColumnDefinition Width="*" />
            <ColumnDefinition Width="auto" />
            <ColumnDefinition Width="auto" />
        </Grid.ColumnDefinitions>
            <Label Grid.Column="0" Content="Pass Code:"
           VerticalAlignment="Center" />
        <TextBox Grid.Column="1" Name="passCodeTextBox" Width="100"
                 VerticalAlignment="Center"
                 Margin="3"
                 Text="{Binding Path=PassCode, UpdateSourceTrigger=PropertyChanged}"
                 ViewModels:FocusExtension.IsFocused="{Binding IsPassCodeFocused}" />
        <Button Grid.Column="2" VerticalAlignment="Center" Margin="3" Name="loginButton"
                Content="Log In" />
        <Button Grid.Column="3"
                VerticalAlignment="Center"
                Margin="3"
                Name="cancelButton"
                Content="Cancel" />
    </Grid>

(我已经删除了一些按钮处理的东西!)

在我的 ViewModel 中,我有如下代码:

    public void LogonButtonClicked(object sender, ExecuteEventArgs e)
    {
        if (securityService.Login(PassCode))
        {
            eventBroker.Invoke(EventName.CloseLogonView, this);
        }
        else
        {
            IsViewVisible = Visibility.Hidden;
            msgService.ShowError("Pass Code was not recognised", "Logon Error");
            IsViewVisible = Visibility.Visible;
            PassCode = "";
            IsPassCodeFocused = true;
        }
    }

我正在使用附加属性:

public class FocusExtension
{
    public static readonly DependencyProperty IsFocusedProperty = DependencyProperty.RegisterAttached("IsFocused", typeof(bool?), typeof(FocusExtension), new FrameworkPropertyMetadata(IsFocusedChanged));
    public static bool? GetIsFocused(DependencyObject element)
    {
        if (element == null)
        {
            throw new ArgumentNullException("element");
        }

        return (bool?)element.GetValue(IsFocusedProperty);
    }

    public static void SetIsFocused(DependencyObject element, bool? value)
    {
        if (element == null)
        {
            throw new ArgumentNullException("element");
        }

        element.SetValue(IsFocusedProperty, value);
    }

    private static void IsFocusedChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
    {
        FrameworkElement fe = (FrameworkElement)d;

        if (e.OldValue == null)
        {
            fe.GotFocus += FrameworkElement_GotFocus;
            fe.LostFocus += FrameworkElement_LostFocus;
        }

        if ((bool)e.NewValue)
        {
            fe.Focus();
        }
    }

    private static void FrameworkElement_GotFocus(object sender, RoutedEventArgs e)
    {
        ((FrameworkElement)sender).SetValue(IsFocusedProperty, true);
    }

    private static void FrameworkElement_LostFocus(object sender, RoutedEventArgs e)
    {
        ((FrameworkElement)sender).SetValue(IsFocusedProperty, false);
    }
}

}

发生的情况是光标出现在 TextBox 中但没有闪烁。TextBox 没有焦点,因为在您键入时没有显示任何内容。如果你点击它,它工作正常。

我做错了什么?

4

1 回答 1

0

我无法使用您提供的代码重现它,但我注意到两件事是:

1) 在 LogonView 上,我认为您的意图是

FocusManager.FocusedElement="{Binding ElementName=passCodeTextBox}"

并不是

FocusManager.FocusedElement="{Binding Path=passCodeTextBox}"

2)看起来 IsFocused 应用在多个地方。我会尝试在 IsFocusedChanged() 中设置断点,看看哪个控件最后得到它。

在这之间,观看FocusManager.FocusedElement ( http://msdn.microsoft.com/en-us/library/system.windows.input.focusmanager.focusedelement.aspx ) 和Keyboard.FocusedElement ( http://msdn.microsoft. com/en-us/library/system.windows.input.keyboard.focusedelement)您应该能够追踪焦点的真正位置。

于 2012-06-20T19:25:01.373 回答