关注WPF文本框对附加属性不能正常工作

时间:2022-09-09 14:12:50

In WPF MVVM environment, I'm trying to ensure that focus is given to a TextBox. What happens is that the Cursor appears in the TextBox but is not flashing and the TextBox does not have focus. The code is:

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

I have a Popup containing this UserControl:

我有一个包含这个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>

(I've removed some Button handling stuff!)

(我去掉了一些按钮处理的东西!)

In my ViewModel, I have code like:

在我的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;
        }
    }

I am using an attached property:

我正在使用附属物:

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);
    }
}

}

}

What happens is that the cursor appears in the TextBox but is not flashing. The TextBox does not have focus because nothing appears when you type. If you click on it, it works fine.

会发生的是,光标出现在文本框中,但并没有闪烁。文本框没有焦点,因为您输入时什么也没有出现。如果你点击它,它可以正常工作。

What have I done wrong?

我做错了什么?

1 个解决方案

#1


0  

I couldn't reproduce it using the code you provided, but two things I noticed are:

我无法用你提供的代码复制它,但我注意到两件事:

1) On LogonView, I think your intent was

登录后,我认为你的意图是

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

FocusManager。FocusedElement = " {绑定ElementName = passCodeTextBox } "

and not

而不是

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

FocusManager。FocusedElement = " {绑定路径= passCodeTextBox } "

2) It looks like IsFocused is applied in multiple places. I'd try setting a breakpoint in IsFocusedChanged() and see which control gets it last.

看起来isfocus在很多地方都有应用。我将尝试在IsFocusedChanged()中设置断点,并查看哪个控件最后得到它。

Between that, and watching FocusManager.FocusedElement ( http://msdn.microsoft.com/en-us/library/system.windows.input.focusmanager.focusedelement.aspx ) and Keyboard.FocusedElement ( http://msdn.microsoft.com/en-us/library/system.windows.input.keyboard.focusedelement ) you should be able to track down where focus is really going.

在这之间,并观看FocusManager。FocusedElement (http://msdn.microsoft.com/en- us/library/system.windows.input.focusmanagement.focusedelement.aspx)和键盘。FocusedElement (http://msdn.microsoft.com/en-us/library/system.windows.input.keyboard.focusedelement)您应该能够跟踪焦点真正在哪里。

#1


0  

I couldn't reproduce it using the code you provided, but two things I noticed are:

我无法用你提供的代码复制它,但我注意到两件事:

1) On LogonView, I think your intent was

登录后,我认为你的意图是

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

FocusManager。FocusedElement = " {绑定ElementName = passCodeTextBox } "

and not

而不是

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

FocusManager。FocusedElement = " {绑定路径= passCodeTextBox } "

2) It looks like IsFocused is applied in multiple places. I'd try setting a breakpoint in IsFocusedChanged() and see which control gets it last.

看起来isfocus在很多地方都有应用。我将尝试在IsFocusedChanged()中设置断点,并查看哪个控件最后得到它。

Between that, and watching FocusManager.FocusedElement ( http://msdn.microsoft.com/en-us/library/system.windows.input.focusmanager.focusedelement.aspx ) and Keyboard.FocusedElement ( http://msdn.microsoft.com/en-us/library/system.windows.input.keyboard.focusedelement ) you should be able to track down where focus is really going.

在这之间,并观看FocusManager。FocusedElement (http://msdn.microsoft.com/en- us/library/system.windows.input.focusmanagement.focusedelement.aspx)和键盘。FocusedElement (http://msdn.microsoft.com/en-us/library/system.windows.input.keyboard.focusedelement)您应该能够跟踪焦点真正在哪里。