仅在按下某个键组合时,如何将WPF控件的不透明度从0更改为100%?

问题描述

我在一个Button设置为0的视图上有一个Opacity

我正在寻找一种方法,使Button仅在按下某个键组合使其可单击时才会显示(通过使其不透明度= 100%)。假设组合键为LeftShiftLeftCtrl

但是,只要按下任一键,更改:

  1. 除了选择的“组合”之外,还按下另一个
  2. 释放所有键
  3. 释放一些构成“组合”的钥匙

我希望不透明度恢复为0。

我可以通过处理如下的Views Preview..._KeyDown事件来完成工作:

   private void Window_PreviewKeyDown(object sender,KeyEventArgs e)
    {

        if (Keyboard.IsKeyDown(Key.LeftCtrl) && Keyboard.IsKeyDown(Key.LeftShift))
        {
            btn.Opacity = 1;
        }
        else 
        {
            btn.Opacity = 0;
        }

    }

问题是我必须按下另一个键才能将不透明度重置为0;

以下是完整的简单XAML:

<Window x:Class="TestOpacityKeyCombination.MainWindow"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
    xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
    xmlns:local="clr-namespace:TestOpacityKeyCombination"
    mc:Ignorable="d"
    Title="MainWindow" Height="450" Width="800" PreviewKeyDown="Window_PreviewKeyDown">
<Grid>
    <Button Background="Red" Height="100" Width="100"  x:Name="btn" Opacity="0"/> 
</Grid>
</Window>

如何使它按我想要的方式工作?

解决方法

您可以使用PreviewKeyUp事件。

这是您的XAML

<Window x:Class="TestOpacityKeyCombination.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:local="clr-namespace:TestOpacityKeyCombination"
mc:Ignorable="d"
Title="MainWindow" Height="450" Width="800" PreviewKeyDown="Window_PreviewKeyDown" PreviewKeyUp="Window_PreviewKeyUp">
<Grid>
    <Button Background="Red" Height="100" Width="100"  x:Name="btn" Opacity="0"/> 
</Grid>

和C#代码

private void Window_PreviewKeyDown(object sender,KeyEventArgs e)
    {
        if (Keyboard.IsKeyDown(Key.LeftCtrl) && Keyboard.IsKeyDown(Key.LeftShift))
        {
            Menu.Opacity = 1;
            if (IsAnyKeyDown())
            {
                Menu.Opacity = 0;
            }
        }
        else
        {
            Menu.Opacity = 0;
        }
    }

    private void Window_PreviewKeyUp(object sender,KeyEventArgs e)
    {
        //set opacity back to 1 if PressedUp key is not LeftCtrl and LeftShift
        if(!Keyboard.IsKeyUp(Key.LeftCtrl) && !Keyboard.IsKeyUp(Key.LeftShift))
        {
            Menu.Opacity = 1;
            return;
        }
        Menu.Opacity = 0;
    }

    public static bool IsAnyKeyDown()
    {
        var values = Enum.GetValues(typeof(Key));

        foreach (var v in values)
            if (((Key)v) != Key.None && 
                ((Key)v) != Key.LeftCtrl && 
                ((Key)v) != Key.LeftShift && 
                Keyboard.IsKeyDown((Key)v))
                return true;

        return false;
    }
,

只需使用PreviewKeyUp事件来检查释放的密钥是否是有效组合的密钥:

List<Key> validKeys { get; } = new List<Key> {Key.LeftCtrl,Key.LeftShift};

private void Window_PreviewKeyDown(object sender,KeyEventArgs e)
{
  btn.Opacity = 0;

  List<Key> invalidKeys = Enum.GetValues(typeof(Key))
    .Cast<Key>()
    .Except(this.ValidKeys)
    .ToList();
  invalidKeys.Remove(Key.None);

  var keyboardDevice = e.Device as KeyboardDevice;

  // Check if combination is active
  if (this.ValidKeys.All(keyboardDevice.IsKeyDown))
  {
    // Check if additional keys are pressed
    if (invalidKeys.Any(keyboardDevice.IsKeyDown))
    {
      return;
    }

    btn.Opacity = 1;
  }
}

private void Window_PreviewKeyUp(object sender,KeyEventArgs e)
{
  // Check if the combination is invalid
  if (this.ValidKeys.Contains(e.Key))
  {
    btn.Opacity = 0;
  }
}

相关问答

Selenium Web驱动程序和Java。元素在(x,y)点处不可单击。其...
Python-如何使用点“。” 访问字典成员?
Java 字符串是不可变的。到底是什么意思?
Java中的“ final”关键字如何工作?(我仍然可以修改对象。...
“loop:”在Java代码中。这是什么,为什么要编译?
java.lang.ClassNotFoundException:sun.jdbc.odbc.JdbcOdbc...