mirror of
https://github.com/microsoft/PowerToys.git
synced 2025-12-16 19:57:57 +01:00
[Hosts] Add Keyboard Shortcuts (#26019)
* added keyboard shortcuts * use x:Bind
This commit is contained in:
committed by
GitHub
parent
4d5152f78a
commit
d426d9afde
@@ -3,7 +3,6 @@
|
|||||||
// See the LICENSE file in the project root for more information.
|
// See the LICENSE file in the project root for more information.
|
||||||
|
|
||||||
using Hosts.Helpers;
|
using Hosts.Helpers;
|
||||||
using Microsoft.UI.Windowing;
|
|
||||||
using WinUIEx;
|
using WinUIEx;
|
||||||
|
|
||||||
namespace Hosts
|
namespace Hosts
|
||||||
|
|||||||
@@ -132,6 +132,9 @@
|
|||||||
<data name="AddEntryBtn.[using:Microsoft.UI.Xaml.Automation]AutomationProperties.Name" xml:space="preserve">
|
<data name="AddEntryBtn.[using:Microsoft.UI.Xaml.Automation]AutomationProperties.Name" xml:space="preserve">
|
||||||
<value>New entry</value>
|
<value>New entry</value>
|
||||||
</data>
|
</data>
|
||||||
|
<data name="AddEntryBtn.[using:Microsoft.UI.Xaml.Controls]ToolTipService.ToolTip" xml:space="preserve">
|
||||||
|
<value>New entry (CTRL+N)</value>
|
||||||
|
</data>
|
||||||
<data name="AdditionalLinesBtn.[using:Microsoft.UI.Xaml.Automation]AutomationProperties.Name" xml:space="preserve">
|
<data name="AdditionalLinesBtn.[using:Microsoft.UI.Xaml.Automation]AutomationProperties.Name" xml:space="preserve">
|
||||||
<value>Additional content</value>
|
<value>Additional content</value>
|
||||||
</data>
|
</data>
|
||||||
@@ -187,6 +190,9 @@
|
|||||||
<data name="DuplicateEntryIcon.[using:Microsoft.UI.Xaml.Controls]ToolTipService.ToolTip" xml:space="preserve">
|
<data name="DuplicateEntryIcon.[using:Microsoft.UI.Xaml.Controls]ToolTipService.ToolTip" xml:space="preserve">
|
||||||
<value>Duplicate entry</value>
|
<value>Duplicate entry</value>
|
||||||
</data>
|
</data>
|
||||||
|
<data name="Edit.Text" xml:space="preserve">
|
||||||
|
<value>Edit</value>
|
||||||
|
</data>
|
||||||
<data name="Entries.[using:Microsoft.UI.Xaml.Automation]AutomationProperties.Name" xml:space="preserve">
|
<data name="Entries.[using:Microsoft.UI.Xaml.Automation]AutomationProperties.Name" xml:space="preserve">
|
||||||
<value>Entries</value>
|
<value>Entries</value>
|
||||||
</data>
|
</data>
|
||||||
|
|||||||
@@ -56,6 +56,11 @@
|
|||||||
Glyph="" />
|
Glyph="" />
|
||||||
<TextBlock x:Uid="AddEntry" />
|
<TextBlock x:Uid="AddEntry" />
|
||||||
</StackPanel>
|
</StackPanel>
|
||||||
|
<Button.KeyboardAccelerators>
|
||||||
|
<KeyboardAccelerator
|
||||||
|
Modifiers="Control"
|
||||||
|
Key="N" />
|
||||||
|
</Button.KeyboardAccelerators>
|
||||||
</Button>
|
</Button>
|
||||||
|
|
||||||
<StackPanel
|
<StackPanel
|
||||||
@@ -195,8 +200,10 @@
|
|||||||
CornerRadius="8"
|
CornerRadius="8"
|
||||||
IsItemClickEnabled="True"
|
IsItemClickEnabled="True"
|
||||||
ItemClick="Entries_ItemClick"
|
ItemClick="Entries_ItemClick"
|
||||||
ItemsSource="{Binding Entries, Mode=TwoWay}"
|
KeyDown="Entries_KeyDown"
|
||||||
SelectedItem="{Binding Selected, Mode=TwoWay}"
|
GotFocus="Entries_GotFocus"
|
||||||
|
ItemsSource="{x:Bind ViewModel.Entries, Mode=TwoWay}"
|
||||||
|
SelectedItem="{x:Bind ViewModel.Selected, Mode=TwoWay}"
|
||||||
Visibility="{x:Bind ViewModel.IsLoading, Converter={StaticResource BoolToInvertedVisibilityConverter}, Mode=OneWay}">
|
Visibility="{x:Bind ViewModel.IsLoading, Converter={StaticResource BoolToInvertedVisibilityConverter}, Mode=OneWay}">
|
||||||
<ListView.ItemTemplate>
|
<ListView.ItemTemplate>
|
||||||
<DataTemplate x:DataType="models:Entry">
|
<DataTemplate x:DataType="models:Entry">
|
||||||
@@ -213,11 +220,27 @@
|
|||||||
<ColumnDefinition Width="Auto" />
|
<ColumnDefinition Width="Auto" />
|
||||||
</Grid.ColumnDefinitions>
|
</Grid.ColumnDefinitions>
|
||||||
<FlyoutBase.AttachedFlyout>
|
<FlyoutBase.AttachedFlyout>
|
||||||
<MenuFlyout>
|
<MenuFlyout Opened="MenuFlyout_Opened">
|
||||||
|
<MenuFlyoutItem
|
||||||
|
x:Uid="Edit"
|
||||||
|
Click="Edit_Click"
|
||||||
|
Icon="Edit">
|
||||||
|
<MenuFlyoutItem.KeyboardAccelerators>
|
||||||
|
<KeyboardAccelerator
|
||||||
|
Modifiers="Control"
|
||||||
|
Key="E" />
|
||||||
|
</MenuFlyoutItem.KeyboardAccelerators>
|
||||||
|
</MenuFlyoutItem>
|
||||||
<MenuFlyoutItem
|
<MenuFlyoutItem
|
||||||
x:Uid="Ping"
|
x:Uid="Ping"
|
||||||
Click="Ping_Click"
|
Click="Ping_Click"
|
||||||
Icon="TwoBars" />
|
Icon="TwoBars">
|
||||||
|
<MenuFlyoutItem.KeyboardAccelerators>
|
||||||
|
<KeyboardAccelerator
|
||||||
|
Modifiers="Control"
|
||||||
|
Key="P" />
|
||||||
|
</MenuFlyoutItem.KeyboardAccelerators>
|
||||||
|
</MenuFlyoutItem>
|
||||||
<MenuFlyoutItem
|
<MenuFlyoutItem
|
||||||
x:Uid="MoveUp"
|
x:Uid="MoveUp"
|
||||||
Click="ReorderButtonUp_Click"
|
Click="ReorderButtonUp_Click"
|
||||||
@@ -238,7 +261,11 @@
|
|||||||
<MenuFlyoutItem
|
<MenuFlyoutItem
|
||||||
x:Uid="Delete"
|
x:Uid="Delete"
|
||||||
Click="Delete_Click"
|
Click="Delete_Click"
|
||||||
Icon="Delete" />
|
Icon="Delete">
|
||||||
|
<MenuFlyoutItem.KeyboardAccelerators>
|
||||||
|
<KeyboardAccelerator Key="Delete" />
|
||||||
|
</MenuFlyoutItem.KeyboardAccelerators>
|
||||||
|
</MenuFlyoutItem>
|
||||||
</MenuFlyout>
|
</MenuFlyout>
|
||||||
</FlyoutBase.AttachedFlyout>
|
</FlyoutBase.AttachedFlyout>
|
||||||
<TextBlock
|
<TextBlock
|
||||||
@@ -346,7 +373,7 @@
|
|||||||
x:Name="EntryDialog"
|
x:Name="EntryDialog"
|
||||||
x:Uid="EntryDialog"
|
x:Uid="EntryDialog"
|
||||||
Loaded="ContentDialog_Loaded_ApplyMargin"
|
Loaded="ContentDialog_Loaded_ApplyMargin"
|
||||||
IsPrimaryButtonEnabled="{Binding Valid, Mode=TwoWay}"
|
IsPrimaryButtonEnabled="{Binding Valid, Mode=OneWay}"
|
||||||
PrimaryButtonStyle="{StaticResource AccentButtonStyle}">
|
PrimaryButtonStyle="{StaticResource AccentButtonStyle}">
|
||||||
<ContentDialog.DataContext>
|
<ContentDialog.DataContext>
|
||||||
<models:Entry />
|
<models:Entry />
|
||||||
|
|||||||
@@ -3,6 +3,7 @@
|
|||||||
// See the LICENSE file in the project root for more information.
|
// See the LICENSE file in the project root for more information.
|
||||||
|
|
||||||
using System;
|
using System;
|
||||||
|
using System.Linq;
|
||||||
using System.Threading.Tasks;
|
using System.Threading.Tasks;
|
||||||
using System.Windows.Input;
|
using System.Windows.Input;
|
||||||
using CommunityToolkit.Mvvm.Input;
|
using CommunityToolkit.Mvvm.Input;
|
||||||
@@ -15,6 +16,8 @@ using Microsoft.UI.Xaml.Controls;
|
|||||||
using Microsoft.UI.Xaml.Controls.Primitives;
|
using Microsoft.UI.Xaml.Controls.Primitives;
|
||||||
using Microsoft.UI.Xaml.Input;
|
using Microsoft.UI.Xaml.Input;
|
||||||
using Windows.ApplicationModel.Resources;
|
using Windows.ApplicationModel.Resources;
|
||||||
|
using Windows.System;
|
||||||
|
using Windows.UI.Core;
|
||||||
|
|
||||||
namespace Hosts.Views
|
namespace Hosts.Views
|
||||||
{
|
{
|
||||||
@@ -60,9 +63,14 @@ namespace Hosts.Views
|
|||||||
}
|
}
|
||||||
|
|
||||||
private async void Entries_ItemClick(object sender, ItemClickEventArgs e)
|
private async void Entries_ItemClick(object sender, ItemClickEventArgs e)
|
||||||
|
{
|
||||||
|
await ShowEditDialogAsync(e.ClickedItem as Entry);
|
||||||
|
}
|
||||||
|
|
||||||
|
public async Task ShowEditDialogAsync(Entry entry)
|
||||||
{
|
{
|
||||||
var resourceLoader = ResourceLoader.GetForViewIndependentUse();
|
var resourceLoader = ResourceLoader.GetForViewIndependentUse();
|
||||||
ViewModel.Selected = e.ClickedItem as Entry;
|
ViewModel.Selected = entry;
|
||||||
EntryDialog.Title = resourceLoader.GetString("UpdateEntry_Title");
|
EntryDialog.Title = resourceLoader.GetString("UpdateEntry_Title");
|
||||||
EntryDialog.PrimaryButtonText = resourceLoader.GetString("UpdateBtn");
|
EntryDialog.PrimaryButtonText = resourceLoader.GetString("UpdateBtn");
|
||||||
EntryDialog.PrimaryButtonCommand = UpdateCommand;
|
EntryDialog.PrimaryButtonCommand = UpdateCommand;
|
||||||
@@ -111,21 +119,40 @@ namespace Hosts.Views
|
|||||||
|
|
||||||
if (menuFlyoutItem != null)
|
if (menuFlyoutItem != null)
|
||||||
{
|
{
|
||||||
var selectedEntry = menuFlyoutItem.DataContext as Entry;
|
await ShowDeleteDialogAsync(menuFlyoutItem.DataContext as Entry);
|
||||||
ViewModel.Selected = selectedEntry;
|
|
||||||
DeleteDialog.Title = selectedEntry.Address;
|
|
||||||
await DeleteDialog.ShowAsync();
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public async Task ShowDeleteDialogAsync(Entry entry)
|
||||||
|
{
|
||||||
|
ViewModel.Selected = entry;
|
||||||
|
DeleteDialog.Title = entry.Address;
|
||||||
|
await DeleteDialog.ShowAsync();
|
||||||
|
}
|
||||||
|
|
||||||
private async void Ping_Click(object sender, RoutedEventArgs e)
|
private async void Ping_Click(object sender, RoutedEventArgs e)
|
||||||
{
|
{
|
||||||
var menuFlyoutItem = sender as MenuFlyoutItem;
|
var menuFlyoutItem = sender as MenuFlyoutItem;
|
||||||
|
|
||||||
if (menuFlyoutItem != null)
|
if (menuFlyoutItem != null)
|
||||||
{
|
{
|
||||||
ViewModel.Selected = menuFlyoutItem.DataContext as Entry;
|
await PingAsync(menuFlyoutItem.DataContext as Entry);
|
||||||
await ViewModel.PingSelectedAsync();
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private async Task PingAsync(Entry entry)
|
||||||
|
{
|
||||||
|
ViewModel.Selected = entry;
|
||||||
|
await ViewModel.PingSelectedAsync();
|
||||||
|
}
|
||||||
|
|
||||||
|
private async void Edit_Click(object sender, RoutedEventArgs e)
|
||||||
|
{
|
||||||
|
var menuFlyoutItem = sender as MenuFlyoutItem;
|
||||||
|
|
||||||
|
if (menuFlyoutItem != null)
|
||||||
|
{
|
||||||
|
await ShowEditDialogAsync(menuFlyoutItem.DataContext as Entry);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -197,5 +224,56 @@ namespace Hosts.Views
|
|||||||
Logger.LogError("Couldn't set the margin for a content dialog. It will appear on top of the title bar.", ex);
|
Logger.LogError("Couldn't set the margin for a content dialog. It will appear on top of the title bar.", ex);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Handle the keyboard shortcuts at list view level since
|
||||||
|
/// KeyboardAccelerators in FlyoutBase.AttachedFlyout works only when the flyout is open
|
||||||
|
/// </summary>
|
||||||
|
private async void Entries_KeyDown(object sender, KeyRoutedEventArgs e)
|
||||||
|
{
|
||||||
|
var listView = sender as ListView;
|
||||||
|
if (listView != null && e.KeyStatus.WasKeyDown == false)
|
||||||
|
{
|
||||||
|
var entry = listView.SelectedItem as Entry;
|
||||||
|
|
||||||
|
if (Microsoft.UI.Input.InputKeyboardSource.GetKeyStateForCurrentThread(VirtualKey.Control).HasFlag(CoreVirtualKeyStates.Down))
|
||||||
|
{
|
||||||
|
if (e.Key == VirtualKey.E)
|
||||||
|
{
|
||||||
|
await ShowEditDialogAsync(entry);
|
||||||
|
}
|
||||||
|
else if (e.Key == VirtualKey.P)
|
||||||
|
{
|
||||||
|
await PingAsync(entry);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if (e.Key == VirtualKey.Delete)
|
||||||
|
{
|
||||||
|
await ShowDeleteDialogAsync(entry);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Focus the first item when the list view gets the focus with keyboard
|
||||||
|
/// </summary>
|
||||||
|
private void Entries_GotFocus(object sender, RoutedEventArgs e)
|
||||||
|
{
|
||||||
|
var listView = sender as ListView;
|
||||||
|
if (listView.SelectedItem == null && listView.Items.Count > 0)
|
||||||
|
{
|
||||||
|
listView.SelectedIndex = 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void MenuFlyout_Opened(object sender, object e)
|
||||||
|
{
|
||||||
|
// Focus the first item: required for workaround https://github.com/microsoft/PowerToys/issues/21263
|
||||||
|
var menuFlyout = sender as MenuFlyout;
|
||||||
|
if (menuFlyout != null && menuFlyout.Items.Count > 0)
|
||||||
|
{
|
||||||
|
menuFlyout.Items.First().Focus(FocusState.Programmatic);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user