关注 WPF 文本框无法与附加属性一起正常工作

发布于 2024-09-27 21:49:16 字数 4168 浏览 2 评论 0原文

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

我有一个包含此用户控件的弹出窗口:

<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 没有焦点,因为您键入时什么也没有出现。如果你点击它,它就可以正常工作。

我做错了什么?

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:

I have a Popup containing this 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:

    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?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

起风了 2024-10-04 21:49:16

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

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 ( < a href="http://msdn.microsoft.com/en-us/library/system.windows.input.keyboard.focusedelement" rel="nofollow">http://msdn.microsoft.com/en-us/ library/system.windows.input.keyboard.focusedelement )您应该能够追踪焦点真正的去向。

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

and not

FocusManager.FocusedElement="{Binding Path=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.

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.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文