Compare commits
2 Commits
deb8d43911
...
764a8cffb8
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
764a8cffb8 | ||
|
|
e8584c1453 |
@@ -105,12 +105,12 @@
|
||||
Padding="4"
|
||||
BorderBrush="{DynamicResource BackgroundColor.Menu.SubCategory.Hover}"
|
||||
BorderThickness="1">
|
||||
<ScrollViewer x:Name="PART_CategoryScrollViewer"
|
||||
<ScrollViewer x:Name="PART_ItemsScrollViewer"
|
||||
MaxHeight="320"
|
||||
VerticalScrollBarVisibility="Auto"
|
||||
Background="Transparent"
|
||||
BorderThickness="0"
|
||||
PreviewMouseWheel="CategoryScrollViewer_PreviewMouseWheel">
|
||||
PreviewMouseWheel="ItemsScrollViewer_PreviewMouseWheel">
|
||||
<TreeView x:Name="PART_TreeView"
|
||||
Background="Transparent"
|
||||
BorderThickness="0"
|
||||
|
||||
@@ -8,7 +8,6 @@ using System.Windows.Controls;
|
||||
using System.Windows.Input;
|
||||
using System.Windows.Media;
|
||||
using System.Windows.Threading;
|
||||
using static C4IT.Logging.cLogManager;
|
||||
|
||||
namespace FasdDesktopUi.Basics.UserControls
|
||||
{
|
||||
@@ -22,7 +21,7 @@ namespace FasdDesktopUi.Basics.UserControls
|
||||
|
||||
private TextBox searchTextBox;
|
||||
private TreeView treeViewControl;
|
||||
private ScrollViewer categoryScrollViewer;
|
||||
private ScrollViewer itemsScrollViewer;
|
||||
|
||||
public ObservableCollection<HierarchicalSelectionItem> VisibleItems => visibleItems;
|
||||
|
||||
@@ -41,7 +40,6 @@ namespace FasdDesktopUi.Basics.UserControls
|
||||
EnsureTemplateParts();
|
||||
if (treeViewControl != null)
|
||||
treeViewControl.ItemsSource = VisibleItems;
|
||||
UpdateDisplaySelection();
|
||||
}
|
||||
|
||||
#region DependencyProperties
|
||||
@@ -64,7 +62,6 @@ namespace FasdDesktopUi.Basics.UserControls
|
||||
{
|
||||
control.RebuildLookup();
|
||||
control.ApplyFilter(control.lastSearchText);
|
||||
control.TryExpandToSelectedItem();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -84,8 +81,8 @@ namespace FasdDesktopUi.Basics.UserControls
|
||||
{
|
||||
if (d is HierarchicalSelectionControl control)
|
||||
{
|
||||
control.LogSelectedItemChange(e.NewValue as HierarchicalSelectionItem);
|
||||
control.TryExpandToSelectedItem();
|
||||
control.SyncTreeSelectionWithSelectedItem(bringIntoView: false);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -109,13 +106,15 @@ namespace FasdDesktopUi.Basics.UserControls
|
||||
|
||||
#endregion
|
||||
|
||||
#region UI Event Handling
|
||||
|
||||
private void ComboBoxControl_DropDownOpened(object sender, EventArgs e)
|
||||
{
|
||||
EnsureTemplateParts();
|
||||
searchTextBox?.Focus();
|
||||
searchTextBox?.SelectAll();
|
||||
suppressTreeSelectionChanged = false;
|
||||
LogEntry($"[CategoryPicker] DropDownOpened. Selected={SelectedItem?.FullPath ?? "<null>"}");
|
||||
SyncTreeSelectionWithSelectedItem(bringIntoView: true);
|
||||
DropDownOpened?.Invoke(this, e);
|
||||
}
|
||||
|
||||
@@ -123,7 +122,6 @@ namespace FasdDesktopUi.Basics.UserControls
|
||||
{
|
||||
searchDelayTimer.Stop();
|
||||
suppressTreeSelectionChanged = false;
|
||||
LogEntry("[CategoryPicker] DropDownClosed");
|
||||
DropDownClosed?.Invoke(this, e);
|
||||
}
|
||||
|
||||
@@ -137,7 +135,6 @@ namespace FasdDesktopUi.Basics.UserControls
|
||||
{
|
||||
searchDelayTimer.Stop();
|
||||
lastSearchText = searchTextBox?.Text ?? string.Empty;
|
||||
LogEntry($"[CategoryPicker] Search text changed: '{lastSearchText}'");
|
||||
ApplyFilter(lastSearchText);
|
||||
}
|
||||
|
||||
@@ -152,7 +149,6 @@ namespace FasdDesktopUi.Basics.UserControls
|
||||
if (original != null && !Equals(SelectedItem, original))
|
||||
{
|
||||
SelectedItem = original;
|
||||
LogEntry($"[CategoryPicker] Tree selection changed: {original.FullPath}");
|
||||
}
|
||||
|
||||
suppressTreeSelectionChanged = true;
|
||||
@@ -160,6 +156,10 @@ namespace FasdDesktopUi.Basics.UserControls
|
||||
}
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region Data Preparation and Filtering
|
||||
|
||||
private HierarchicalSelectionItem ResolveOriginalItem(HierarchicalSelectionItem item)
|
||||
{
|
||||
if (item == null)
|
||||
@@ -203,6 +203,7 @@ namespace FasdDesktopUi.Basics.UserControls
|
||||
}
|
||||
|
||||
TryExpandToSelectedItem();
|
||||
SyncTreeSelectionWithSelectedItem(bringIntoView: false);
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -220,6 +221,9 @@ namespace FasdDesktopUi.Basics.UserControls
|
||||
clone.SetExpandedRecursive(true);
|
||||
visibleItems.Add(clone);
|
||||
}
|
||||
|
||||
// If the selected item is part of current results, keep it visually selected.
|
||||
SyncTreeSelectionWithSelectedItem(bringIntoView: false);
|
||||
}
|
||||
|
||||
private void TryExpandToSelectedItem()
|
||||
@@ -238,6 +242,101 @@ namespace FasdDesktopUi.Basics.UserControls
|
||||
}
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region Tree Selection Sync
|
||||
|
||||
private void SyncTreeSelectionWithSelectedItem(bool bringIntoView)
|
||||
{
|
||||
if (SelectedItem == null || string.IsNullOrWhiteSpace(SelectedItem.Id))
|
||||
return;
|
||||
|
||||
EnsureTemplateParts();
|
||||
if (treeViewControl == null)
|
||||
return;
|
||||
|
||||
// Wait for popup/template layout to finish so item containers are generated.
|
||||
Dispatcher.BeginInvoke(new Action(() =>
|
||||
{
|
||||
var target = FindVisibleItemById(VisibleItems, SelectedItem.Id);
|
||||
if (target == null)
|
||||
return;
|
||||
|
||||
var ancestor = target.Parent;
|
||||
while (ancestor != null)
|
||||
{
|
||||
ancestor.IsExpanded = true;
|
||||
ancestor = ancestor.Parent;
|
||||
}
|
||||
|
||||
treeViewControl.UpdateLayout();
|
||||
var targetContainer = GetTreeViewItemContainer(treeViewControl, target);
|
||||
if (targetContainer == null)
|
||||
return;
|
||||
|
||||
suppressTreeSelectionChanged = true;
|
||||
try
|
||||
{
|
||||
targetContainer.IsSelected = true;
|
||||
if (bringIntoView)
|
||||
targetContainer.BringIntoView();
|
||||
}
|
||||
finally
|
||||
{
|
||||
suppressTreeSelectionChanged = false;
|
||||
}
|
||||
}), DispatcherPriority.Loaded);
|
||||
}
|
||||
|
||||
private static HierarchicalSelectionItem FindVisibleItemById(IEnumerable<HierarchicalSelectionItem> items, string id)
|
||||
{
|
||||
if (items == null || string.IsNullOrWhiteSpace(id))
|
||||
return null;
|
||||
|
||||
foreach (var item in items)
|
||||
{
|
||||
if (item == null)
|
||||
continue;
|
||||
|
||||
if (string.Equals(item.Id, id, StringComparison.OrdinalIgnoreCase))
|
||||
return item;
|
||||
|
||||
var childMatch = FindVisibleItemById(item.Children, id);
|
||||
if (childMatch != null)
|
||||
return childMatch;
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
private static TreeViewItem GetTreeViewItemContainer(ItemsControl root, object targetItem)
|
||||
{
|
||||
if (root == null || targetItem == null)
|
||||
return null;
|
||||
|
||||
var directContainer = root.ItemContainerGenerator.ContainerFromItem(targetItem) as TreeViewItem;
|
||||
if (directContainer != null)
|
||||
return directContainer;
|
||||
|
||||
foreach (var child in root.Items)
|
||||
{
|
||||
var childContainer = root.ItemContainerGenerator.ContainerFromItem(child) as TreeViewItem;
|
||||
if (childContainer == null)
|
||||
continue;
|
||||
|
||||
childContainer.UpdateLayout();
|
||||
var result = GetTreeViewItemContainer(childContainer, targetItem);
|
||||
if (result != null)
|
||||
return result;
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region Template and Scroll Handling
|
||||
|
||||
private void EnsureTemplateParts()
|
||||
{
|
||||
if (treeViewControl == null)
|
||||
@@ -257,15 +356,15 @@ namespace FasdDesktopUi.Basics.UserControls
|
||||
searchTextBox.TextChanged += SearchTextBox_TextChanged;
|
||||
}
|
||||
|
||||
if (categoryScrollViewer == null)
|
||||
if (itemsScrollViewer == null)
|
||||
{
|
||||
categoryScrollViewer = ComboBoxControl.Template.FindName("PART_CategoryScrollViewer", ComboBoxControl) as ScrollViewer;
|
||||
itemsScrollViewer = ComboBoxControl.Template.FindName("PART_ItemsScrollViewer", ComboBoxControl) as ScrollViewer;
|
||||
}
|
||||
}
|
||||
|
||||
private void CategoryScrollViewer_PreviewMouseWheel(object sender, MouseWheelEventArgs e)
|
||||
private void ItemsScrollViewer_PreviewMouseWheel(object sender, MouseWheelEventArgs e)
|
||||
{
|
||||
var scroller = categoryScrollViewer ?? sender as ScrollViewer;
|
||||
var scroller = itemsScrollViewer ?? sender as ScrollViewer;
|
||||
if (scroller == null || scroller.ScrollableHeight <= 0)
|
||||
return;
|
||||
|
||||
@@ -300,23 +399,9 @@ namespace FasdDesktopUi.Basics.UserControls
|
||||
e.Handled = true;
|
||||
}
|
||||
|
||||
private void UpdateDisplaySelection()
|
||||
{
|
||||
// Display handled by template TextBlock bound to SelectedItem.FullPath.
|
||||
}
|
||||
#endregion
|
||||
|
||||
private void LogSelectedItemChange(HierarchicalSelectionItem newValue)
|
||||
{
|
||||
var description = "<null>";
|
||||
if (newValue != null)
|
||||
{
|
||||
var fullPath = string.IsNullOrWhiteSpace(newValue.FullPath) ? newValue.DisplayName : newValue.FullPath;
|
||||
var id = string.IsNullOrWhiteSpace(newValue.Id) ? "<null>" : newValue.Id;
|
||||
description = $"{fullPath} (Id={id})";
|
||||
}
|
||||
|
||||
LogEntry($"[CategoryPicker] DependencyProperty SelectedItem updated -> {description}");
|
||||
}
|
||||
#region Keyboard
|
||||
|
||||
protected override void OnPreviewKeyDown(KeyEventArgs e)
|
||||
{
|
||||
@@ -338,5 +423,7 @@ namespace FasdDesktopUi.Basics.UserControls
|
||||
e.Handled = true;
|
||||
}
|
||||
}
|
||||
|
||||
#endregion
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,5 +1,4 @@
|
||||
<settingspagebase:SettingsPageBase
|
||||
xmlns:settingspagebase="clr-namespace:FasdDesktopUi.Pages.SettingsPage"
|
||||
<settingspagebase:SettingsPageBase xmlns:settingspagebase="clr-namespace:FasdDesktopUi.Pages.SettingsPage"
|
||||
x:Class="FasdDesktopUi.Pages.SettingsPage.SettingsPageView"
|
||||
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
|
||||
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
|
||||
@@ -23,7 +22,9 @@
|
||||
WindowStartupLocation="CenterScreen"
|
||||
Initialized="Window_Initialized"
|
||||
x:Name="SettingsWindow"
|
||||
KeyDown="SettingsWindow_KeyDown" Closed="SettingsWindow_Closed" IsVisibleChanged="SettingsWindow_IsVisibleChanged">
|
||||
KeyDown="SettingsWindow_KeyDown"
|
||||
Closed="SettingsWindow_Closed"
|
||||
IsVisibleChanged="SettingsWindow_IsVisibleChanged">
|
||||
|
||||
<settingspagebase:SettingsPageBase.Resources>
|
||||
<vc:LanguageDefinitionsConverter x:Key="LanguageConverter" />
|
||||
@@ -203,25 +204,39 @@
|
||||
SelectedCountryCode="GB" />
|
||||
</StackPanel>
|
||||
|
||||
<StackPanel x:Name="ShouldSkipSlimViewLabel" Orientation="Horizontal">
|
||||
<StackPanel x:Name="ShouldSkipSlimViewLabel"
|
||||
Orientation="Horizontal">
|
||||
<TextBlock Text="{Binding Converter={StaticResource LanguageConverter}, ConverterParameter=Menu.ShouldSkipSlimView}" />
|
||||
<ico:AdaptableIcon x:Name="ShouldSkipSlimViewPolicy" SelectedInternIcon="lock_closed" Margin="-25,-5,0,0" IconWidth="23" IconHeight="23" Visibility="Collapsed"/>
|
||||
<ico:AdaptableIcon x:Name="ShouldSkipSlimViewPolicy"
|
||||
SelectedInternIcon="lock_closed"
|
||||
PrimaryIconColor="{DynamicResource Color.Menu.Icon}"
|
||||
Margin="-25,-5,0,0"
|
||||
IconWidth="23"
|
||||
IconHeight="23"
|
||||
Visibility="Collapsed" />
|
||||
</StackPanel>
|
||||
|
||||
<CheckBox x:Name="ShouldSkipSlimViewCheckBox"
|
||||
Style="{DynamicResource ToggleSwitch}"
|
||||
IsChecked="{Binding ElementName=SettingsWindow, Path=ShouldSkipSlimView}"
|
||||
HorizontalAlignment="Left"
|
||||
Margin="0,3,0,10"
|
||||
>
|
||||
Margin="0,3,0,10">
|
||||
</CheckBox>
|
||||
|
||||
<StackPanel x:Name="PositionOfSmallViewsLabel" Orientation="Horizontal">
|
||||
<StackPanel x:Name="PositionOfSmallViewsLabel"
|
||||
Orientation="Horizontal">
|
||||
<TextBlock Text="{Binding Converter={StaticResource LanguageConverter}, ConverterParameter=Menu.PositionOfSmallViews}" />
|
||||
<ico:AdaptableIcon x:Name="PositionOfSmallViewsPolicy" SelectedInternIcon="lock_closed" Margin="-25,-5,0,0" IconWidth="23" IconHeight="23" Visibility="Collapsed"/>
|
||||
<ico:AdaptableIcon x:Name="PositionOfSmallViewsPolicy"
|
||||
SelectedInternIcon="lock_closed"
|
||||
PrimaryIconColor="{DynamicResource Color.Menu.Icon}"
|
||||
Margin="-25,-5,0,0"
|
||||
IconWidth="23"
|
||||
IconHeight="23"
|
||||
Visibility="Collapsed" />
|
||||
</StackPanel>
|
||||
|
||||
<Grid x:Name="PositionOfSmallViewsInput" Grid.IsSharedSizeScope="True"
|
||||
<Grid x:Name="PositionOfSmallViewsInput"
|
||||
Grid.IsSharedSizeScope="True"
|
||||
HorizontalAlignment="Left">
|
||||
<Grid.ColumnDefinitions>
|
||||
<ColumnDefinition Width="Auto"
|
||||
@@ -269,12 +284,20 @@
|
||||
|
||||
</Grid>
|
||||
|
||||
<StackPanel x:Name="PositionOfFavouriteBarLabel" Orientation="Horizontal">
|
||||
<StackPanel x:Name="PositionOfFavouriteBarLabel"
|
||||
Orientation="Horizontal">
|
||||
<TextBlock Text="{Binding Converter={StaticResource LanguageConverter}, ConverterParameter=Menu.PositionOfFavouriteBar}" />
|
||||
<ico:AdaptableIcon x:Name="PositionOfFavouriteBarPolicy" SelectedInternIcon="lock_closed" Margin="-25,-5,0,0" IconWidth="23" IconHeight="23" Visibility="Collapsed"/>
|
||||
<ico:AdaptableIcon x:Name="PositionOfFavouriteBarPolicy"
|
||||
SelectedInternIcon="lock_closed"
|
||||
PrimaryIconColor="{DynamicResource Color.Menu.Icon}"
|
||||
Margin="-25,-5,0,0"
|
||||
IconWidth="23"
|
||||
IconHeight="23"
|
||||
Visibility="Collapsed" />
|
||||
</StackPanel>
|
||||
|
||||
<Grid x:Name="PositionOfFavouriteBarInput" Grid.IsSharedSizeScope="True"
|
||||
<Grid x:Name="PositionOfFavouriteBarInput"
|
||||
Grid.IsSharedSizeScope="True"
|
||||
HorizontalAlignment="Left">
|
||||
<Grid.ColumnDefinitions>
|
||||
<ColumnDefinition Width="Auto"
|
||||
|
||||
Reference in New Issue
Block a user