| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488 | 
							- using System;
 
- using System.Collections.Generic;
 
- using System.Collections.ObjectModel;
 
- using System.ComponentModel;
 
- using System.Linq;
 
- using System.Linq.Expressions;
 
- using System.Threading.Tasks;
 
- using System.Windows;
 
- using System.Windows.Controls;
 
- using System.Windows.Media;
 
- using System.Windows.Media.Imaging;
 
- using InABox.Core;
 
- using InABox.WPF;
 
- using NPOI.OpenXmlFormats.Dml.Chart;
 
- using Syncfusion.UI.Xaml.TreeGrid;
 
- using Syncfusion.UI.Xaml.TreeView;
 
- using Syncfusion.Windows.Tools.Controls;
 
- namespace InABox.DynamicGrid
 
- {
 
-     public class DynamicTreeNode : INotifyPropertyChanged
 
-     {
 
-         private DynamicTreeNodes _owner;
 
-         
 
-         public ObservableCollection<DynamicTreeNode> Children => _owner.GetChilden(_id);
 
-         
 
-         private Guid _id;
 
-         public Guid ID 
 
-         {
 
-             get { return _id; }
 
-             set
 
-             {
 
-                 _id = value;
 
-                 RaisedOnPropertyChanged("ID");
 
-             }
 
-         }
 
-         
 
-         private Guid _parent;
 
-         public Guid Parent 
 
-         {
 
-             get { return _parent; }
 
-             set
 
-             {
 
-                 _parent = value;
 
-                 RaisedOnPropertyChanged("Parent");
 
-             }
 
-         }
 
-         private string _description;
 
-         public string Description
 
-         {
 
-             get { return _description; }
 
-             set
 
-             {
 
-                 _description = value;
 
-                 RaisedOnPropertyChanged("Description");
 
-             }
 
-         }
 
-    
 
-         private ImageSource? _image;
 
-         public ImageSource? Image
 
-         {
 
-             get { return _image; }
 
-             set
 
-             {
 
-                 _image = value;
 
-                 RaisedOnPropertyChanged("Image");
 
-             }
 
-         }
 
-         public event PropertyChangedEventHandler? PropertyChanged;
 
-         public void RaisedOnPropertyChanged(string propertyName)
 
-         {
 
-             PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
 
-         }
 
-         public DynamicTreeNode(DynamicTreeNodes owner)
 
-         {
 
-             _owner = owner;
 
-             _description = "";
 
-         }
 
-         public DynamicTreeNode(DynamicTreeNodes owner, Guid id, Guid parent) : this(owner)
 
-         {
 
-             _id = id;
 
-             _parent = parent;
 
-         }
 
-     }
 
-     public class DynamicTreeNodes 
 
-     {
 
-         private List<DynamicTreeNode> _nodes;
 
-         public ObservableCollection<DynamicTreeNode> Nodes => new ObservableCollection<DynamicTreeNode>(_nodes.Where(x => x.Parent == Guid.Empty));
 
-         
 
-         public DynamicTreeNodes()
 
-         {
 
-             _nodes = new List<DynamicTreeNode>();
 
-         }
 
-         public DynamicTreeNode Add(Guid id, Guid parent)
 
-         {
 
-             var node = new DynamicTreeNode(this, id, parent);
 
-             _nodes.Add(node);
 
-             return node;
 
-         }
 
-         public ObservableCollection<DynamicTreeNode> GetChilden(Guid id)
 
-         {
 
-             return new ObservableCollection<DynamicTreeNode>(_nodes.Where(x => x.Parent.Equals(id) && (x.ID != id)));
 
-         }
 
-         public void Load<T>(CoreTable table, Expression<Func<T, Guid>> id, Expression<Func<T, Guid>> parentid, Expression<Func<T, String>> description)
 
-         {
 
-             _nodes.Clear();
 
-             foreach (var row in table.Rows)
 
-             {
 
-                 Guid _id = row.Get<T, Guid>(id);
 
-                 Guid _parent = row.Get<T, Guid>(parentid);
 
-                 String _description = row.Get<T, String>(description);
 
-                 Add(_id, _parent).Description = _description;
 
-             }
 
-         }
 
-         
 
-     }
 
-     
 
-     public enum DynamicTreeOption
 
-     {
 
-         Add,
 
-         Edit,
 
-         Delete
 
-     }
 
-     public delegate void OnSelectItem(DynamicTreeNode node);
 
-     public delegate void OnContextMenuOpening(DynamicTreeNode node, ContextMenu menu);
 
-     
 
-     public abstract class DynamicTreeView<T> : ContentControl where T : BaseObject, new()
 
-     {
 
-         protected abstract Expression<Func<T, Guid>> ID { get; }
 
-         protected abstract Expression<Func<T, Guid>> ParentID { get; }
 
-         protected abstract Expression<Func<T, String>> Description { get; }
 
-         protected CoreTable Data { get; private set; }
 
-         private ContextMenu _menu;
 
-         private SfTreeGrid _tree;
 
-         private DockPanel _dock;
 
-         private Grid _grid;
 
-         private Button _add;
 
-         private Button _edit;
 
-         private Button _delete;
 
-         private Label _spacer;
 
-         public FluentList<DynamicTreeOption> Options { get; private set; }
 
-         public event OnSelectItem OnSelectItem;
 
-         public event OnContextMenuOpening OnContextMenuOpening;
 
-         private double minRowHeight = 30D;
 
-         private double maxRowHeight = 30D;
 
-         public double MinRowHeight 
 
-         { 
 
-             get => minRowHeight;
 
-             set
 
-             {
 
-                 minRowHeight = value;
 
-                 CalculateRowHeight();
 
-             }
 
-         }
 
-         public double MaxRowHeight 
 
-         { 
 
-             get => maxRowHeight;
 
-             set
 
-             {
 
-                 maxRowHeight = value;
 
-                 CalculateRowHeight();
 
-             }
 
-         }
 
-         /*public double RowHeight
 
-         {
 
-             get => _tree.RowHeight;
 
-             set => _tree.RowHeight = value;
 
-         }*/
 
-         
 
-         public DynamicTreeView() : base()
 
-         {
 
-             
 
-             Options = new FluentList<DynamicTreeOption>();
 
-             Options.OnChanged += OptionsChanged;
 
-             
 
-             _grid = new Grid();
 
-             _grid.ColumnDefinitions.Add(new ColumnDefinition() { Width = new GridLength(1D, GridUnitType.Star) });
 
-             _grid.RowDefinitions.Add(new RowDefinition() { Height = new GridLength(1D, GridUnitType.Star) });
 
-             _grid.RowDefinitions.Add(new RowDefinition() { Height = new GridLength(1D, GridUnitType.Auto) });
 
-             
 
-             _tree = new SfTreeGrid();
 
-             _tree.ChildPropertyName = "Children";
 
-             //_tree.ParentPropertyName = "Parent";
 
-             _tree.AutoGenerateColumns = false;
 
-             _tree.AutoExpandMode = AutoExpandMode.AllNodesExpanded;
 
-             //_tree.NodeCollapsing += (o, e) => { e.Cancel = true; };
 
-             _tree.HeaderRowHeight = 0D;
 
-             _tree.SelectionChanged += (o,e) => OnSelectItem?.Invoke((_tree.SelectedItem as DynamicTreeNode)!);
 
-             _tree.AllowSelectionOnExpanderClick = false;
 
-             _menu = new ContextMenu();
 
-             var additem = new MenuItem() { Header = "Add Child Folder" };
 
-             additem.Click += (o, e) => { AddItem((_tree.SelectedItem as DynamicTreeNode)!.ID); };
 
-             _menu.Items.Add(additem);
 
-             _tree.ContextMenuOpening += _tree_ContextMenuOpening;
 
-             _tree.ContextMenu = _menu;
 
-             _tree.Background = new SolidColorBrush(Colors.DimGray);
 
-             
 
-             var cellStyle = new Style(typeof(TreeGridRowControl));
 
-             cellStyle.Setters.Add(new Setter(BackgroundProperty, new SolidColorBrush(Colors.White)));
 
-             _tree.RowStyle = cellStyle;            
 
-             
 
-             _tree.SelectionBackground = new SolidColorBrush(System.Windows.Media.Color.FromArgb(0xFF, 0x11, 0x9E, 0xD9));
 
-             _tree.Columns.Add(new TreeGridTextColumn()
 
-                 {
 
-                     MappingName = "Description"
 
-                 }
 
-             );
 
-             _tree.ColumnSizer = TreeColumnSizer.Star;
 
-             _tree.RowHeight = 30D;
 
-             _tree.SetValue(Grid.RowProperty, 0);
 
-             _grid.Children.Add(_tree);
 
-             
 
-             _dock = new DockPanel();
 
-             _dock.SetValue(Grid.RowProperty, 1);
 
-             _grid.Children.Add(_dock);
 
-             _add = CreateButton(Properties.Resources.add.AsBitmapImage(System.Drawing.Color.White), "", "Add Item", (o) => AddItem(Guid.Empty));
 
-             _add.Margin = new Thickness(0, 2, 2, 0);
 
-             _add.Visibility = Visibility.Collapsed;
 
-             _add.SetValue(DockPanel.DockProperty, Dock.Left);
 
-             _dock.Children.Add(_add);
 
-             
 
-             _edit = CreateButton(Properties.Resources.pencil.AsBitmapImage(System.Drawing.Color.White), "", "Edit Item", EditItem);
 
-             _edit.Margin = new Thickness(0, 2, 2, 0);
 
-             _edit.Visibility = Visibility.Collapsed;
 
-             _edit.SetValue(DockPanel.DockProperty, Dock.Left);
 
-             _dock.Children.Add(_edit);
 
-             _delete = CreateButton(Properties.Resources.delete.AsBitmapImage(System.Drawing.Color.White), "", "Delete Item", DeleteItem);
 
-             _delete.Margin = new Thickness(2, 2, 0, 0);
 
-             _delete.Visibility = Visibility.Collapsed;
 
-             _delete.SetValue(DockPanel.DockProperty, Dock.Right);
 
-             _dock.Children.Add(_delete);
 
-             
 
-             _spacer = new Label();
 
-             _spacer.SetValue(DockPanel.DockProperty, Dock.Left);
 
-             _dock.Children.Add(_spacer);
 
-             Content = _grid;
 
-             SizeChanged += DynamicTreeView_SizeChanged;
 
-         }
 
-         #region Public Interface
 
-         public void AddItem(DynamicTreeNode? parentNode = null, bool edit = true)
 
-         {
 
-             var id = parentNode?.ID ?? Guid.Empty;
 
-             try
 
-             {
 
-                 T item = DoCreateItem(id);
 
-                 if (edit)
 
-                 {
 
-                     if (DoEditItem(item))
 
-                     {
 
-                         DoSaveItem(item);
 
-                         Refresh();
 
-                     }
 
-                 }
 
-                 else
 
-                 {
 
-                     DoSaveItem(item);
 
-                     Refresh();
 
-                 }
 
-             }
 
-             catch (Exception e)
 
-             {
 
-                 MessageBox.Show(e.Message);
 
-             }
 
-         }
 
-         #endregion
 
-         private void _tree_ContextMenuOpening(object sender, ContextMenuEventArgs e)
 
-         {
 
-             _menu.Items.Clear();
 
-             if (OnContextMenuOpening is not null)
 
-             {
 
-                 OnContextMenuOpening.Invoke((_tree.SelectedItem as DynamicTreeNode)!, _menu);
 
-                 if(_menu.Items.Count == 0)
 
-                 {
 
-                     e.Handled = true;
 
-                 }
 
-             }
 
-             else
 
-             {
 
-                 _menu.AddItem("Add Item", null, (_tree.SelectedItem as DynamicTreeNode)!.ID, AddItem);
 
-             }
 
-         }
 
-         private void DynamicTreeView_SizeChanged(object sender, SizeChangedEventArgs e)
 
-         {
 
-             CalculateRowHeight();
 
-         }
 
-         private void CalculateRowHeight()
 
-         {
 
-             if(Data != null && Data.Rows.Count > 0)
 
-             {
 
-                 var contentHeight = _tree.ActualHeight - (_tree.Padding.Top + _tree.Padding.Bottom) - 2; // Two extra pixels of space
 
-                 var targetHeight = contentHeight / Data.Rows.Count;
 
-                 _tree.RowHeight = Math.Max(Math.Min(targetHeight, MaxRowHeight), MinRowHeight);
 
-             }
 
-         }
 
-         
 
-         private Button CreateButton(BitmapImage? image = null, string? text = null, string?  tooltip = null, Action<Button>? action = null)
 
-         {
 
-             var button = new Button();
 
-             button.SetValue(BorderBrushProperty, new SolidColorBrush(Colors.Gray));
 
-             button.SetValue(BorderThicknessProperty, new Thickness(0.75));
 
-             button.Height = 30;
 
-             button.MinWidth = 30;
 
-             button.Click += (o, e) => action?.Invoke(button);
 
-             UpdateButton(button, image, text, tooltip);
 
-             return button;
 
-         }
 
-         protected void UpdateButton(Button button, BitmapImage? image, string? text, string? tooltip = null)
 
-         {
 
-             var stackPnl = new StackPanel();
 
-             stackPnl.Orientation = Orientation.Horizontal;
 
-             if (image != null)
 
-             {
 
-                 var img = new Image();
 
-                 img.Source = image;
 
-                 img.Margin = new Thickness(2);
 
-                 img.ToolTip = tooltip;
 
-                 stackPnl.Children.Add(img);
 
-             }
 
-             if (!string.IsNullOrEmpty(text))
 
-             {
 
-                 var lbl = new Label();
 
-                 lbl.Content = text;
 
-                 lbl.VerticalAlignment = VerticalAlignment.Stretch;
 
-                 lbl.VerticalContentAlignment = VerticalAlignment.Center;
 
-                 lbl.Margin = new Thickness(2, 0, 5, 0);
 
-                 lbl.ToolTip = ToolTip;
 
-                 stackPnl.Children.Add(lbl);
 
-             }
 
-             button.Content = stackPnl;
 
-             button.ToolTip = tooltip;
 
-         }
 
-         
 
-         private void OptionsChanged(object sender, EventArgs args)
 
-         {
 
-             _add.Visibility = Options.Contains(DynamicTreeOption.Add) ? Visibility.Visible : Visibility.Collapsed;
 
-             _edit.Visibility = Options.Contains(DynamicTreeOption.Edit) ? Visibility.Visible : Visibility.Collapsed;
 
-             _delete.Visibility = Options.Contains(DynamicTreeOption.Delete) ? Visibility.Visible : Visibility.Collapsed;
 
-         }
 
-         protected virtual T DoCreateItem(Guid parent)
 
-         {
 
-             T result = new T();
 
-             CoreUtils.SetPropertyValue(result, CoreUtils.GetFullPropertyName(ParentID, "."), parent);
 
-             return result;
 
-         }
 
-         protected abstract T? DoLoadItem(Guid id);
 
-         protected virtual bool DoEditItem(T item)
 
-         {
 
-             var form = new DynamicEditorForm(typeof(T));
 
-             form.Items = new T[] { item };
 
-             return form.ShowDialog() == true;
 
-         }
 
-         protected abstract void DoSaveItem(T item);
 
-         protected abstract bool DoDeleteItem(Guid id);
 
-         private void AddItem(Guid id)
 
-         {
 
-             try
 
-             {
 
-                 T item = DoCreateItem(id);
 
-                 if (DoEditItem(item))
 
-                 {
 
-                     DoSaveItem(item);
 
-                     Refresh();
 
-                 }
 
-             }
 
-             catch (Exception e)
 
-             {
 
-                 MessageBox.Show(e.Message);
 
-             }
 
-         }
 
-         
 
-         private void EditItem(Button button)
 
-         {
 
-             var node = _tree.SelectedItem as DynamicTreeNode;
 
-             if (node == null)
 
-             {
 
-                 MessageBox.Show("Please Select an item to edit!");
 
-                 return;
 
-             }
 
-             var item = DoLoadItem(node.ID);
 
-             if (item != null && DoEditItem(item))
 
-             {
 
-                 DoSaveItem(item);
 
-                 Refresh();
 
-             }
 
-         }
 
-         private  void DeleteItem(Button button)
 
-         {
 
-             var node = _tree.SelectedItem as DynamicTreeNode;
 
-             if (node == null)
 
-             {
 
-                 MessageBox.Show("Please Select an item to edit!");
 
-                 return;
 
-             }
 
-             if (DoDeleteItem(node.ID))
 
-             {
 
-                 Refresh();
 
-             }
 
-         }
 
-         
 
-         public DynamicTreeNodes Nodes { get; set; }
 
-         protected abstract void DoRefresh(Action<CoreTable?, Exception?> action);
 
-         private void AfterRefresh()
 
-         {
 
-             var nodes = new DynamicTreeNodes();
 
-             foreach (var row in Data.Rows)
 
-             {
 
-                 var _id = row.Get(ID);
 
-                 var _parent = row.Get(ParentID);
 
-                 var _description = row.Get(Description);
 
-                 nodes.Add(_id, _parent).Description = _description;
 
-             }
 
-             Nodes = nodes;
 
-             _tree.ItemsSource = nodes.Nodes;
 
-             CalculateRowHeight();
 
-         }
 
-         public void Refresh()
 
-         {
 
-             DoRefresh((table, exception) =>
 
-             {
 
-                 if(exception != null)
 
-                 {
 
-                     Dispatcher.Invoke(() =>
 
-                     {
 
-                         MessageBox.Show(String.Format("Error: {0}", exception.Message));
 
-                     });
 
-                 }
 
-                 else if(table is not null)
 
-                 {
 
-                     Data = table;
 
-                     Dispatcher.Invoke(() =>
 
-                     {
 
-                         AfterRefresh();
 
-                     });
 
-                 }
 
-             });
 
-         }
 
-     }
 
- }
 
 
  |