From 06e5db6ff049c1f9ef7f0fb8c7703eec3adcd436 Mon Sep 17 00:00:00 2001 From: Mike Griese Date: Wed, 7 May 2025 04:47:57 -0500 Subject: [PATCH] CmdPal: Actually observe Details (#39263) Extensions can change the properties on their Details, and they should be observable, but they weren't. This is because the ShellPage is ultimately responsible for exposing the details, but it doesn't own the details. The selected ListItemViewModel from the ListPage does. This PR just adds a event handler on ListViewModel. We'll attach/detach that handler to ListItemViewModels as the selection changes. In the body of that handler, we'll let the ShellPage know when the details object changes (by sending ShowDetails/HideDetails messages). Closes #39216 --- .../ListViewModel.cs | 44 +++++++++++++++++++ 1 file changed, 44 insertions(+) diff --git a/src/modules/cmdpal/Microsoft.CmdPal.UI.ViewModels/ListViewModel.cs b/src/modules/cmdpal/Microsoft.CmdPal.UI.ViewModels/ListViewModel.cs index 31b2c3c0de..7774d4686b 100644 --- a/src/modules/cmdpal/Microsoft.CmdPal.UI.ViewModels/ListViewModel.cs +++ b/src/modules/cmdpal/Microsoft.CmdPal.UI.ViewModels/ListViewModel.cs @@ -61,6 +61,8 @@ public partial class ListViewModel : PageViewModel, IDisposable private Task? _initializeItemsTask; private CancellationTokenSource? _cancellationTokenSource; + private ListItemViewModel? _lastSelectedItem; + public override bool IsInitialized { get => base.IsInitialized; protected set @@ -330,6 +332,11 @@ public partial class ListViewModel : PageViewModel, IDisposable [RelayCommand] private void UpdateSelectedItem(ListItemViewModel? item) { + if (_lastSelectedItem != null) + { + _lastSelectedItem.PropertyChanged -= SelectedItemPropertyChanged; + } + if (item != null) { SetSelectedItem(item); @@ -367,6 +374,43 @@ public partial class ListViewModel : PageViewModel, IDisposable TextToSuggest = item.TextToSuggest; }); + + _lastSelectedItem = item; + _lastSelectedItem.PropertyChanged += SelectedItemPropertyChanged; + } + + private void SelectedItemPropertyChanged(object? sender, System.ComponentModel.PropertyChangedEventArgs e) + { + var item = _lastSelectedItem; + if (item == null) + { + return; + } + + // already on the UI thread here + switch (e.PropertyName) + { + case nameof(item.Command): + case nameof(item.SecondaryCommand): + case nameof(item.AllCommands): + case nameof(item.Name): + WeakReferenceMessenger.Default.Send(new(item)); + break; + case nameof(item.Details): + if (ShowDetails && item.HasDetails) + { + WeakReferenceMessenger.Default.Send(new(item.Details)); + } + else + { + WeakReferenceMessenger.Default.Send(); + } + + break; + case nameof(item.TextToSuggest): + TextToSuggest = item.TextToSuggest; + break; + } } private void ClearSelectedItem()