123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258 |
- using System;
- using System.Linq;
- using System.Windows;
- using HandyControl.Data;
- namespace HandyControl.Controls;
- public class SideMenu : HeaderedSimpleItemsControl
- {
- private SideMenuItem _selectedItem;
- private SideMenuItem _selectedHeader;
- private bool _isItemSelected;
- public SideMenu()
- {
- AddHandler(SideMenuItem.SelectedEvent, new RoutedEventHandler(SideMenuItemSelected));
- Loaded += (s, e) => Init();
- }
- protected override void Refresh()
- {
- base.Refresh();
- Init();
- }
- private void Init()
- {
- if (ItemsHost == null) return;
- OnExpandModeChanged(ExpandMode);
- }
- private void SideMenuItemSelected(object sender, RoutedEventArgs e)
- {
- if (e.OriginalSource is SideMenuItem item)
- {
- if (item.Role == SideMenuItemRole.Item)
- {
- _isItemSelected = true;
- if (Equals(item, _selectedItem)) return;
- if (_selectedItem != null)
- {
- _selectedItem.IsSelected = false;
- }
- _selectedItem = item;
- _selectedItem.IsSelected = true;
- RaiseEvent(new FunctionEventArgs<object>(SelectionChangedEvent, this)
- {
- Info = e.OriginalSource
- });
- }
- else
- {
- if (!Equals(item, _selectedHeader))
- {
- if (_selectedHeader != null)
- {
- if (ExpandMode == ExpandMode.Freedom && item.ItemsHost.IsVisible && !_isItemSelected)
- {
- item.IsSelected = false;
- SwitchPanelArea(item);
- return;
- }
- _selectedHeader.IsSelected = false;
- if (ExpandMode != ExpandMode.Freedom)
- {
- SwitchPanelArea(_selectedHeader);
- }
- }
- _selectedHeader = item;
- _selectedHeader.IsSelected = true;
- SwitchPanelArea(_selectedHeader);
- }
- else if (ExpandMode == ExpandMode.Freedom && !_isItemSelected)
- {
- _selectedHeader.IsSelected = false;
- SwitchPanelArea(_selectedHeader);
- _selectedHeader = null;
- }
- if (_isItemSelected)
- {
- _isItemSelected = false;
- }
- else if (_selectedHeader != null)
- {
- if (AutoSelect)
- {
- if (_selectedItem != null)
- {
- _selectedItem.IsSelected = false;
- _selectedItem = null;
- }
- _selectedHeader.SelectDefaultItem();
- }
- _isItemSelected = false;
- }
- if (!item.HasItems)
- {
- RaiseEvent(new FunctionEventArgs<object>(SelectionChangedEvent, this)
- {
- Info = e.OriginalSource
- });
- }
- }
- }
- }
- private void SwitchPanelArea(SideMenuItem oldItem)
- {
- switch (ExpandMode)
- {
- case ExpandMode.ShowAll:
- return;
- case ExpandMode.ShowOne:
- case ExpandMode.Freedom:
- case ExpandMode.Accordion:
- oldItem.SwitchPanelArea(oldItem.IsSelected);
- break;
- }
- }
- protected override DependencyObject GetContainerForItemOverride() => new SideMenuItem();
- protected override bool IsItemItsOwnContainerOverride(object item) => item is SideMenuItem;
- public static readonly DependencyProperty AutoSelectProperty = DependencyProperty.Register(
- nameof(AutoSelect), typeof(bool), typeof(SideMenu), new PropertyMetadata(ValueBoxes.TrueBox));
- public bool AutoSelect
- {
- get => (bool) GetValue(AutoSelectProperty);
- set => SetValue(AutoSelectProperty, ValueBoxes.BooleanBox(value));
- }
- public static readonly DependencyProperty ExpandModeProperty = DependencyProperty.Register(
- nameof(ExpandMode), typeof(ExpandMode), typeof(SideMenu), new PropertyMetadata(default(ExpandMode), OnExpandModeChanged));
- private static void OnExpandModeChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
- {
- var ctl = (SideMenu) d;
- var v = (ExpandMode) e.NewValue;
- if (ctl.ItemsHost == null)
- {
- return;
- }
- ctl.OnExpandModeChanged(v);
- }
- private void OnExpandModeChanged(ExpandMode mode)
- {
- if (mode == ExpandMode.ShowAll)
- {
- ShowAll();
- }
- else if (mode == ExpandMode.ShowOne)
- {
- SideMenuItem sideMenuItemSelected = null;
- foreach (var sideMenuItem in ItemsHost.Children.OfType<SideMenuItem>())
- {
- if (sideMenuItemSelected != null)
- {
- sideMenuItem.IsSelected = false;
- if (sideMenuItem.ItemsHost != null)
- {
- foreach (var sideMenuSubItem in sideMenuItem.ItemsHost.Children.OfType<SideMenuItem>())
- {
- sideMenuSubItem.IsSelected = false;
- }
- }
- }
- else if (sideMenuItem.IsSelected)
- {
- switch (sideMenuItem.Role)
- {
- case SideMenuItemRole.Header:
- _selectedHeader = sideMenuItem;
- break;
- case SideMenuItemRole.Item:
- _selectedItem = sideMenuItem;
- break;
- }
- ShowSelectedOne(sideMenuItem);
- sideMenuItemSelected = sideMenuItem;
- if (sideMenuItem.ItemsHost != null)
- {
- foreach (var sideMenuSubItem in sideMenuItem.ItemsHost.Children.OfType<SideMenuItem>())
- {
- if (_selectedItem != null)
- {
- sideMenuSubItem.IsSelected = false;
- }
- else if (sideMenuSubItem.IsSelected)
- {
- _selectedItem = sideMenuSubItem;
- }
- }
- }
- }
- }
- }
- }
- public ExpandMode ExpandMode
- {
- get => (ExpandMode) GetValue(ExpandModeProperty);
- set => SetValue(ExpandModeProperty, value);
- }
- public static readonly DependencyProperty PanelAreaLengthProperty = DependencyProperty.Register(
- nameof(PanelAreaLength), typeof(double), typeof(SideMenu), new PropertyMetadata(double.NaN));
- public double PanelAreaLength
- {
- get => (double) GetValue(PanelAreaLengthProperty);
- set => SetValue(PanelAreaLengthProperty, value);
- }
- private void ShowAll()
- {
- foreach (var sideMenuItem in ItemsHost.Children.OfType<SideMenuItem>())
- {
- sideMenuItem.SwitchPanelArea(true);
- }
- }
- private void ShowSelectedOne(SideMenuItem item)
- {
- foreach (var sideMenuItem in ItemsHost.Children.OfType<SideMenuItem>())
- {
- sideMenuItem.SwitchPanelArea(Equals(sideMenuItem, item));
- }
- }
- public static readonly RoutedEvent SelectionChangedEvent = EventManager.RegisterRoutedEvent(
- "SelectionChanged", RoutingStrategy.Bubble, typeof(EventHandler<FunctionEventArgs<object>>), typeof(SideMenu));
- public event EventHandler<FunctionEventArgs<object>> SelectionChanged
- {
- add => AddHandler(SelectionChangedEvent, value);
- remove => RemoveHandler(SelectionChangedEvent, value);
- }
- }
|