diff --git a/src/modules/cmdpal/Exts/Microsoft.CmdPal.Ext.WindowWalker/Pages/WindowWalkerListPage.cs b/src/modules/cmdpal/Exts/Microsoft.CmdPal.Ext.WindowWalker/Pages/WindowWalkerListPage.cs index 50887694dc..768dafec44 100644 --- a/src/modules/cmdpal/Exts/Microsoft.CmdPal.Ext.WindowWalker/Pages/WindowWalkerListPage.cs +++ b/src/modules/cmdpal/Exts/Microsoft.CmdPal.Ext.WindowWalker/Pages/WindowWalkerListPage.cs @@ -22,6 +22,7 @@ internal sealed partial class WindowWalkerListPage : DynamicListPage, IDisposabl Icon = new("\ue8f9"); // SwitchApps Name = Resources.windowwalker_name; Id = "com.microsoft.cmdpal.windowwalker"; + PlaceholderText = Resources.windowwalker_PlaceholderText; } public override void UpdateSearchText(string oldSearch, string newSearch) => diff --git a/src/modules/cmdpal/Exts/Microsoft.CmdPal.Ext.WindowWalker/Properties/Resources.Designer.cs b/src/modules/cmdpal/Exts/Microsoft.CmdPal.Ext.WindowWalker/Properties/Resources.Designer.cs index 3b4d75ec60..3edc393e4f 100644 --- a/src/modules/cmdpal/Exts/Microsoft.CmdPal.Ext.WindowWalker/Properties/Resources.Designer.cs +++ b/src/modules/cmdpal/Exts/Microsoft.CmdPal.Ext.WindowWalker/Properties/Resources.Designer.cs @@ -213,6 +213,15 @@ namespace Microsoft.CmdPal.Ext.WindowWalker.Properties { } } + /// + /// Looks up a localized string similar to Search open windows.... + /// + public static string windowwalker_PlaceholderText { + get { + return ResourceManager.GetString("windowwalker_PlaceholderText", resourceCulture); + } + } + /// /// Looks up a localized string similar to Switches between open windows. /// diff --git a/src/modules/cmdpal/Exts/Microsoft.CmdPal.Ext.WindowWalker/Properties/Resources.resx b/src/modules/cmdpal/Exts/Microsoft.CmdPal.Ext.WindowWalker/Properties/Resources.resx index a2de81028e..12781a6a24 100644 --- a/src/modules/cmdpal/Exts/Microsoft.CmdPal.Ext.WindowWalker/Properties/Resources.resx +++ b/src/modules/cmdpal/Exts/Microsoft.CmdPal.Ext.WindowWalker/Properties/Resources.resx @@ -229,4 +229,7 @@ pid + + Search open windows... + \ No newline at end of file diff --git a/src/modules/cmdpal/Microsoft.CmdPal.UI.ViewModels/ListViewModel.cs b/src/modules/cmdpal/Microsoft.CmdPal.UI.ViewModels/ListViewModel.cs index 9311977c9e..29a66cf40e 100644 --- a/src/modules/cmdpal/Microsoft.CmdPal.UI.ViewModels/ListViewModel.cs +++ b/src/modules/cmdpal/Microsoft.CmdPal.UI.ViewModels/ListViewModel.cs @@ -35,7 +35,11 @@ public partial class ListViewModel : PageViewModel // cannot be marked [ObservableProperty] public bool ShowDetails { get; private set; } - public string PlaceholderText { get => string.IsNullOrEmpty(field) ? "Type here to search..." : field; private set; } = string.Empty; + public string ModelPlaceholderText { get => string.IsNullOrEmpty(field) ? "Type here to search..." : field; private set; } = string.Empty; + + public override string PlaceholderText { get => ModelPlaceholderText; } + + public string SearchText { get; private set; } = string.Empty; private bool _isDynamic; @@ -241,9 +245,13 @@ public partial class ListViewModel : PageViewModel ShowDetails = listPage.ShowDetails; UpdateProperty(nameof(ShowDetails)); - PlaceholderText = listPage.PlaceholderText; + + ModelPlaceholderText = listPage.PlaceholderText; UpdateProperty(nameof(PlaceholderText)); + SearchText = listPage.SearchText; + UpdateProperty(nameof(SearchText)); + FetchItems(); listPage.ItemsChanged += Model_ItemsChanged; } @@ -264,7 +272,10 @@ public partial class ListViewModel : PageViewModel this.ShowDetails = model.ShowDetails; break; case nameof(PlaceholderText): - this.PlaceholderText = model.PlaceholderText; + this.ModelPlaceholderText = model.PlaceholderText; + break; + case nameof(SearchText): + this.SearchText = model.SearchText; break; } diff --git a/src/modules/cmdpal/Microsoft.CmdPal.UI.ViewModels/PageViewModel.cs b/src/modules/cmdpal/Microsoft.CmdPal.UI.ViewModels/PageViewModel.cs index 1a9b599d08..8c0a45028d 100644 --- a/src/modules/cmdpal/Microsoft.CmdPal.UI.ViewModels/PageViewModel.cs +++ b/src/modules/cmdpal/Microsoft.CmdPal.UI.ViewModels/PageViewModel.cs @@ -32,6 +32,9 @@ public partial class PageViewModel : ExtensionObjectViewModel, IPageContext [ObservableProperty] public partial string Filter { get; set; } = string.Empty; + [ObservableProperty] + public virtual partial string PlaceholderText { get; private set; } = "Type here to search..."; + [ObservableProperty] public partial CommandPaletteHost ExtensionHost { get; private set; } diff --git a/src/modules/cmdpal/Microsoft.CmdPal.UI/Controls/SearchBar.xaml b/src/modules/cmdpal/Microsoft.CmdPal.UI/Controls/SearchBar.xaml index 3008092cb8..e3ce58651a 100644 --- a/src/modules/cmdpal/Microsoft.CmdPal.UI/Controls/SearchBar.xaml +++ b/src/modules/cmdpal/Microsoft.CmdPal.UI/Controls/SearchBar.xaml @@ -15,7 +15,7 @@ VerticalAlignment="Stretch" VerticalContentAlignment="Stretch" KeyDown="FilterBox_KeyDown" - PlaceholderText="Type here to search..." + PlaceholderText="{x:Bind CurrentPageViewModel.PlaceholderText, Mode=OneWay}" PreviewKeyDown="FilterBox_PreviewKeyDown" PreviewKeyUp="FilterBox_PreviewKeyUp" Style="{StaticResource SearchTextBoxStyle}" diff --git a/src/modules/cmdpal/Microsoft.CmdPal.UI/Controls/SearchBar.xaml.cs b/src/modules/cmdpal/Microsoft.CmdPal.UI/Controls/SearchBar.xaml.cs index b9c46d32d0..a8fb8f7d32 100644 --- a/src/modules/cmdpal/Microsoft.CmdPal.UI/Controls/SearchBar.xaml.cs +++ b/src/modules/cmdpal/Microsoft.CmdPal.UI/Controls/SearchBar.xaml.cs @@ -43,14 +43,23 @@ public sealed partial class SearchBar : UserControl, 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... + var @this = (SearchBar)d; - if (d is SearchBar @this + if (@this != null + && e.OldValue is PageViewModel old) + { + old.PropertyChanged -= @this.Page_PropertyChanged; + } + + if (@this != null && e.NewValue is PageViewModel page) { // TODO: In some cases we probably want commands to clear a filter // somewhere in the process, so we need to figure out when that is. @this.FilterBox.Text = page.Filter; @this.FilterBox.Select(@this.FilterBox.Text.Length, 0); + + page.PropertyChanged += @this.Page_PropertyChanged; } } @@ -213,4 +222,19 @@ public sealed partial class SearchBar : UserControl, } public void Receive(GoHomeMessage message) => ClearSearch(); + + // Used to handle the case when a ListPage's `SearchText` may have changed + private void Page_PropertyChanged(object? sender, System.ComponentModel.PropertyChangedEventArgs e) + { + var property = e.PropertyName; + var list = CurrentPageViewModel as ListViewModel; + if (list != null && + property == nameof(ListViewModel.SearchText)) + { + FilterBox.Text = list.SearchText; + + // Move the cursor to the end of the input + FilterBox.Select(FilterBox.Text.Length, 0); + } + } }