/
githubmirror
/
PowerToys
Обзор
Документация
Войти
/
githubmirror
/
PowerToys
Код
Запросы
0
Пакеты
0
Релизы
0
Аналитика
Безопасность
main
src/modules/cmdpal/Microsoft.CmdPal.UI.ViewModels/CommandViewModel.cs
175 строк
5 KB
Mike Griese
CmdPal: Add support for pages with parameters (redux) (#47826)
16 май 2026, 04:31
Не верифицирован
16 май 2026, 04:31
42902ee
Код
Авторство
О чём код?
// 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 Microsoft.CmdPal.UI.ViewModels.Models; using Microsoft.CommandPalette.Extensions; namespace Microsoft.CmdPal.UI.ViewModels; public partial class CommandViewModel : ExtensionObjectViewModel { public ExtensionObject<ICommand> Model { get; private set; } = new(null); public bool IsSet => Model.Unsafe is not null; protected bool IsInitialized { get; private set; } protected bool IsFastInitialized { get; private set; } public bool HasIcon => Icon.IsSet; // These are properties that are "observable" from the extension object // itself, in the sense that they get raised by PropChanged events from the // extension. However, we don't want to actually make them // [ObservableProperty]s, because PropChanged comes in off the UI thread, // and ObservableProperty is not smart enough to raise the PropertyChanged // on the UI thread. public string Id { get; private set; } = string.Empty; public string Name { get; private set; } = string.Empty; public IconInfoViewModel Icon { get; private set; } // UNDER NO CIRCUMSTANCES MAY SOMEONE WRITE TO THIS DICTIONARY. // This is our copy of the data from the extension. // Adding values to it does not add to the extension. // Modifying it will not modify the extension // (except it might, if the dictionary was passed by ref) private Dictionary<string, ExtensionObject<object>>? _properties; public IReadOnlyDictionary<string, ExtensionObject<object>>? Properties => _properties?.AsReadOnly(); public CommandViewModel(ICommand? command, WeakReference<IPageContext> pageContext) : base(pageContext) { Model = new(command); Icon = new(null); } public void FastInitializeProperties() { if (IsFastInitialized) { return; } var model = Model.Unsafe; if (model is null) { return; } Id = model.Id ?? string.Empty; Name = model.Name ?? string.Empty; IsFastInitialized = true; } public override void InitializeProperties() { if (IsInitialized) { return; } if (!IsFastInitialized) { FastInitializeProperties(); } var model = Model.Unsafe; if (model is null) { return; } var ico = model.Icon; if (ico is not null) { Icon = new(ico); Icon.InitializeProperties(); UpdateProperty(nameof(Icon)); } if (model is IExtendedAttributesProvider command2) { UpdatePropertiesFromExtension(command2); } model.PropChanged += Model_PropChanged; } private void Model_PropChanged(object sender, IPropChangedEventArgs args) { try { FetchProperty(args.PropertyName); } catch (Exception ex) { ShowException(ex, Name); } } protected void FetchProperty(string propertyName) { var model = Model.Unsafe; if (model is null) { return; // throw? } switch (propertyName) { case nameof(Name): Name = model.Name; break; case nameof(Icon): var iconInfo = model.Icon; Icon = new(iconInfo); Icon.InitializeProperties(); break; case nameof(Properties): UpdatePropertiesFromExtension(model as IExtendedAttributesProvider); break; } UpdateProperty(propertyName); } protected override void UnsafeCleanup() { base.UnsafeCleanup(); Icon = new(null); // necessary? var model = Model.Unsafe; if (model is not null) { model.PropChanged -= Model_PropChanged; } } private void UpdatePropertiesFromExtension(IExtendedAttributesProvider? model) { var propertiesFromExtension = model?.GetProperties(); if (propertiesFromExtension == null) { _properties = null; return; } _properties = []; // COPY the properties into us. // The IDictionary that was passed to us may be marshalled by-ref or by-value, we _don't know_. // // If it's by-ref, the values are arbitrary objects that are out-of-proc. // If it's bu-value, then everything is in-proc, and we can't mutate the data. foreach (var property in propertiesFromExtension) { _properties.Add(property.Key, new(property.Value)); } } }