using InABox.Core; using InABox.Wpf; using InABox.WPF; using Syncfusion.Data; using Syncfusion.UI.Xaml.TreeGrid; using System; using System.Collections.Generic; using System.Linq; using System.Linq.Expressions; using System.Text; using System.Threading.Tasks; using System.Windows; using System.Windows.Controls; using System.Windows.Media; namespace InABox.DynamicGrid; public class DynamicGridTreeUIComponent : IDynamicGridUIComponent where T : BaseObject, new() { private IDynamicGridUIComponentParent _parent; public IDynamicGridUIComponentParent Parent { get => _parent; set { _parent = value; } } private Column IDColumn; private Column ParentColumn; private Column DescriptionColumn; private ContextMenu _menu; private SfTreeGrid _tree; private readonly ContextMenu ColumnsMenu; private Dictionary? _rowMap; public event OnContextMenuOpening OnContextMenuOpening; FrameworkElement IDynamicGridUIComponent.Control => _tree; private bool _shownumbers = false; public bool ShowNumbers { get => _shownumbers; set { _shownumbers = value; _tree.Columns[1].Width = value ? 50 : 0; } } public DynamicGridTreeUIComponent(Expression> idColumn, Expression> parentIDColumn, Expression> descriptionColumn) { IDColumn = new Column(CoreUtils.GetFullPropertyName(idColumn, ".")); ParentColumn = new Column(CoreUtils.GetFullPropertyName(parentIDColumn, ".")); DescriptionColumn = new Column(CoreUtils.GetFullPropertyName(descriptionColumn, ".")); ColumnsMenu = new ContextMenu(); ColumnsMenu.Opened += ColumnsMenu_ContextMenuOpening; _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.HeaderContextMenu = ColumnsMenu; _tree.SelectionChanged += (o,e) => { var row = GetRow(_tree.SelectedItem as CoreTreeNode); if(row is not null) { Parent.SelectItems(new[] { row }); } else { Parent.SelectItems(Array.Empty()); } } _tree.AllowSelectionOnExpanderClick = false; _menu = new ContextMenu(); var additem = new MenuItem() { Header = "Add Child Folder" }; additem.Click += (o, e) => { DoAddItem((_tree.SelectedItem as CoreTreeNode)!.ID, true); }; _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(Control.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.Columns.Add(new TreeGridTextColumn() { MappingName = "Number", Width = _shownumbers ? 50 : 0, TextAlignment = TextAlignment.Right } ); _tree.ColumnSizer = TreeColumnSizer.Star; _tree.RowHeight = 30D; _tree.SetValue(Grid.RowProperty, 0); } private CoreRow? GetRow(CoreTreeNode? node) { return node is not null ? _rowMap?.GetValueOrDefault(node.ID) : null; } private void ColumnsMenu_ContextMenuOpening(object sender, RoutedEventArgs e) { if (sender is not ContextMenu menu) return; menu.Items.Clear(); Parent.LoadColumnsMenu(menu); } public bool OptionsChanged() { ColumnsMenu.Visibility = Parent.HasOption(DynamicTreeOption.SelectColumns) ? Visibility.Visible : Visibility.Hidden; } #region Context Menu private void _tree_ContextMenuOpening(object sender, ContextMenuEventArgs e) { _menu.Items.Clear(); if (OnContextMenuOpening is not null) { OnContextMenuOpening.Invoke((_tree.SelectedItem as CoreTreeNode)!, _menu); if(_menu.Items.Count == 0) { e.Handled = true; } } else { if (Parent.HasOption(DynamicGridOption.AddRows)) { _menu.AddItem("Add Item", null, (_tree.SelectedItem as CoreTreeNode)!.ID, (id) => DoAddItem(id, true)); } } } #endregion #region CRUD protected T DoCreateItem(Guid parent) { var result = Parent.CreateItem(); CoreUtils.SetPropertyValue(result, ParentColumn.Property, parent); return result; } protected void DoAddItem(Guid id, bool edit) { try { var item = DoCreateItem(id); if (edit) { if (Parent.EditItems(new[] { item })) { Parent.Refresh(false, true); } } else { Parent.SaveItem(item); Parent.Refresh(false, true); } } catch (Exception e) { MessageWindow.ShowError("An error occurred while adding an item", e); } } #endregion #region Refresh public CoreTreeNodes Nodes { get; set; } public void BeforeRefresh() { throw new NotImplementedException(); } public void RefreshColumns(DynamicGridColumns columns, DynamicActionColumns actionColumns) { throw new NotImplementedException(); } public void RefreshData(CoreTable data) { var nodes = new CoreTreeNodes(); foreach (var row in data.Rows) { var _id = row.Get(IDColumn.Property); var _parent = row.Get(ParentColumn.Property); var _description = row.Get(DescriptionColumn.Property); nodes.Add(_id, _parent, row).Description = _description; } Nodes = nodes; _tree.ItemsSource = nodes.Nodes; CalculateRowHeight(); } #endregion public CoreRow[] SelectedRows { get { return _tree.SelectedItems.OfType() .Select(x => GetRow(x)).NotNull().ToArray(); } set { _tree.SelectedItems.Clear(); foreach (var row in value) { _tree.SelectedItems.Add(Nodes.Find(row.Get(IDColumn.Property))); } } } public double RowHeight { get => _tree.RowHeight; set => _tree.RowHeight = value; } public double HeaderRowHeight { get => _tree.HeaderRowHeight; set => _tree.HeaderRowHeight = value; } public int DesiredWidth() { throw new NotImplementedException(); } public void AddVisualFilter(string column, string value, FilterType filtertype = FilterType.Contains) { } public List> GetFilterPredicates() { return new List>(); } public CoreRow[] GetVisibleRows() { throw new NotImplementedException(); } public void InvalidateRow(CoreRow row) { throw new NotImplementedException(); } public void ScrollIntoView(CoreRow row) { throw new NotImplementedException(); } public void UpdateCell(CoreRow row, string column, object? value) { throw new NotImplementedException(); } public void UpdateRow(CoreRow row) { throw new NotImplementedException(); } }