Фокус на WPF TextBox не работает должным образом с прикрепленными свойствами - PullRequest
2 голосов
/ 20 октября 2010

В среде 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 не имеет фокуса, потому что при вводе ничего не появляется. Если вы нажмете на него, он работает нормально.

Что я сделал не так?

1 Ответ

0 голосов
/ 20 июня 2012

Я не смог воспроизвести его, используя предоставленный вами код, но заметил две вещи:

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) вы сможете отслеживать куда действительно направлен фокус.

...