diff --git a/src/Files.App/Actions/Display/GroupAction.cs b/src/Files.App/Actions/Display/GroupAction.cs
index e0bf7d3e1930..7020496f2664 100644
--- a/src/Files.App/Actions/Display/GroupAction.cs
+++ b/src/Files.App/Actions/Display/GroupAction.cs
@@ -177,6 +177,7 @@ public GroupByAction()
public Task ExecuteAsync(object? parameter = null)
{
DisplayContext.GroupOption = GroupOption;
+ LayoutHelpers.UpdateOpenTabsPreferences([nameof(LayoutPreferencesItem.DirectoryGroupOption)]);
return Task.CompletedTask;
}
@@ -377,6 +378,10 @@ public Task ExecuteAsync(object? parameter = null)
{
DisplayContext.GroupOption = GroupOption;
DisplayContext.GroupByDateUnit = GroupByDateUnit;
+ LayoutHelpers.UpdateOpenTabsPreferences([
+ nameof(LayoutPreferencesItem.DirectoryGroupOption),
+ nameof(LayoutPreferencesItem.DirectoryGroupByDateUnit)
+ ]);
return Task.CompletedTask;
}
@@ -425,6 +430,7 @@ public GroupAscendingAction()
public Task ExecuteAsync(object? parameter = null)
{
context.GroupDirection = SortDirection.Ascending;
+ LayoutHelpers.UpdateOpenTabsPreferences([nameof(LayoutPreferencesItem.DirectoryGroupDirection)]);
return Task.CompletedTask;
}
@@ -469,6 +475,7 @@ public GroupDescendingAction()
public Task ExecuteAsync(object? parameter = null)
{
context.GroupDirection = SortDirection.Descending;
+ LayoutHelpers.UpdateOpenTabsPreferences([nameof(LayoutPreferencesItem.DirectoryGroupDirection)]);
return Task.CompletedTask;
}
@@ -505,6 +512,7 @@ public ToggleGroupDirectionAction()
public Task ExecuteAsync(object? parameter = null)
{
context.GroupDirection = context.SortDirection is SortDirection.Descending ? SortDirection.Ascending : SortDirection.Descending;
+ LayoutHelpers.UpdateOpenTabsPreferences([nameof(LayoutPreferencesItem.DirectoryGroupDirection)]);
return Task.CompletedTask;
}
@@ -536,6 +544,7 @@ public GroupByYearAction()
public Task ExecuteAsync(object? parameter = null)
{
context.GroupByDateUnit = GroupByDateUnit.Year;
+ LayoutHelpers.UpdateOpenTabsPreferences([nameof(LayoutPreferencesItem.DirectoryGroupByDateUnit)]);
return Task.CompletedTask;
}
@@ -580,6 +589,7 @@ public GroupByMonthAction()
public Task ExecuteAsync(object? parameter = null)
{
context.GroupByDateUnit = GroupByDateUnit.Month;
+ LayoutHelpers.UpdateOpenTabsPreferences([nameof(LayoutPreferencesItem.DirectoryGroupByDateUnit)]);
return Task.CompletedTask;
}
@@ -621,6 +631,7 @@ public Task ExecuteAsync(object? parameter = null)
GroupByDateUnit.Month => GroupByDateUnit.Day,
_ => GroupByDateUnit.Year
};
+ LayoutHelpers.UpdateOpenTabsPreferences([nameof(LayoutPreferencesItem.DirectoryGroupByDateUnit)]);
return Task.CompletedTask;
}
diff --git a/src/Files.App/Actions/Display/SortAction.cs b/src/Files.App/Actions/Display/SortAction.cs
index 4c5b9742259e..ad7e85d7d67f 100644
--- a/src/Files.App/Actions/Display/SortAction.cs
+++ b/src/Files.App/Actions/Display/SortAction.cs
@@ -165,6 +165,7 @@ public SortByAction()
public Task ExecuteAsync(object? parameter = null)
{
displayContext.SortOption = SortOption;
+ LayoutHelpers.UpdateOpenTabsPreferences([nameof(LayoutPreferencesItem.DirectorySortOption)]);
return Task.CompletedTask;
}
@@ -207,6 +208,7 @@ public SortAscendingAction()
public Task ExecuteAsync(object? parameter = null)
{
context.SortDirection = SortDirection.Ascending;
+ LayoutHelpers.UpdateOpenTabsPreferences([nameof(LayoutPreferencesItem.DirectorySortDirection)]);
return Task.CompletedTask;
}
@@ -241,6 +243,7 @@ public SortDescendingAction()
public Task ExecuteAsync(object? parameter = null)
{
context.SortDirection = SortDirection.Descending;
+ LayoutHelpers.UpdateOpenTabsPreferences([nameof(LayoutPreferencesItem.DirectorySortDirection)]);
return Task.CompletedTask;
}
@@ -274,6 +277,8 @@ context.SortDirection is SortDirection.Descending
? SortDirection.Ascending
: SortDirection.Descending;
+ LayoutHelpers.UpdateOpenTabsPreferences([nameof(LayoutPreferencesItem.DirectorySortDirection)]);
+
return Task.CompletedTask;
}
}
diff --git a/src/Files.App/Actions/Display/SortFilesAndFoldersTogetherAction.cs b/src/Files.App/Actions/Display/SortFilesAndFoldersTogetherAction.cs
index e91ea79c8bc4..f58b3ce0f1b2 100644
--- a/src/Files.App/Actions/Display/SortFilesAndFoldersTogetherAction.cs
+++ b/src/Files.App/Actions/Display/SortFilesAndFoldersTogetherAction.cs
@@ -26,6 +26,7 @@ public SortFilesAndFoldersTogetherAction()
public Task ExecuteAsync(object? parameter = null)
{
context.SortDirectoriesAlongsideFiles = true;
+ LayoutHelpers.UpdateOpenTabsPreferences([nameof(LayoutPreferencesItem.SortDirectoriesAlongsideFiles)]);
return Task.CompletedTask;
}
diff --git a/src/Files.App/Actions/Display/SortFilesFirstAction.cs b/src/Files.App/Actions/Display/SortFilesFirstAction.cs
index 8db1fc77c1fd..e6f324684826 100644
--- a/src/Files.App/Actions/Display/SortFilesFirstAction.cs
+++ b/src/Files.App/Actions/Display/SortFilesFirstAction.cs
@@ -27,6 +27,10 @@ public Task ExecuteAsync(object? parameter = null)
{
context.SortFilesFirst = true;
context.SortDirectoriesAlongsideFiles = false;
+ LayoutHelpers.UpdateOpenTabsPreferences([
+ nameof(LayoutPreferencesItem.SortFilesFirst),
+ nameof(LayoutPreferencesItem.SortDirectoriesAlongsideFiles)
+ ]);
return Task.CompletedTask;
}
diff --git a/src/Files.App/Actions/Display/SortFoldersFirstAction.cs b/src/Files.App/Actions/Display/SortFoldersFirstAction.cs
index d1aaaaf587c1..8ac73746316d 100644
--- a/src/Files.App/Actions/Display/SortFoldersFirstAction.cs
+++ b/src/Files.App/Actions/Display/SortFoldersFirstAction.cs
@@ -27,6 +27,10 @@ public Task ExecuteAsync(object? parameter = null)
{
context.SortFilesFirst = false;
context.SortDirectoriesAlongsideFiles = false;
+ LayoutHelpers.UpdateOpenTabsPreferences([
+ nameof(LayoutPreferencesItem.SortFilesFirst),
+ nameof(LayoutPreferencesItem.SortDirectoriesAlongsideFiles)
+ ]);
return Task.CompletedTask;
}
diff --git a/src/Files.App/Data/Contracts/IShellPanesPage.cs b/src/Files.App/Data/Contracts/IShellPanesPage.cs
index 9eb40f0971fc..37082471a165 100644
--- a/src/Files.App/Data/Contracts/IShellPanesPage.cs
+++ b/src/Files.App/Data/Contracts/IShellPanesPage.cs
@@ -58,5 +58,13 @@ public interface IShellPanesPage : IDisposable, INotifyPropertyChanged
/// Focuses the other pane.
///
public void FocusOtherPane();
+
+ ///
+ /// Updates the layout of open panes.
+ ///
+ /// The path of panes to update
+ /// The preferences to update
+ /// Whether the active pane should be updated or not
+ public void UpdatePanesLayout(string targetPath, string[] preferences, bool includeActivePane = false);
}
}
diff --git a/src/Files.App/Helpers/Layout/LayoutHelpers.cs b/src/Files.App/Helpers/Layout/LayoutHelpers.cs
new file mode 100644
index 000000000000..7d48183ad368
--- /dev/null
+++ b/src/Files.App/Helpers/Layout/LayoutHelpers.cs
@@ -0,0 +1,22 @@
+// Copyright (c) Files Community
+// Licensed under the MIT License.
+
+namespace Files.App.Helpers
+{
+ static class LayoutHelpers
+ {
+ public static void UpdateOpenTabsPreferences(string[] preferences)
+ {
+ var multitaskingContext = Ioc.Default.GetRequiredService();
+ var tabs = multitaskingContext.Control?.GetAllTabInstances();
+ var activePath = ((ShellPanesPage)multitaskingContext.CurrentTabItem.TabItemContent)?.ActivePane?.TabBarItemParameter?.NavigationParameter as string;
+ if (tabs is null || activePath is null)
+ return;
+
+ for (int i = 0; i < tabs.Count; i++)
+ {
+ ((ShellPanesPage)tabs[i]).UpdatePanesLayout(activePath, preferences, i != multitaskingContext.CurrentTabIndex);
+ }
+ }
+ }
+}
diff --git a/src/Files.App/Helpers/Layout/LayoutPreferencesManager.cs b/src/Files.App/Helpers/Layout/LayoutPreferencesManager.cs
index 7f17895d5c85..6cf46cbdd03c 100644
--- a/src/Files.App/Helpers/Layout/LayoutPreferencesManager.cs
+++ b/src/Files.App/Helpers/Layout/LayoutPreferencesManager.cs
@@ -265,6 +265,44 @@ public Type GetLayoutType(string path, bool changeLayoutMode = true)
};
}
+ public void UpdateGroupAndSortOptions(string? path, string[] properties)
+ {
+ if (string.IsNullOrWhiteSpace(path))
+ return;
+
+ var preferencesItem = GetLayoutPreferencesForPath(path);
+ if (preferencesItem is null)
+ return;
+
+ foreach (var property in properties)
+ {
+ switch (property)
+ {
+ case nameof(preferencesItem.DirectorySortOption):
+ DirectorySortOption = preferencesItem.DirectorySortOption;
+ break;
+ case nameof(preferencesItem.DirectorySortDirection):
+ DirectorySortDirection = preferencesItem.DirectorySortDirection;
+ break;
+ case nameof(preferencesItem.DirectoryGroupOption):
+ DirectoryGroupOption = preferencesItem.DirectoryGroupOption;
+ break;
+ case nameof(preferencesItem.DirectoryGroupByDateUnit):
+ DirectoryGroupByDateUnit = preferencesItem.DirectoryGroupByDateUnit;
+ break;
+ case nameof(preferencesItem.DirectoryGroupDirection):
+ DirectoryGroupDirection = preferencesItem.DirectoryGroupDirection;
+ break;
+ case nameof(preferencesItem.SortDirectoriesAlongsideFiles):
+ SortDirectoriesAlongsideFiles = preferencesItem.SortDirectoriesAlongsideFiles;
+ break;
+ case nameof(preferencesItem.SortFilesFirst):
+ SortFilesFirst = preferencesItem.SortFilesFirst;
+ break;
+ }
+ }
+ }
+
public bool IsPathUsingDefaultLayout(string? path)
{
return UserSettingsService.LayoutSettingsService.SyncFolderPreferencesAcrossDirectories ||
diff --git a/src/Files.App/Views/ShellPanesPage.xaml.cs b/src/Files.App/Views/ShellPanesPage.xaml.cs
index 7298d6d1c5ad..daa78baa9d15 100644
--- a/src/Files.App/Views/ShellPanesPage.xaml.cs
+++ b/src/Files.App/Views/ShellPanesPage.xaml.cs
@@ -19,6 +19,7 @@ public sealed partial class ShellPanesPage : Page, IShellPanesPage, ITabBarItemC
// Dependency injections
private IGeneralSettingsService GeneralSettingsService { get; } = Ioc.Default.GetRequiredService();
+ private ILayoutSettingsService LayoutSettingsService { get; } = Ioc.Default.GetRequiredService();
private AppModel AppModel { get; } = Ioc.Default.GetRequiredService();
// Constants
@@ -356,6 +357,23 @@ public void FocusOtherPane()
GetPane(0)?.Focus(FocusState.Programmatic);
}
+ ///
+ public void UpdatePanesLayout(string targetPath, string[] preferences, bool includeActivePane = false)
+ {
+ foreach (var pane in GetPanes())
+ {
+ var path = pane.ShellViewModel.CurrentFolder?.ItemPath;
+ if ((includeActivePane || pane != ActivePane) &&
+ (LayoutSettingsService.SyncFolderPreferencesAcrossDirectories ||
+ path is not null &&
+ path.Equals(targetPath, StringComparison.OrdinalIgnoreCase)))
+ {
+ var page = pane.SlimContentPage as BaseLayoutPage;
+ page?.FolderSettings?.UpdateGroupAndSortOptions(path, preferences);
+ }
+ }
+ }
+
// Private methods
private ModernShellPage? GetPane(int index = -1)