mirror of
https://github.com/microsoft/PowerToys.git
synced 2026-02-23 19:49:43 +01:00
Wire it up to the UI, painfully, but it works
This commit is contained in:
@@ -0,0 +1,307 @@
|
||||
// Copyright (c) Microsoft Corporation
|
||||
// The Microsoft Corporation licenses this file to you under the MIT license.
|
||||
// See the LICENSE file in the project root for more information.
|
||||
|
||||
using System.Collections.ObjectModel;
|
||||
using Microsoft.CmdPal.Core.ViewModels.Models;
|
||||
using Microsoft.CommandPalette.Extensions;
|
||||
using Microsoft.CommandPalette.Extensions.Toolkit;
|
||||
using Windows.Foundation;
|
||||
|
||||
namespace Microsoft.CmdPal.Core.ViewModels;
|
||||
|
||||
#pragma warning disable SA1402 // File may only contain a single type
|
||||
#pragma warning disable SA1649 // File name should match first type name
|
||||
|
||||
public abstract partial class ParameterRunViewModel : ExtensionObjectViewModel
|
||||
{
|
||||
internal InitializedState Initialized { get; set; } = InitializedState.Uninitialized;
|
||||
|
||||
protected bool IsInitialized => IsInErrorState || Initialized.HasFlag(InitializedState.Initialized);
|
||||
|
||||
public bool IsInErrorState => Initialized.HasFlag(InitializedState.Error);
|
||||
|
||||
internal ParameterRunViewModel(WeakReference<IPageContext> context)
|
||||
: base(context)
|
||||
{
|
||||
}
|
||||
}
|
||||
|
||||
public partial class LabelRunViewModel : ParameterRunViewModel
|
||||
{
|
||||
private ExtensionObject<ILabelRun> _model;
|
||||
|
||||
public string Text { get; set; } = string.Empty;
|
||||
|
||||
public LabelRunViewModel(ILabelRun labelRun, WeakReference<IPageContext> context)
|
||||
: base(context)
|
||||
{
|
||||
_model = new(labelRun);
|
||||
}
|
||||
|
||||
public override void InitializeProperties()
|
||||
{
|
||||
if (IsInitialized)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
var labelRun = _model.Unsafe;
|
||||
if (labelRun == null)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
Text = labelRun.Text;
|
||||
UpdateProperty(nameof(Text));
|
||||
|
||||
Initialized = InitializedState.Initialized;
|
||||
}
|
||||
}
|
||||
|
||||
public partial class ParameterValueRunViewModel : ParameterRunViewModel
|
||||
{
|
||||
private ExtensionObject<IParameterValueRun> _model;
|
||||
|
||||
public string PlaceholderText { get; set; } = string.Empty;
|
||||
|
||||
public bool NeedsValue { get; set; }
|
||||
|
||||
public ParameterValueRunViewModel(IParameterValueRun valueRun, WeakReference<IPageContext> context)
|
||||
: base(context)
|
||||
{
|
||||
_model = new(valueRun);
|
||||
}
|
||||
|
||||
public override void InitializeProperties()
|
||||
{
|
||||
if (IsInitialized)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
var valueRun = _model.Unsafe;
|
||||
if (valueRun == null)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
PlaceholderText = valueRun.PlaceholderText;
|
||||
NeedsValue = valueRun.NeedsValue;
|
||||
UpdateProperty(nameof(PlaceholderText));
|
||||
UpdateProperty(nameof(NeedsValue));
|
||||
|
||||
Initialized = InitializedState.Initialized;
|
||||
}
|
||||
}
|
||||
|
||||
public partial class StringParameterRunViewModel : ParameterValueRunViewModel
|
||||
{
|
||||
private ExtensionObject<IStringParameterRun> _model;
|
||||
|
||||
public string Text { get; set; } = string.Empty;
|
||||
|
||||
public StringParameterRunViewModel(IStringParameterRun stringRun, WeakReference<IPageContext> context)
|
||||
: base(stringRun, context)
|
||||
{
|
||||
_model = new(stringRun);
|
||||
}
|
||||
|
||||
public override void InitializeProperties()
|
||||
{
|
||||
if (IsInitialized)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
base.InitializeProperties();
|
||||
var stringRun = _model.Unsafe;
|
||||
if (stringRun == null)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
Text = stringRun.Text;
|
||||
UpdateProperty(nameof(Text));
|
||||
}
|
||||
}
|
||||
|
||||
public partial class CommandParameterRunViewModel : ParameterValueRunViewModel
|
||||
{
|
||||
private ExtensionObject<ICommandParameterRun> _model;
|
||||
|
||||
public string DisplayText { get; set; } = string.Empty;
|
||||
|
||||
public IconInfoViewModel Icon { get; set; } = new(null);
|
||||
|
||||
public CommandParameterRunViewModel(ICommandParameterRun commandRun, WeakReference<IPageContext> context)
|
||||
: base(commandRun, context)
|
||||
{
|
||||
_model = new(commandRun);
|
||||
}
|
||||
|
||||
public override void InitializeProperties()
|
||||
{
|
||||
if (IsInitialized)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
base.InitializeProperties();
|
||||
var commandRun = _model.Unsafe;
|
||||
if (commandRun == null)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
DisplayText = commandRun.DisplayText;
|
||||
Icon = new(commandRun.Icon);
|
||||
if (Icon is not null)
|
||||
{
|
||||
Icon.InitializeProperties();
|
||||
}
|
||||
|
||||
UpdateProperty(nameof(DisplayText));
|
||||
UpdateProperty(nameof(Icon));
|
||||
}
|
||||
}
|
||||
|
||||
public partial class ParametersPageViewModel : PageViewModel, IDisposable
|
||||
{
|
||||
private ExtensionObject<IParametersPage> _model;
|
||||
|
||||
public override bool IsInitialized
|
||||
{
|
||||
get => base.IsInitialized; protected set
|
||||
{
|
||||
base.IsInitialized = value;
|
||||
}
|
||||
}
|
||||
|
||||
public ObservableCollection<ParameterRunViewModel> Items { get; set; } = [];
|
||||
|
||||
private readonly Lock _listLock = new();
|
||||
|
||||
public event TypedEventHandler<ParametersPageViewModel, object>? ItemsUpdated;
|
||||
|
||||
public ParametersPageViewModel(IParametersPage model, TaskScheduler scheduler, AppExtensionHost host)
|
||||
: base(model, scheduler, host)
|
||||
{
|
||||
_model = new(model);
|
||||
}
|
||||
|
||||
private void Model_ItemsChanged(object sender, IItemsChangedEventArgs args) => FetchItems();
|
||||
|
||||
//// Run on background thread, from InitializeAsync
|
||||
public override void InitializeProperties()
|
||||
{
|
||||
base.InitializeProperties();
|
||||
|
||||
var model = _model.Unsafe;
|
||||
if (model is null)
|
||||
{
|
||||
return; // throw?
|
||||
}
|
||||
|
||||
FetchItems();
|
||||
|
||||
// model.ItemsChanged += Model_ItemsChanged; // TODO!
|
||||
}
|
||||
|
||||
//// Run on background thread, from InitializeAsync or Model_ItemsChanged
|
||||
private void FetchItems()
|
||||
{
|
||||
// Collect all the items into new viewmodels
|
||||
Collection<ParameterRunViewModel> newViewModels = [];
|
||||
try
|
||||
{
|
||||
var newItems = _model.Unsafe!.Parameters;
|
||||
foreach (var item in newItems)
|
||||
{
|
||||
ParameterRunViewModel? itemVm = item switch
|
||||
{
|
||||
ILabelRun labelRun => new LabelRunViewModel(labelRun, PageContext),
|
||||
IStringParameterRun stringRun => new StringParameterRunViewModel(stringRun, PageContext),
|
||||
ICommandParameterRun commandRun => new CommandParameterRunViewModel(commandRun, PageContext),
|
||||
_ => null,
|
||||
};
|
||||
if (itemVm != null)
|
||||
{
|
||||
itemVm.InitializeProperties();
|
||||
newViewModels.Add(itemVm);
|
||||
}
|
||||
}
|
||||
|
||||
// Update the Items collection on the UI thread
|
||||
List<ParameterRunViewModel> removedItems = [];
|
||||
lock (_listLock)
|
||||
{
|
||||
// Now that we have new ViewModels for everything from the
|
||||
// extension, smartly update our list of VMs
|
||||
ListHelpers.InPlaceUpdateList(Items, newViewModels, out removedItems);
|
||||
|
||||
// DO NOT ThrowIfCancellationRequested AFTER THIS! If you do,
|
||||
// you'll clean up list items that we've now transferred into
|
||||
// .Items
|
||||
}
|
||||
|
||||
// If we removed items, we need to clean them up, to remove our event handlers
|
||||
foreach (var removedItem in removedItems)
|
||||
{
|
||||
removedItem.SafeCleanup();
|
||||
}
|
||||
}
|
||||
catch (Exception)
|
||||
{
|
||||
// Handle exceptions (e.g., log them)
|
||||
}
|
||||
|
||||
DoOnUiThread(
|
||||
() =>
|
||||
{
|
||||
ItemsUpdated?.Invoke(this, EventArgs.Empty);
|
||||
OnPropertyChanged(nameof(Items)); // TODO! hack
|
||||
});
|
||||
}
|
||||
|
||||
public void Dispose()
|
||||
{
|
||||
GC.SuppressFinalize(this);
|
||||
|
||||
// TODO!
|
||||
|
||||
// _cancellationTokenSource?.Cancel();
|
||||
// _cancellationTokenSource?.Dispose();
|
||||
// _cancellationTokenSource = null;
|
||||
|
||||
// _fetchItemsCancellationTokenSource?.Cancel();
|
||||
// _fetchItemsCancellationTokenSource?.Dispose();
|
||||
// _fetchItemsCancellationTokenSource = null;
|
||||
}
|
||||
|
||||
protected override void UnsafeCleanup()
|
||||
{
|
||||
base.UnsafeCleanup();
|
||||
|
||||
// _cancellationTokenSource?.Cancel();
|
||||
// _fetchItemsCancellationTokenSource?.Cancel();
|
||||
var model = _model.Unsafe;
|
||||
if (model is not null)
|
||||
{
|
||||
// model.ItemsChanged -= Model_ItemsChanged;
|
||||
}
|
||||
|
||||
lock (_listLock)
|
||||
{
|
||||
foreach (var item in Items)
|
||||
{
|
||||
item.SafeCleanup();
|
||||
}
|
||||
|
||||
Items.Clear();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#pragma warning restore SA1649 // File name should match first type name
|
||||
#pragma warning restore SA1402 // File may only contain a single type
|
||||
@@ -23,6 +23,7 @@ public class CommandPalettePageViewModelFactory
|
||||
{
|
||||
IListPage listPage => new ListViewModel(listPage, _scheduler, host) { IsNested = nested },
|
||||
IContentPage contentPage => new CommandPaletteContentPageViewModel(contentPage, _scheduler, host),
|
||||
IParametersPage paramsPage => new ParametersPageViewModel(paramsPage, _scheduler, host),
|
||||
_ => null,
|
||||
};
|
||||
}
|
||||
|
||||
@@ -4,7 +4,9 @@
|
||||
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
|
||||
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
|
||||
xmlns:cmdpalUi="using:Microsoft.CmdPal.UI"
|
||||
xmlns:controls="using:CommunityToolkit.WinUI.Controls"
|
||||
xmlns:converters="using:CommunityToolkit.WinUI.Converters"
|
||||
xmlns:coreVm="using:Microsoft.CmdPal.Core.ViewModels"
|
||||
xmlns:cpcontrols="using:Microsoft.CmdPal.UI.Controls"
|
||||
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
|
||||
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
|
||||
@@ -13,21 +15,77 @@
|
||||
<UserControl.Resources>
|
||||
<ResourceDictionary>
|
||||
<cmdpalUi:PlaceholderTextConverter x:Key="PlaceholderTextConverter" />
|
||||
|
||||
<DataTemplate x:Key="LabelRunTemplate" x:DataType="coreVm:LabelRunViewModel">
|
||||
<TextBlock
|
||||
MinHeight="32"
|
||||
VerticalAlignment="Center"
|
||||
Text="{x:Bind Text, Mode=OneWay}" />
|
||||
</DataTemplate>
|
||||
<DataTemplate x:Key="ButtonParamTemplate" x:DataType="coreVm:CommandParameterRunViewModel">
|
||||
<Button
|
||||
MinHeight="32"
|
||||
VerticalAlignment="Center"
|
||||
VerticalContentAlignment="Stretch"
|
||||
Content="{x:Bind DisplayText, Mode=OneWay}" />
|
||||
</DataTemplate>
|
||||
<DataTemplate x:Key="StringParamTemplate" x:DataType="coreVm:StringParameterRunViewModel">
|
||||
<TextBox
|
||||
MinHeight="32"
|
||||
VerticalAlignment="Center"
|
||||
VerticalContentAlignment="Stretch"
|
||||
BorderBrush="{ThemeResource AccentTextFillColorPrimaryBrush}"
|
||||
BorderThickness="1"
|
||||
Foreground="{ThemeResource AccentTextFillColorPrimaryBrush}"
|
||||
PlaceholderText="{x:Bind PlaceholderText, Mode=OneWay}"
|
||||
Style="{StaticResource SearchTextBoxStyle}"
|
||||
Text="{x:Bind Text, Mode=TwoWay}" />
|
||||
</DataTemplate>
|
||||
<cpcontrols:ParameterRunTemplateSelector
|
||||
x:Key="ParameterRunTemplateSelector"
|
||||
ButtonParamTemplate="{StaticResource ButtonParamTemplate}"
|
||||
LabelRunTemplate="{StaticResource LabelRunTemplate}"
|
||||
StringParamTemplate="{StaticResource StringParamTemplate}" />
|
||||
</ResourceDictionary>
|
||||
</UserControl.Resources>
|
||||
|
||||
<!-- Search box -->
|
||||
<TextBox
|
||||
x:Name="FilterBox"
|
||||
MinHeight="32"
|
||||
VerticalAlignment="Stretch"
|
||||
VerticalContentAlignment="Stretch"
|
||||
AutomationProperties.AutomationId="MainSearchBox"
|
||||
KeyDown="FilterBox_KeyDown"
|
||||
PlaceholderText="{x:Bind CurrentPageViewModel.PlaceholderText, Converter={StaticResource PlaceholderTextConverter}, Mode=OneWay}"
|
||||
PreviewKeyDown="FilterBox_PreviewKeyDown"
|
||||
PreviewKeyUp="FilterBox_PreviewKeyUp"
|
||||
Style="{StaticResource SearchTextBoxStyle}"
|
||||
TextChanged="FilterBox_TextChanged" />
|
||||
<!-- Disabled Description="{x:Bind CurrentPageViewModel.TextToSuggest, Mode=OneWay}" for now, needs more work -->
|
||||
<controls:SwitchPresenter
|
||||
HorizontalAlignment="Stretch"
|
||||
TargetType="x:String"
|
||||
Value="{x:Bind PageType, Mode=OneWay}">
|
||||
<controls:Case Value="List">
|
||||
|
||||
<!-- Search box -->
|
||||
<TextBox
|
||||
x:Name="FilterBox"
|
||||
MinHeight="32"
|
||||
VerticalAlignment="Stretch"
|
||||
VerticalContentAlignment="Stretch"
|
||||
AutomationProperties.AutomationId="MainSearchBox"
|
||||
KeyDown="FilterBox_KeyDown"
|
||||
PlaceholderText="{x:Bind CurrentPageViewModel.PlaceholderText, Converter={StaticResource PlaceholderTextConverter}, Mode=OneWay}"
|
||||
PreviewKeyDown="FilterBox_PreviewKeyDown"
|
||||
PreviewKeyUp="FilterBox_PreviewKeyUp"
|
||||
Style="{StaticResource SearchTextBoxStyle}"
|
||||
TextChanged="FilterBox_TextChanged" />
|
||||
<!-- Disabled Description="{x:Bind CurrentPageViewModel.TextToSuggest, Mode=OneWay}" for now, needs more work -->
|
||||
</controls:Case>
|
||||
|
||||
<controls:Case Value="Parameters">
|
||||
|
||||
<ItemsControl
|
||||
x:Name="ParametersBar"
|
||||
HorizontalAlignment="Stretch"
|
||||
VerticalAlignment="Stretch"
|
||||
ItemTemplateSelector="{StaticResource ParameterRunTemplateSelector}"
|
||||
ItemsSource="{x:Bind Parameters, Mode=OneWay}">
|
||||
<ItemsControl.ItemsPanel>
|
||||
<ItemsPanelTemplate>
|
||||
<StackPanel Orientation="Horizontal" />
|
||||
</ItemsPanelTemplate>
|
||||
</ItemsControl.ItemsPanel>
|
||||
</ItemsControl>
|
||||
|
||||
</controls:Case>
|
||||
</controls:SwitchPresenter>
|
||||
</UserControl>
|
||||
|
||||
@@ -2,6 +2,8 @@
|
||||
// The Microsoft Corporation licenses this file to you under the MIT license.
|
||||
// See the LICENSE file in the project root for more information.
|
||||
|
||||
using System.Collections.ObjectModel;
|
||||
using System.ComponentModel;
|
||||
using CommunityToolkit.Mvvm.Messaging;
|
||||
using CommunityToolkit.WinUI;
|
||||
using Microsoft.CmdPal.Core.ViewModels;
|
||||
@@ -19,6 +21,7 @@ using VirtualKey = Windows.System.VirtualKey;
|
||||
namespace Microsoft.CmdPal.UI.Controls;
|
||||
|
||||
public sealed partial class SearchBar : UserControl,
|
||||
INotifyPropertyChanged,
|
||||
IRecipient<GoHomeMessage>,
|
||||
IRecipient<FocusSearchBoxMessage>,
|
||||
IRecipient<UpdateSuggestionMessage>,
|
||||
@@ -46,6 +49,8 @@ public sealed partial class SearchBar : UserControl,
|
||||
public static readonly DependencyProperty CurrentPageViewModelProperty =
|
||||
DependencyProperty.Register(nameof(CurrentPageViewModel), typeof(PageViewModel), typeof(SearchBar), new PropertyMetadata(null, OnCurrentPageViewModelChanged));
|
||||
|
||||
public event PropertyChangedEventHandler? PropertyChanged;
|
||||
|
||||
private static void OnCurrentPageViewModelChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
|
||||
{
|
||||
//// TODO: If the Debounce timer hasn't fired, we may want to store the current Filter in the OldValue/prior VM, but we don't want that to go actually do work...
|
||||
@@ -67,8 +72,20 @@ public sealed partial class SearchBar : UserControl,
|
||||
|
||||
page.PropertyChanged += @this.Page_PropertyChanged;
|
||||
}
|
||||
|
||||
@this?.PropertyChanged?.Invoke(@this, new(nameof(PageType)));
|
||||
}
|
||||
|
||||
public string PageType => CurrentPageViewModel switch
|
||||
{
|
||||
ListViewModel => "List",
|
||||
ContentPageViewModel => "Content",
|
||||
ParametersPageViewModel => "Parameters",
|
||||
_ => string.Empty,
|
||||
};
|
||||
|
||||
public ObservableCollection<ParameterRunViewModel>? Parameters => CurrentPageViewModel is ParametersPageViewModel ppvm ? ppvm.Items : null;
|
||||
|
||||
public SearchBar()
|
||||
{
|
||||
this.InitializeComponent();
|
||||
@@ -355,6 +372,13 @@ public sealed partial class SearchBar : UserControl,
|
||||
SelectSearch();
|
||||
}
|
||||
}
|
||||
else if (CurrentPageViewModel is ParametersPageViewModel parametersPage)
|
||||
{
|
||||
if (property == nameof(ParametersPageViewModel.Items))
|
||||
{
|
||||
this.PropertyChanged?.Invoke(this, new(nameof(Parameters)));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void Receive(GoHomeMessage message) => ClearSearch();
|
||||
@@ -453,3 +477,30 @@ public sealed partial class SearchBar : UserControl,
|
||||
}));
|
||||
}
|
||||
}
|
||||
|
||||
#pragma warning disable SA1402 // File may only contain a single type
|
||||
public sealed partial class ParameterRunTemplateSelector : DataTemplateSelector
|
||||
#pragma warning restore SA1402 // File may only contain a single type
|
||||
{
|
||||
public DataTemplate? LabelRunTemplate { get; set; }
|
||||
|
||||
public DataTemplate? StringParamTemplate { get; set; }
|
||||
|
||||
public DataTemplate? ButtonParamTemplate { get; set; }
|
||||
|
||||
protected override DataTemplate? SelectTemplateCore(object item)
|
||||
{
|
||||
return item switch
|
||||
{
|
||||
LabelRunViewModel => LabelRunTemplate,
|
||||
StringParameterRunViewModel => StringParamTemplate,
|
||||
CommandParameterRunViewModel => ButtonParamTemplate,
|
||||
_ => base.SelectTemplateCore(item),
|
||||
};
|
||||
}
|
||||
|
||||
protected override DataTemplate? SelectTemplateCore(object item, DependencyObject container)
|
||||
{
|
||||
return SelectTemplateCore(item);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,29 @@
|
||||
<?xml version="1.0" encoding="utf-8" ?>
|
||||
<Page
|
||||
x:Class="Microsoft.CmdPal.UI.ParametersPage"
|
||||
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
|
||||
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
|
||||
xmlns:Interactions="using:Microsoft.Xaml.Interactions.Core"
|
||||
xmlns:Interactivity="using:Microsoft.Xaml.Interactivity"
|
||||
xmlns:cmdPalControls="using:Microsoft.CmdPal.UI.Controls"
|
||||
xmlns:cmdpalUI="using:Microsoft.CmdPal.UI"
|
||||
xmlns:controls="using:CommunityToolkit.WinUI.Controls"
|
||||
xmlns:converters="using:CommunityToolkit.WinUI.Converters"
|
||||
xmlns:coreViewModels="using:Microsoft.CmdPal.Core.ViewModels"
|
||||
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
|
||||
xmlns:labToolkit="using:CommunityToolkit.Labs.WinUI.MarkdownTextBlock"
|
||||
xmlns:local="using:Microsoft.CmdPal.UI"
|
||||
xmlns:markdownTextBlockRns="using:CommunityToolkit.WinUI.Controls.MarkdownTextBlockRns"
|
||||
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
|
||||
xmlns:viewModels="using:Microsoft.CmdPal.UI.ViewModels"
|
||||
Background="Transparent"
|
||||
mc:Ignorable="d">
|
||||
|
||||
<Page.Resources>
|
||||
<ResourceDictionary />
|
||||
</Page.Resources>
|
||||
<Grid>
|
||||
<TextBlock Text="Parameters Page" />
|
||||
</Grid>
|
||||
|
||||
</Page>
|
||||
@@ -0,0 +1,85 @@
|
||||
// Copyright (c) Microsoft Corporation
|
||||
// The Microsoft Corporation licenses this file to you under the MIT license.
|
||||
// See the LICENSE file in the project root for more information.
|
||||
|
||||
using CommunityToolkit.Mvvm.Messaging;
|
||||
using Microsoft.CmdPal.Core.ViewModels;
|
||||
using Microsoft.UI.Dispatching;
|
||||
using Microsoft.UI.Xaml;
|
||||
using Microsoft.UI.Xaml.Controls;
|
||||
using Microsoft.UI.Xaml.Navigation;
|
||||
|
||||
namespace Microsoft.CmdPal.UI;
|
||||
|
||||
/// <summary>
|
||||
/// An empty page that can be used on its own or navigated to within a Frame.
|
||||
/// </summary>
|
||||
public sealed partial class ParametersPage : Page
|
||||
{
|
||||
private readonly DispatcherQueue _queue = DispatcherQueue.GetForCurrentThread();
|
||||
|
||||
public ParametersPageViewModel? ViewModel
|
||||
{
|
||||
get => (ParametersPageViewModel?)GetValue(ViewModelProperty);
|
||||
set => SetValue(ViewModelProperty, value);
|
||||
}
|
||||
|
||||
// Using a DependencyProperty as the backing store for ViewModel. This enables animation, styling, binding, etc...
|
||||
public static readonly DependencyProperty ViewModelProperty =
|
||||
DependencyProperty.Register(nameof(ViewModel), typeof(ParametersPageViewModel), typeof(ParametersPage), new PropertyMetadata(null));
|
||||
|
||||
public ParametersPage()
|
||||
{
|
||||
this.InitializeComponent();
|
||||
this.Unloaded += OnUnloaded;
|
||||
}
|
||||
|
||||
private void OnUnloaded(object sender, RoutedEventArgs e)
|
||||
{
|
||||
// Unhook from everything to ensure nothing can reach us
|
||||
// between this point and our complete and utter destruction.
|
||||
WeakReferenceMessenger.Default.UnregisterAll(this);
|
||||
}
|
||||
|
||||
protected override void OnNavigatedTo(NavigationEventArgs e)
|
||||
{
|
||||
if (e.Parameter is ParametersPageViewModel vm)
|
||||
{
|
||||
ViewModel = vm;
|
||||
}
|
||||
|
||||
// if (!WeakReferenceMessenger.Default.IsRegistered<ActivateSelectedListItemMessage>(this))
|
||||
// {
|
||||
// WeakReferenceMessenger.Default.Register<ActivateSelectedListItemMessage>(this);
|
||||
// }
|
||||
|
||||
// if (!WeakReferenceMessenger.Default.IsRegistered<ActivateSecondaryCommandMessage>(this))
|
||||
// {
|
||||
// WeakReferenceMessenger.Default.Register<ActivateSecondaryCommandMessage>(this);
|
||||
// }
|
||||
base.OnNavigatedTo(e);
|
||||
}
|
||||
|
||||
protected override void OnNavigatingFrom(NavigatingCancelEventArgs e)
|
||||
{
|
||||
base.OnNavigatingFrom(e);
|
||||
|
||||
// WeakReferenceMessenger.Default.Unregister<ActivateSelectedListItemMessage>(this);
|
||||
// WeakReferenceMessenger.Default.Unregister<ActivateSecondaryCommandMessage>(this);
|
||||
|
||||
// Clean-up event listeners
|
||||
ViewModel = null;
|
||||
}
|
||||
|
||||
// // this comes in on Enter keypresses in the SearchBox
|
||||
// public void Receive(ActivateSelectedListItemMessage message)
|
||||
// {
|
||||
// ViewModel?.InvokePrimaryCommandCommand?.Execute(ViewModel);
|
||||
// }
|
||||
|
||||
// // this comes in on Ctrl+Enter keypresses in the SearchBox
|
||||
// public void Receive(ActivateSecondaryCommandMessage message)
|
||||
// {
|
||||
// ViewModel?.InvokeSecondaryCommandCommand?.Execute(ViewModel);
|
||||
// }
|
||||
}
|
||||
@@ -127,6 +127,7 @@ public sealed partial class ShellPage : Microsoft.UI.Xaml.Controls.Page,
|
||||
{
|
||||
ListViewModel => typeof(ListPage),
|
||||
ContentPageViewModel => typeof(ContentPage),
|
||||
ParametersPageViewModel => typeof(ParametersPage),
|
||||
_ => throw new NotSupportedException(),
|
||||
},
|
||||
message.Page,
|
||||
|
||||
@@ -194,11 +194,6 @@ namespace winrt::Microsoft::Terminal::UI::implementation
|
||||
// Some emojis (e.g. 2️⃣) would be rendered as emoji glyphs otherwise.
|
||||
family = L"Segoe UI Emoji, Segoe UI";
|
||||
}
|
||||
else if (!fontFamily.empty())
|
||||
{
|
||||
icon.FontFamily(winrt::Microsoft::UI::Xaml::Media::FontFamily{ fontFamily });
|
||||
|
||||
}
|
||||
else
|
||||
{
|
||||
family = L"Segoe UI";
|
||||
|
||||
@@ -13,6 +13,40 @@ namespace SamplePagesExtension.Pages;
|
||||
#pragma warning disable SA1649 // File name should match first type name
|
||||
#nullable enable
|
||||
|
||||
public sealed partial class SimpleParameterTest : ParametersPage
|
||||
{
|
||||
private readonly StringParameterRun _stringParameter;
|
||||
private readonly InvokableCommand _command;
|
||||
|
||||
public SimpleParameterTest()
|
||||
{
|
||||
Name = "Open";
|
||||
_stringParameter = new StringParameterRun()
|
||||
{
|
||||
PlaceholderText = "Type something",
|
||||
};
|
||||
|
||||
_command = new AnonymousCommand(() =>
|
||||
{
|
||||
var input = _stringParameter.Text;
|
||||
var toast = new ToastStatusMessage(new StatusMessage() { Message = $"You entered: {input}" });
|
||||
toast.Show();
|
||||
})
|
||||
{
|
||||
Name = "Submit",
|
||||
Icon = new IconInfo("\uE724"), // Send
|
||||
};
|
||||
}
|
||||
|
||||
public override IParameterRun[] Parameters => new IParameterRun[]
|
||||
{
|
||||
new LabelRun("Enter a value:"),
|
||||
_stringParameter,
|
||||
};
|
||||
|
||||
public override IListItem Command => new ListItem(_command);
|
||||
}
|
||||
|
||||
public sealed partial class CreateNoteParametersPage : ParametersPage
|
||||
{
|
||||
private readonly SelectFolderPage _selectFolderPage = new();
|
||||
|
||||
@@ -89,6 +89,13 @@ public partial class SamplesListPage : ListPage
|
||||
Subtitle = "A demo of the settings helpers",
|
||||
},
|
||||
|
||||
// Parameter pages
|
||||
new ListItem(new SimpleParameterTest())
|
||||
{
|
||||
Title = "Sample parameters page",
|
||||
Subtitle = "A demo of a command that takes simple parameters",
|
||||
},
|
||||
|
||||
// Evil edge cases
|
||||
// Anything weird that might break the palette - put that in here.
|
||||
new ListItem(new EvilSamplesPage())
|
||||
|
||||
Reference in New Issue
Block a user