专注于WPF TextBox无法正常使用附加属性

时间:2010-10-20 07:19:30

标签: wpf attached-properties setfocus

在WPF MVVM环境中,我正在尝试确保将焦点放在TextBox上。会发生什么是Cursor出现在TextBox中但没有闪烁,TextBox没有焦点。代码是:

我有一个包含此UserControl的Popup:

<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>

(我删除了一些Button处理的东西!)

在我的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没有焦点,因为键入时没有任何内容。如果你点击它,它可以正常工作。

我做错了什么?

1 个答案:

答案 0 :(得分: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),您应该能够追踪到焦点在哪里。