问题描述
我正在寻找一种方法,使Button
仅在按下某个键组合使其可单击时才会显示(通过使其不透明度= 100%)。假设组合键为LeftShift
和LeftCtrl
。
但是,只要按下任一键,更改:
- 除了选择的“组合”之外,还按下另一个键
- 释放所有键
- 释放一些构成“组合”的钥匙
我希望不透明度恢复为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;
}
}