using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Input;
using System.ComponentModel;
using System.Collections;
using System.Windows.Media;
using XImagingXhandler.XDAL;
using XHandler.View;
namespace XHandler.Controls
{
public class TreeViewExtensions : DependencyObject
{
public static TestDesign testDesign;
///
/// Gets the value of the dependency property "EnableMultiSelect".
///
/// Dependency Object
///
public static bool GetEnableMultiSelect(DependencyObject obj)
{
return (bool)obj.GetValue(EnableMultiSelectProperty);
}
///
/// Sets the value of the dependency property "EnableMultiSelect".
///
/// Dependency Object
///
public static void SetEnableMultiSelect(DependencyObject obj, bool value)
{
obj.SetValue(EnableMultiSelectProperty, value);
}
// Using a DependencyProperty as the backing store for EnableMultiSelect. This enables animation, styling, binding, etc...
public static readonly DependencyProperty EnableMultiSelectProperty =
DependencyProperty.RegisterAttached("EnableMultiSelect", typeof(bool), typeof(TreeViewExtensions), new FrameworkPropertyMetadata(false)
{
PropertyChangedCallback = EnableMultiSelectChanged,
BindsTwoWayByDefault = true
});
///
/// Gets the value of the dependency property "SelectedItems".
///
/// Dependency Object
///
public static IList GetSelectedItems(DependencyObject obj)
{
return (IList)obj.GetValue(SelectedItemsProperty);
}
///
/// Sets the value of the dependency property "SelectedItems".
///
/// Dependency Object
///
public static void SetSelectedItems(DependencyObject obj, IList value)
{
obj.SetValue(SelectedItemsProperty, value);
}
///
/// 已经选中的节点
///
public List SelectedItems
{
get { return (List)GetValue(SelectedItemsProperty); }
set { SetValue(SelectedItemsProperty, value); }
}
// Using a DependencyProperty as the backing store for SelectedItems. This enables animation, styling, binding, etc...
public static readonly DependencyProperty SelectedItemsProperty =
DependencyProperty.RegisterAttached("SelectedItems", typeof(IList), typeof(TreeViewExtensions), new FrameworkPropertyMetadata(null)
{
PropertyChangedCallback = MultiSelectChanged,
BindsTwoWayByDefault = true
});
///
/// TreeViewItem seleted changed event.
///
/// sender
/// event parameter
static void MultiSelectChanged(DependencyObject sender, DependencyPropertyChangedEventArgs args)
{
TreeViewItem item = (TreeViewItem)sender;
var selectedItems = GetSelectedItems(GetTree(item));
SetSelectedItems(item.Parent, selectedItems);
}
///
/// Gets the value of the dependency property "AnchorItem".
///
/// Dependency Object
///
static TreeViewItem GetAnchorItem(DependencyObject obj)
{
return (TreeViewItem)obj.GetValue(AnchorItemProperty);
}
///
/// Sets the value of the dependency property "AnchorItem".
///
/// Dependency Object
///
static void SetAnchorItem(DependencyObject obj, TreeViewItem value)
{
obj.SetValue(AnchorItemProperty, value);
}
// Using a DependencyProperty as the backing store for AnchorItem. This enables animation, styling, binding, etc...
static readonly DependencyProperty AnchorItemProperty =
DependencyProperty.RegisterAttached("AnchorItem", typeof(TreeViewItem), typeof(TreeViewExtensions), new PropertyMetadata(null));
///
/// Gets the value of the dependency property "IsSelected".
///
/// Dependency Object
///
public static bool GetIsSelected(DependencyObject obj)
{
return (bool)obj.GetValue(IsSelectedProperty);
}
private static MethodEx FindMethodExByIndex(MethodEx method, string indexName)
{
if (method.strIndex == indexName)
return method;
else
{
if (method.Children.Count > 0)
{
foreach (var m in method.Children)
{
MethodEx find = FindMethodExByIndex(m, indexName);
if (find != null)
return find;
}
}
else
return null;
}
return null;
}
///
/// Sets the value of the dependency property "IsSelected".
///
/// Dependency Object
///
public static void SetIsSelected(DependencyObject obj, bool value, int type = 0)
{
if (value)
{
if (type == 1)
{
((TreeViewItem)obj).IsSelected = value;
((MethodEx)((TreeViewItem)obj).Header).isSelected = value;
if (testDesign != null)
{
MethodEx methodEx = FindMethodExByIndex(testDesign.rootMethod, ((MethodEx)((TreeViewItem)obj).Header).strIndex);
if (methodEx != null)
methodEx.isSelected = value;
}
}
GradientStopCollection gradientStopCollection = new GradientStopCollection();
gradientStopCollection.Add(new GradientStop()
{
Color = (Color)ColorConverter.ConvertFromString("#FFC7DFFC"),
Offset = 1
});
gradientStopCollection.Add(new GradientStop()
{
Color = (Color)ColorConverter.ConvertFromString("#FF3832B8"),
Offset = 1
});
LinearGradientBrush brush = new LinearGradientBrush(gradientStopCollection, new Point(0.5, 0), new Point(0.5, 1));
(obj as TreeViewItem).Background = brush;
}
else
{
if (type == 1)
{
((TreeViewItem)obj).IsSelected = value;
((MethodEx)((TreeViewItem)obj).Header).isSelected = value;
if (testDesign != null)
{
MethodEx methodEx = FindMethodExByIndex(testDesign.rootMethod, ((MethodEx)((TreeViewItem)obj).Header).strIndex);
if (methodEx != null)
methodEx.isSelected = value;
}
}
(obj as TreeViewItem).Background = Brushes.Transparent;
}
obj.SetValue(IsSelectedProperty, value);
}
// Using a DependencyProperty as the backing store for IsSelected. This enables animation, styling, binding, etc...
public static readonly DependencyProperty IsSelectedProperty =
DependencyProperty.RegisterAttached("IsSelected", typeof(bool), typeof(TreeViewExtensions), new FrameworkPropertyMetadata(false)
{
PropertyChangedCallback = RealSelectedChanged,
BindsTwoWayByDefault = true
});
///
/// "EnableMultiSelect" changed event.
///
/// Dependency Object
/// Event parameter
static void EnableMultiSelectChanged(DependencyObject s, DependencyPropertyChangedEventArgs args)
{
TreeView tree = (TreeView)s;
var wasEnable = (bool)args.OldValue;
var isEnabled = (bool)args.NewValue;
if (wasEnable)
{
tree.RemoveHandler(TreeViewItem.MouseDownEvent, new MouseButtonEventHandler(ItemClicked));
tree.RemoveHandler(TreeView.KeyDownEvent, new KeyEventHandler(KeyDown));
}
if (isEnabled)
{
tree.AddHandler(TreeViewItem.MouseDownEvent, new MouseButtonEventHandler(ItemClicked), true);
tree.AddHandler(TreeView.KeyDownEvent, new KeyEventHandler(KeyDown));
}
}
///
/// Gets TreeView which contains the TreeViewItem.
///
/// item
/// TreeView
static TreeView GetTree(TreeViewItem item)
{
Func getParent = (o) => VisualTreeHelper.GetParent(o);
FrameworkElement currentItem = item;
while (!(getParent(currentItem) is TreeView))
{
currentItem = (FrameworkElement)getParent(currentItem);
}
return (TreeView)getParent(currentItem);
}
///
/// TreeViewItem seleted changed event.
///
/// sender
/// event parameter
static void RealSelectedChanged(DependencyObject sender, DependencyPropertyChangedEventArgs args)
{
TreeViewItem item = (TreeViewItem)sender;
var selectedItems = GetSelectedItems(GetTree(item));
if (selectedItems != null)
{
var isSelected = GetIsSelected(item);
if (isSelected)
{
try
{
selectedItems.Add(item.Header);
}
catch (ArgumentException)
{
}
}
else
{
selectedItems.Remove(item.Header);
}
}
}
///
/// Key down event.
///
/// sender
/// event parameter
static void KeyDown(object sender, KeyEventArgs e)
{
TreeView tree = (TreeView)sender;
if (e.Key == Key.A && e.KeyboardDevice.Modifiers == ModifierKeys.Control)
{
foreach (var item in GetExpandedTreeViewItems(tree))
{
SetIsSelected(item, true,1);
}
e.Handled = true;
}
}
///
/// Item clicked event.
///
/// sender
/// event parameter
static void ItemClicked(object sender, MouseButtonEventArgs e)
{
TreeViewItem item = FindTreeViewItem(e.OriginalSource);
if (item == null)
{
return;
}
TreeView tree = (TreeView)sender;
var mouseButton = e.ChangedButton;
if (mouseButton != MouseButton.Left)
{
if ((mouseButton == MouseButton.Right) && ((Keyboard.Modifiers & (ModifierKeys.Shift | ModifierKeys.Control)) == ModifierKeys.None))
{
if (GetIsSelected(item))
{
UpdateAnchorAndActionItem(tree, item);
return;
}
MakeSingleSelection(tree, item);
}
return;
}
if ((Keyboard.Modifiers & (ModifierKeys.Shift | ModifierKeys.Control)) != (ModifierKeys.Shift | ModifierKeys.Control))
{
if ((Keyboard.Modifiers & ModifierKeys.Control) == ModifierKeys.Control)
{
MakeToggleSelection(tree, item);
return;
}
if ((Keyboard.Modifiers & ModifierKeys.Shift) == ModifierKeys.Shift)
{
MakeAnchorSelection(tree, item, true);
return;
}
MakeSingleSelection(tree, item);
e.Handled = true;
return;
}
}
///
/// Find TreeViewItem which contains the object.
///
/// obj
///
private static TreeViewItem FindTreeViewItem(object obj)
{
DependencyObject dpObj = obj as DependencyObject;
if (dpObj == null)
{
return null;
}
if (dpObj is TreeViewItem)
{
return (TreeViewItem)dpObj;
}
return FindTreeViewItem(VisualTreeHelper.GetParent(dpObj));
}
///
/// Gets all expanded TreeViewItems.
///
/// TreeView
///
private static IEnumerable GetExpandedTreeViewItems(ItemsControl tree)
{
for (int i = 0; i < tree.Items.Count; i++)
{
var item = (TreeViewItem)tree.ItemContainerGenerator.ContainerFromIndex(i);
if (item == null)
{
continue;
}
yield return item;
if (item.IsExpanded)
{
foreach (var subItem in GetExpandedTreeViewItems(item))
{
yield return subItem;
}
}
}
}
///
/// Select by Shift key.
///
///
///
///
private static void MakeAnchorSelection(TreeView tree, TreeViewItem actionItem, bool clearCurrent)
{
if (GetAnchorItem(tree) == null)
{
var selectedItems = GetSelectedTreeViewItems(tree);
if (selectedItems.Count > 0)
{
SetAnchorItem(tree, selectedItems[selectedItems.Count - 1]);
}
else
{
SetAnchorItem(tree, GetExpandedTreeViewItems(tree).Skip(3).FirstOrDefault());
}
if (GetAnchorItem(tree) == null)
{
return;
}
}
var anchor = GetAnchorItem(tree);
var items = GetExpandedTreeViewItems(tree);
bool betweenBoundary = false;
foreach (var item in items)
{
bool isBoundary = item == anchor || item == actionItem;
if (isBoundary)
{
betweenBoundary = !betweenBoundary;
}
if (betweenBoundary || isBoundary)
{
SetIsSelected(item, true,1);
}
else
{
if (clearCurrent)
{
SetIsSelected(item, false,1);
}
else
{
break;
}
}
}
}
///
/// Gets all selected TreeViewItems.
///
/// TreeView
///
private static List GetSelectedTreeViewItems(TreeView tree)
{
return GetExpandedTreeViewItems(tree).Where(i => GetIsSelected(i)).ToList();
}
///
/// Select by left mouse button.
///
///
///
private static void MakeSingleSelection(TreeView tree, TreeViewItem item)
{
foreach (TreeViewItem selectedItem in GetExpandedTreeViewItems(tree))
{
if (selectedItem == null)
{
continue;
}
if (selectedItem != item)
{
SetIsSelected(selectedItem, false,1);
}
else
{
SetIsSelected(selectedItem, true,1);
}
}
UpdateAnchorAndActionItem(tree, item);
}
///
/// Select by Ctrl key.
///
/// TreeView
/// TreeViewItem
private static void MakeToggleSelection(TreeView tree, TreeViewItem item)
{
SetIsSelected(item, !GetIsSelected(item),1);
UpdateAnchorAndActionItem(tree, item);
}
///
/// Update the Anchor TreeViewItem.
///
/// TreeView
/// TreeViewItem
private static void UpdateAnchorAndActionItem(TreeView tree, TreeViewItem item)
{
SetAnchorItem(tree, item);
}
}
}