diff --git a/src/Files.App.Controls/Omnibar/EventArgs.cs b/src/Files.App.Controls/Omnibar/EventArgs.cs
index 6f0d5ca518ba..e702c0d8d3cb 100644
--- a/src/Files.App.Controls/Omnibar/EventArgs.cs
+++ b/src/Files.App.Controls/Omnibar/EventArgs.cs
@@ -8,4 +8,6 @@ public record class OmnibarQuerySubmittedEventArgs(OmnibarMode Mode, object? Ite
public record class OmnibarSuggestionChosenEventArgs(OmnibarMode Mode, object SelectedItem);
public record class OmnibarTextChangedEventArgs(OmnibarMode Mode, OmnibarTextChangeReason Reason);
+
+ public record class OmnibarModeChangedEventArgs(OmnibarMode? OldMode, OmnibarMode NewMode);
}
diff --git a/src/Files.App.Controls/Omnibar/IOmnibarTextMemberPathProvider.cs b/src/Files.App.Controls/Omnibar/IOmnibarTextMemberPathProvider.cs
index 41f798da7e7f..d38f0d3aeb8c 100644
--- a/src/Files.App.Controls/Omnibar/IOmnibarTextMemberPathProvider.cs
+++ b/src/Files.App.Controls/Omnibar/IOmnibarTextMemberPathProvider.cs
@@ -4,7 +4,7 @@
namespace Files.App.Controls
{
///
- /// An interface that provides a way to get the text member path of .
+ /// An interface that provides a way to get the text member path of .
///
///
/// An alternative to this interface is to use an powered by CsWinRT.
diff --git a/src/Files.App.Controls/Omnibar/Omnibar.Properties.cs b/src/Files.App.Controls/Omnibar/Omnibar.Properties.cs
index fb3cc94db2a5..cd156dc4cea2 100644
--- a/src/Files.App.Controls/Omnibar/Omnibar.Properties.cs
+++ b/src/Files.App.Controls/Omnibar/Omnibar.Properties.cs
@@ -28,7 +28,7 @@ partial void OnCurrentSelectedModePropertyChanged(DependencyPropertyChangedEvent
return;
ChangeMode(e.OldValue as OmnibarMode, newMode);
- CurrentSelectedModeName = newMode.ModeName;
+ CurrentSelectedModeName = newMode.Name;
}
partial void OnCurrentSelectedModeNameChanged(string? newValue)
diff --git a/src/Files.App.Controls/Omnibar/Omnibar.cs b/src/Files.App.Controls/Omnibar/Omnibar.cs
index 6ab43cea4e14..e13c04274558 100644
--- a/src/Files.App.Controls/Omnibar/Omnibar.cs
+++ b/src/Files.App.Controls/Omnibar/Omnibar.cs
@@ -41,6 +41,7 @@ public partial class Omnibar : Control
public event TypedEventHandler? QuerySubmitted;
public event TypedEventHandler? SuggestionChosen;
public event TypedEventHandler? TextChanged;
+ public event TypedEventHandler? ModeChanged;
// Constructor
@@ -155,9 +156,11 @@ protected void ChangeMode(OmnibarMode? oldMode, OmnibarMode newMode)
VisualStateManager.GoToState(newMode, "Focused", true);
newMode.IsTabStop = false;
+ ModeChanged?.Invoke(this, new(oldMode, newMode!));
+
_textBox.PlaceholderText = newMode.PlaceholderText ?? string.Empty;
- _textBoxSuggestionsListView.ItemTemplate = newMode.SuggestionItemTemplate;
- _textBoxSuggestionsListView.ItemsSource = newMode.SuggestionItemsSource;
+ _textBoxSuggestionsListView.ItemTemplate = newMode.ItemTemplate;
+ _textBoxSuggestionsListView.ItemsSource = newMode.ItemsSource;
if (newMode.IsAutoFocusEnabled)
{
@@ -179,10 +182,10 @@ protected void ChangeMode(OmnibarMode? oldMode, OmnibarMode newMode)
{
VisualStateManager.GoToState(_textBox, "InputAreaVisible", true);
}
-
- TryToggleIsSuggestionsPopupOpen(true);
}
+ TryToggleIsSuggestionsPopupOpen(true);
+
// Remove the reposition transition from the all modes
foreach (var mode in Modes)
{
@@ -196,12 +199,17 @@ internal protected void FocusTextBox()
_textBox.Focus(FocusState.Keyboard);
}
- public bool TryToggleIsSuggestionsPopupOpen(bool wantToOpen)
+ internal protected bool TryToggleIsSuggestionsPopupOpen(bool wantToOpen)
{
- if (wantToOpen && (!IsFocused || CurrentSelectedMode?.SuggestionItemsSource is null || (CurrentSelectedMode?.SuggestionItemsSource is IList collection && collection.Count is 0)) ||
- _textBoxSuggestionsPopup is null)
+ if (_textBoxSuggestionsPopup is null)
return false;
+ if (wantToOpen && (!IsFocused || CurrentSelectedMode?.ItemsSource is null || (CurrentSelectedMode?.ItemsSource is IList collection && collection.Count is 0)))
+ {
+ _textBoxSuggestionsPopup.IsOpen = false;
+ return false;
+ }
+
_textBoxSuggestionsPopup.IsOpen = wantToOpen;
return false;
diff --git a/src/Files.App.Controls/Omnibar/Omnibar.xaml b/src/Files.App.Controls/Omnibar/Omnibar.xaml
index 26c90b65eb0f..c08f2fc5de71 100644
--- a/src/Files.App.Controls/Omnibar/Omnibar.xaml
+++ b/src/Files.App.Controls/Omnibar/Omnibar.xaml
@@ -145,11 +145,21 @@
-
+
+
+
+
+
-
+
+
@@ -181,13 +192,16 @@
-
+
+
+
-
+
+
diff --git a/src/Files.App.Controls/Omnibar/OmnibarMode.Properties.cs b/src/Files.App.Controls/Omnibar/OmnibarMode.Properties.cs
index 6245ebbca02f..3130d95d305c 100644
--- a/src/Files.App.Controls/Omnibar/OmnibarMode.Properties.cs
+++ b/src/Files.App.Controls/Omnibar/OmnibarMode.Properties.cs
@@ -28,15 +28,9 @@ public partial class OmnibarMode
[GeneratedDependencyProperty]
public partial FrameworkElement? IconOnInactive { get; set; }
- [GeneratedDependencyProperty]
- public partial object? SuggestionItemsSource { get; set; }
-
- [GeneratedDependencyProperty]
- public partial DataTemplate? SuggestionItemTemplate { get; set; }
-
[GeneratedDependencyProperty]
///
- /// Implement in to get the text member path from the suggestion item correctly.
+ /// Implement in to get the text member path from the suggestion item correctly.
///
public partial string? TextMemberPath { get; set; }
diff --git a/src/Files.App.Controls/Omnibar/OmnibarMode.cs b/src/Files.App.Controls/Omnibar/OmnibarMode.cs
index b4d5927383a9..1a3b49e975d9 100644
--- a/src/Files.App.Controls/Omnibar/OmnibarMode.cs
+++ b/src/Files.App.Controls/Omnibar/OmnibarMode.cs
@@ -6,7 +6,7 @@
namespace Files.App.Controls
{
[DebuggerDisplay("{" + nameof(ToString) + "(),nq}")]
- public partial class OmnibarMode : Control
+ public partial class OmnibarMode : ItemsControl
{
// Constants
@@ -66,6 +66,14 @@ protected override void OnKeyUp(KeyRoutedEventArgs args)
}
}
+ protected override void OnItemsChanged(object e)
+ {
+ base.OnItemsChanged(e);
+
+ if (_ownerRef is not null && _ownerRef.TryGetTarget(out var owner))
+ owner.TryToggleIsSuggestionsPopupOpen(true);
+ }
+
private void OmnibarMode_Loaded(object sender, RoutedEventArgs e)
{
// Set this mode as the current mode if it is the default mode
diff --git a/src/Files.App/UserControls/NavigationToolbar.xaml b/src/Files.App/UserControls/NavigationToolbar.xaml
index ef9e511e009c..eec566ce5c64 100644
--- a/src/Files.App/UserControls/NavigationToolbar.xaml
+++ b/src/Files.App/UserControls/NavigationToolbar.xaml
@@ -321,7 +321,6 @@
x:Name="Omnibar"
Grid.Column="1"
x:Load="{x:Bind ViewModel.EnableOmnibar, Mode=OneWay}"
- CurrentSelectedMode="{x:Bind ViewModel.OmnibarCurrentSelectedMode, Mode=TwoWay}"
CurrentSelectedModeName="{x:Bind ViewModel.OmnibarCurrentSelectedModeName, Mode=TwoWay}"
IsFocused="{x:Bind ViewModel.IsOmnibarFocused, Mode=TwoWay}"
LostFocus="Omnibar_LostFocus"
@@ -334,9 +333,9 @@
IconOnActive="{controls:ThemedIconMarkup Style={StaticResource App.ThemedIcons.Omnibar.Path}, IsFilled=True}"
IconOnInactive="{controls:ThemedIconMarkup Style={StaticResource App.ThemedIcons.Omnibar.Path}, IconType=Outline}"
IsDefault="True"
+ ItemsSource="{x:Bind ViewModel.PathModeSuggestionItems, Mode=OneWay}"
ModeName="{x:Bind Commands.EditPath.LabelWithHotKey, Mode=OneWay}"
PlaceholderText="{helpers:ResourceString Name=OmnibarPathModeTextPlaceholder}"
- SuggestionItemsSource="{x:Bind ViewModel.PathModeSuggestionItems, Mode=OneWay}"
Text="{x:Bind ViewModel.PathText, Mode=TwoWay}"
TextMemberPath="Path">
@@ -365,11 +364,11 @@
-
+
-
+
-
+
@@ -422,7 +421,7 @@
HotKeys="{x:Bind HotKeys}" />
-
+
();
private readonly ICommandManager Commands = Ioc.Default.GetRequiredService();
private readonly StatusCenterViewModel OngoingTasksViewModel = Ioc.Default.GetRequiredService();
+ private readonly IContentPageContext ContentPageContext = Ioc.Default.GetRequiredService();
// Properties
@@ -413,9 +414,9 @@ private void BreadcrumbBar_ItemDropDownFlyoutClosed(object sender, BreadcrumbBar
private void Omnibar_LostFocus(object sender, RoutedEventArgs e)
{
- if (ViewModel.OmnibarCurrentSelectedMode == OmnibarCommandPaletteMode)
+ if (Omnibar.CurrentSelectedMode == OmnibarCommandPaletteMode)
{
- ViewModel.OmnibarCurrentSelectedMode = OmnibarPathMode;
+ Omnibar.CurrentSelectedMode = OmnibarPathMode;
ViewModel.OmnibarCommandPaletteModeText = string.Empty;
}
}
diff --git a/src/Files.App/ViewModels/UserControls/NavigationToolbarViewModel.cs b/src/Files.App/ViewModels/UserControls/NavigationToolbarViewModel.cs
index 8332c2aa3a04..216f0835c966 100644
--- a/src/Files.App/ViewModels/UserControls/NavigationToolbarViewModel.cs
+++ b/src/Files.App/ViewModels/UserControls/NavigationToolbarViewModel.cs
@@ -4,6 +4,7 @@
using CommunityToolkit.WinUI;
using Files.App.Controls;
using Files.Shared.Helpers;
+using Microsoft.Extensions.Logging;
using Microsoft.UI.Dispatching;
using Microsoft.UI.Xaml;
using Microsoft.UI.Xaml.Controls;
@@ -242,7 +243,7 @@ public bool IsOmnibarFocused
if (value)
{
- switch (OmnibarCurrentSelectedMode.Name)
+ switch (OmnibarCurrentSelectedModeName)
{
case OmnibarPathModeName:
PathText =
@@ -263,11 +264,34 @@ public bool IsOmnibarFocused
}
}
- private OmnibarMode _OmnibarCurrentSelectedMode;
- public OmnibarMode OmnibarCurrentSelectedMode { get => _OmnibarCurrentSelectedMode; set => SetProperty(ref _OmnibarCurrentSelectedMode, value); }
-
- private string _OmnibarCurrentSelectedModeName;
- public string OmnibarCurrentSelectedModeName { get => _OmnibarCurrentSelectedModeName; set => SetProperty(ref _OmnibarCurrentSelectedModeName, value); }
+ private string _OmnibarCurrentSelectedModeName = OmnibarPathModeName;
+ public string OmnibarCurrentSelectedModeName
+ {
+ get => _OmnibarCurrentSelectedModeName;
+ set
+ {
+ if (SetProperty(ref _OmnibarCurrentSelectedModeName, value) && IsOmnibarFocused)
+ {
+ switch (value)
+ {
+ case OmnibarPathModeName:
+ PathText =
+ string.IsNullOrEmpty(ContentPageContext.ShellPage?.ShellViewModel?.WorkingDirectory)
+ ? Constants.UserEnvironmentPaths.HomePath
+ : ContentPageContext.ShellPage.ShellViewModel.WorkingDirectory;
+ _ = PopulateOmnibarSuggestionsForPathMode();
+ break;
+ case OmnibarPaletteModeName:
+ PopulateOmnibarSuggestionsForCommandPaletteMode();
+ break;
+ case OmnibarSearchModeName:
+ break;
+ default:
+ break;
+ }
+ }
+ }
+ }
private CurrentInstanceViewModel _InstanceViewModel;
public CurrentInstanceViewModel InstanceViewModel
@@ -738,7 +762,6 @@ await DialogDisplayHelper.ShowDialogAsync(Strings.InvalidItemDialogTitle.GetLoca
}
PathControlDisplayText = ContentPageContext.ShellPage.ShellViewModel.WorkingDirectory;
- IsOmnibarFocused = false;
}
public void PathBoxItem_PreviewKeyDown(object sender, KeyRoutedEventArgs e)
@@ -1077,6 +1100,8 @@ private static async Task LaunchApplicationFromPath(string currentInput, s
public async Task PopulateOmnibarSuggestionsForPathMode()
{
+ PathModeSuggestionItems.Clear();
+
var result = await SafetyExtensions.IgnoreExceptions((Func>)(async () =>
{
List? newSuggestions = [];
@@ -1117,9 +1142,7 @@ public async Task PopulateOmnibarSuggestionsForPathMode()
// If there are no suggestions, show "No suggestions"
if (newSuggestions.Count is 0)
- {
- AddNoResultsItem();
- }
+ return false;
// Check whether at least one item is in common between the old and the new suggestions
// since the suggestions popup becoming empty causes flickering
diff --git a/tests/Files.App.UITests/Views/OmnibarPage.xaml b/tests/Files.App.UITests/Views/OmnibarPage.xaml
index 26a4a1604835..4ca5f82a5a0b 100644
--- a/tests/Files.App.UITests/Views/OmnibarPage.xaml
+++ b/tests/Files.App.UITests/Views/OmnibarPage.xaml
@@ -50,12 +50,12 @@
+ SuggestionItemsSource="{x:Bind Omnibar1_PaletteSuggestions, Mode=OneWay}"
+ TextMemberPath="{x:Bind Omnibar1_TextMemberPathForPaletteMode}">