开发者

Bind to Caps Lock

开发者 https://www.devze.com 2023-03-29 10:30 出处:网络
I\'m building a login screen in WPF. I\'m trying to figure out how to bind a part of my code to only be visible when the caps lock key is on.

I'm building a login screen in WPF. I'm trying to figure out how to bind a part of my code to only be visible when the caps lock key is on.

<StackPanel Grid.Row="3" Grid.ColumnSpan="2" Grid.Column="1" Orientation="Horizontal">
        <Image Source="../../.开发者_如何学编程./Resources/Icons/109_AllAnnotations_Warning_16x16_72.png" Height="16" Width="16"/>
        <Label>Caps lock is on</Label>
</StackPanel>

I would prefer a solution with xaml binding only.


We're using the following approach in our sign in form to show a 'Caps lock warning' when the password box has focus.

    private void PasswordBox_PreviewKeyDown(object sender, KeyEventArgs e)
    {
        UpdateCapsLockWarning(e.KeyboardDevice);
    }

    private void PasswordBox_GotKeyboardFocus(object sender, KeyboardFocusChangedEventArgs e)
    {
        UpdateCapsLockWarning(e.KeyboardDevice);
    }

    private void PasswordBox_LostKeyboardFocus(object sender, KeyboardFocusChangedEventArgs e)
    {
        CapsLockWarning.Visibility = Visibility.Hidden;
    }

    private void UpdateCapsLockWarning(KeyboardDevice keyboard)
    {
        CapsLockWarning.Visibility = keyboard.IsKeyToggled(Key.CapsLock) ? Visibility.Visible : Visibility.Hidden;
    }

Not the binding-only answer you're looking for though.


Expanding on your xaml:

<Window x:Class="LoginWindow" 
        ... 
        Activated="Window_Activated"
        PreviewKeyDown="Window_PreviewKeyDown">
    ...
    <StackPanel Name="CapsLockOn" Grid.Row="3" Grid.ColumnSpan="2" Grid.Column="1" Orientation="Horizontal">
            <Image Source="../../../Resources/Icons/109_AllAnnotations_Warning_16x16_72.png" Height="16" Width="16"/>
            <Label>Caps lock is on</Label>
    </StackPanel>
    ...
</Window>

Then in code behind:

public partial class LoginWindow : Window
{
    ...

    private void Window_Activated(object sender, EventArgs e)
    {
        SetCapsLockOnState();
    }

    private Window_PreviewKeyDown(object sender, KeyEventArgs e)
    {
        SetCapsLockOnState();
    }

    private void SetCapsLockOnState()
    {
        if (Console.CapsLock)
        {
            CapsLockOn.Visibility.Visible;
        }
        else
        {
            CapsLockOn.Visibility.Hidden;
        }
    }

    ...
}

PreviewKeyDown is a tunneling event. Meaning that the event at the element tree root (ie Window) is called first, before then the event moves along the element tree towards the event source. This is handy as we can detect changes to caps lock state in one place, without any fear that this may be interfered with by other code.

The PreviewKeyDown event only response to changes in caps lock state. You need to call SetCapsLockState() to correctly set the state of SetCapsLockOnState to reflect the caps lock state when the window is created, and if the caps lock state changes when the window doesn't have focus. I have chosen to use the Activated event to cover both of these cases.

0

精彩评论

暂无评论...
验证码 换一张
取 消