|
@@ -247,6 +247,7 @@ public class DynamicGridTreeUIComponent<T> : IDynamicGridUIComponent<T>, IDynami
|
|
|
_tree.CurrentCellEndEdit += _tree_CurrentCellEndEdit;
|
|
|
_tree.CurrentCellDropDownSelectionChanged += _tree_CurrentCellDropDownSelectionChanged;
|
|
|
_tree.PreviewKeyUp += _tree_PreviewKeyUp;
|
|
|
+ _tree.SelectionController = new TreeGridSelectionControllerExt(_tree, this);
|
|
|
|
|
|
_tree.ColumnSizer = TreeColumnSizer.None;
|
|
|
_tree.RowHeight = 30D;
|
|
@@ -271,6 +272,24 @@ public class DynamicGridTreeUIComponent<T> : IDynamicGridUIComponent<T>, IDynami
|
|
|
_tree.SizeChanged += _tree_SizeChanged;
|
|
|
}
|
|
|
|
|
|
+ private class TreeGridSelectionControllerExt(SfTreeGrid treeGrid, DynamicGridTreeUIComponent<T> grid) : TreeGridRowSelectionController(treeGrid)
|
|
|
+ {
|
|
|
+ private DynamicGridTreeUIComponent<T> Grid = grid;
|
|
|
+
|
|
|
+ public override bool HandleKeyDown(KeyEventArgs args)
|
|
|
+ {
|
|
|
+ if (args.Key == Key.Escape)
|
|
|
+ {
|
|
|
+ Grid.CancelEdit();
|
|
|
+ return false;
|
|
|
+ }
|
|
|
+ else
|
|
|
+ {
|
|
|
+ return base.HandleKeyDown(args);
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
#region Public Interface
|
|
|
|
|
|
public IEnumerable<CoreRow> GetChildren(Guid id)
|
|
@@ -394,6 +413,8 @@ public class DynamicGridTreeUIComponent<T> : IDynamicGridUIComponent<T>, IDynami
|
|
|
|
|
|
#endregion
|
|
|
|
|
|
+ #region FilterUI
|
|
|
+
|
|
|
private void _tree_FilterItemsPopulating(object? sender, Syncfusion.UI.Xaml.TreeGrid.Filtering.TreeGridFilterItemsPopulatingEventArgs e)
|
|
|
{
|
|
|
var colIdx = _tree.Columns.IndexOf(e.Column);
|
|
@@ -477,21 +498,49 @@ public class DynamicGridTreeUIComponent<T> : IDynamicGridUIComponent<T>, IDynami
|
|
|
UpdateRecordCount();
|
|
|
}
|
|
|
|
|
|
- private CoreRow? GetRow(CoreTreeNode? node)
|
|
|
+ public void AddVisualFilter(string column, string value, FilterType filtertype = FilterType.Contains)
|
|
|
{
|
|
|
- return MapRow(node?.Row);
|
|
|
+ if (value.IsNullOrWhiteSpace())
|
|
|
+ return;
|
|
|
+ var col = _tree.Columns.FirstOrDefault((x => string.Equals(x.MappingName?.ToUpper(),column?.Replace(".", "_").ToUpper())));
|
|
|
+ if (col != null)
|
|
|
+ {
|
|
|
+ col.FilterPredicates.Add(new FilterPredicate { FilterType = filtertype, FilterValue = value });
|
|
|
+ }
|
|
|
}
|
|
|
|
|
|
- private CoreRow? MapRow(CoreRow? row)
|
|
|
+ public List<Tuple<string, Func<CoreRow, bool>>> GetFilterPredicates()
|
|
|
{
|
|
|
- if (row is null) return null;
|
|
|
-
|
|
|
- var index = row.Index;
|
|
|
- if (index < 0 || index >= Parent.Data.Rows.Count) return null;
|
|
|
-
|
|
|
- return Parent.Data.Rows[row.Index];
|
|
|
+ var list = new List<Tuple<string, Func<CoreRow, bool>>>();
|
|
|
+ foreach (var column in _tree.Columns)
|
|
|
+ {
|
|
|
+ var colIndex = _tree.Columns.IndexOf(column);
|
|
|
+ var col = ColumnList[colIndex];
|
|
|
+ if (col is DynamicGridColumn gridColumn)
|
|
|
+ {
|
|
|
+ var rowPredicate = DynamicGridGridUIComponentExtension.ConvertColumnPredicates(gridColumn, column.FilterPredicates);
|
|
|
+ if(rowPredicate is not null)
|
|
|
+ {
|
|
|
+ list.Add(new(gridColumn.ColumnName, rowPredicate));
|
|
|
+ }
|
|
|
+ }
|
|
|
+ else if(col is DynamicActionColumn dac && dac.FilterRecord is not null)
|
|
|
+ {
|
|
|
+ if(dac.SelectedFilters is not null && dac.SelectedFilters.Length > 0)
|
|
|
+ {
|
|
|
+ list.Add(new(column.MappingName, (row) => dac.FilterRecord(row, dac.SelectedFilters)));
|
|
|
+ }
|
|
|
+ if(dac.ExcludeFilters is not null && dac.ExcludeFilters.Length > 0)
|
|
|
+ {
|
|
|
+ list.Add(new(column.MappingName, (row) => !dac.FilterRecord(row, dac.ExcludeFilters)));
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+ return list;
|
|
|
}
|
|
|
|
|
|
+ #endregion
|
|
|
+
|
|
|
private void ColumnsMenu_ContextMenuOpening(object sender, RoutedEventArgs e)
|
|
|
{
|
|
|
if (sender is not ContextMenu menu) return;
|
|
@@ -643,6 +692,39 @@ public class DynamicGridTreeUIComponent<T> : IDynamicGridUIComponent<T>, IDynami
|
|
|
|
|
|
#endregion
|
|
|
|
|
|
+ #region Rows
|
|
|
+
|
|
|
+ private CoreRow? GetRow(CoreTreeNode? node)
|
|
|
+ {
|
|
|
+ return MapRow(node?.Row);
|
|
|
+ }
|
|
|
+
|
|
|
+ private CoreRow? MapRow(CoreRow? row)
|
|
|
+ {
|
|
|
+ if (row is null) return null;
|
|
|
+
|
|
|
+ var index = row.Index;
|
|
|
+ if (index < 0 || index >= Parent.Data.Rows.Count) return null;
|
|
|
+
|
|
|
+ return Parent.Data.Rows[row.Index];
|
|
|
+ }
|
|
|
+
|
|
|
+ private CoreTreeNode? GetNode(CoreRow row)
|
|
|
+ {
|
|
|
+ if (_innerTable is null || row.Index < 0 || row.Index >= _innerTable.Rows.Count) return null;
|
|
|
+
|
|
|
+ var _innerRow = _innerTable.Rows[row.Index];
|
|
|
+ var node = Nodes.Find(_innerRow);
|
|
|
+ return node;
|
|
|
+ }
|
|
|
+
|
|
|
+ public CoreRow[] GetVisibleRows()
|
|
|
+ {
|
|
|
+ return _tree.View?.Nodes.Select(x => MapRow((x.Item as CoreTreeNode)?.Row)).NotNull().ToArray() ?? new CoreRow[] { };
|
|
|
+ }
|
|
|
+
|
|
|
+ #endregion
|
|
|
+
|
|
|
#region Columns
|
|
|
|
|
|
private class StackedHeaderRenderer : TreeGridStackedHeaderCellRenderer
|
|
@@ -1159,51 +1241,7 @@ public class DynamicGridTreeUIComponent<T> : IDynamicGridUIComponent<T>, IDynami
|
|
|
|
|
|
#endregion
|
|
|
|
|
|
-
|
|
|
- public void AddVisualFilter(string column, string value, FilterType filtertype = FilterType.Contains)
|
|
|
- {
|
|
|
- if (value.IsNullOrWhiteSpace())
|
|
|
- return;
|
|
|
- var col = _tree.Columns.FirstOrDefault((x => string.Equals(x.MappingName?.ToUpper(),column?.Replace(".", "_").ToUpper())));
|
|
|
- if (col != null)
|
|
|
- {
|
|
|
- col.FilterPredicates.Add(new FilterPredicate { FilterType = filtertype, FilterValue = value });
|
|
|
- }
|
|
|
- }
|
|
|
- public List<Tuple<string, Func<CoreRow, bool>>> GetFilterPredicates()
|
|
|
- {
|
|
|
- var list = new List<Tuple<string, Func<CoreRow, bool>>>();
|
|
|
- foreach (var column in _tree.Columns)
|
|
|
- {
|
|
|
- var colIndex = _tree.Columns.IndexOf(column);
|
|
|
- var col = ColumnList[colIndex];
|
|
|
- if (col is DynamicGridColumn gridColumn)
|
|
|
- {
|
|
|
- var rowPredicate = DynamicGridGridUIComponentExtension.ConvertColumnPredicates(gridColumn, column.FilterPredicates);
|
|
|
- if(rowPredicate is not null)
|
|
|
- {
|
|
|
- list.Add(new(gridColumn.ColumnName, rowPredicate));
|
|
|
- }
|
|
|
- }
|
|
|
- else if(col is DynamicActionColumn dac && dac.FilterRecord is not null)
|
|
|
- {
|
|
|
- if(dac.SelectedFilters is not null && dac.SelectedFilters.Length > 0)
|
|
|
- {
|
|
|
- list.Add(new(column.MappingName, (row) => dac.FilterRecord(row, dac.SelectedFilters)));
|
|
|
- }
|
|
|
- if(dac.ExcludeFilters is not null && dac.ExcludeFilters.Length > 0)
|
|
|
- {
|
|
|
- list.Add(new(column.MappingName, (row) => !dac.FilterRecord(row, dac.ExcludeFilters)));
|
|
|
- }
|
|
|
- }
|
|
|
- }
|
|
|
- return list;
|
|
|
- }
|
|
|
-
|
|
|
- public CoreRow[] GetVisibleRows()
|
|
|
- {
|
|
|
- return _tree.View?.Nodes.Select(x => MapRow((x.Item as CoreTreeNode)?.Row)).NotNull().ToArray() ?? new CoreRow[] { };
|
|
|
- }
|
|
|
+ #region Invalidation + Updating
|
|
|
|
|
|
public void InvalidateRow(CoreRow row)
|
|
|
{
|
|
@@ -1219,21 +1257,6 @@ public class DynamicGridTreeUIComponent<T> : IDynamicGridUIComponent<T>, IDynami
|
|
|
_invalidating = false;
|
|
|
}
|
|
|
|
|
|
-
|
|
|
- public void ScrollIntoView(CoreRow row)
|
|
|
- {
|
|
|
- _tree.ScrollInView(new RowColumnIndex(row.Index + 1, 0));
|
|
|
- }
|
|
|
-
|
|
|
- private CoreTreeNode? GetNode(CoreRow row)
|
|
|
- {
|
|
|
- if (_innerTable is null || row.Index < 0 || row.Index >= _innerTable.Rows.Count) return null;
|
|
|
-
|
|
|
- var _innerRow = _innerTable.Rows[row.Index];
|
|
|
- var node = Nodes.Find(_innerRow);
|
|
|
- return node;
|
|
|
- }
|
|
|
-
|
|
|
public void UpdateCell(CoreRow row, string column, object? value)
|
|
|
{
|
|
|
var node = GetNode(row);
|
|
@@ -1243,9 +1266,9 @@ public class DynamicGridTreeUIComponent<T> : IDynamicGridUIComponent<T>, IDynami
|
|
|
node.InvalidateData();
|
|
|
}
|
|
|
}
|
|
|
+
|
|
|
public void UpdateCell(CoreRow row, DynamicColumnBase column)
|
|
|
{
|
|
|
-
|
|
|
var node = GetNode(row);
|
|
|
if(node is not null)
|
|
|
{
|
|
@@ -1261,21 +1284,33 @@ public class DynamicGridTreeUIComponent<T> : IDynamicGridUIComponent<T>, IDynami
|
|
|
}
|
|
|
}
|
|
|
|
|
|
+ public void UpdateRow(CoreRow row, CoreTreeNode dataRow)
|
|
|
+ {
|
|
|
+ foreach(var (key, value) in row)
|
|
|
+ {
|
|
|
+ dataRow[key] = value;
|
|
|
+ }
|
|
|
+ for (var i = 0; i < ActionColumns.Count; i++)
|
|
|
+ dataRow[$"_ActionColumn{i}"] = ActionColumns[i].Data(row);
|
|
|
+ dataRow.InvalidateData();
|
|
|
+ }
|
|
|
+
|
|
|
public void UpdateRow(CoreRow row)
|
|
|
{
|
|
|
var dataRow = GetNode(row);
|
|
|
if(dataRow is not null)
|
|
|
{
|
|
|
- foreach(var (key, value) in row)
|
|
|
- {
|
|
|
- dataRow[key] = value;
|
|
|
- }
|
|
|
- for (var i = 0; i < ActionColumns.Count; i++)
|
|
|
- dataRow[$"_ActionColumn{i}"] = ActionColumns[i].Data(row);
|
|
|
- dataRow.InvalidateData();
|
|
|
+ UpdateRow(row, dataRow);
|
|
|
}
|
|
|
}
|
|
|
|
|
|
+ #endregion
|
|
|
+
|
|
|
+ public void ScrollIntoView(CoreRow row)
|
|
|
+ {
|
|
|
+ _tree.ScrollInView(new RowColumnIndex(row.Index + 1, 0));
|
|
|
+ }
|
|
|
+
|
|
|
#region Direct Edit
|
|
|
|
|
|
private void _tree_PreviewKeyUp(object sender, KeyEventArgs e)
|
|
@@ -1297,6 +1332,13 @@ public class DynamicGridTreeUIComponent<T> : IDynamicGridUIComponent<T>, IDynami
|
|
|
e.Handled = true;
|
|
|
}
|
|
|
}
|
|
|
+ else if(e.Key == Key.Escape)
|
|
|
+ {
|
|
|
+ if (Parent.IsDirectEditMode())
|
|
|
+ {
|
|
|
+ bChanged = false;
|
|
|
+ }
|
|
|
+ }
|
|
|
}
|
|
|
|
|
|
private bool bChanged;
|
|
@@ -1468,6 +1510,18 @@ public class DynamicGridTreeUIComponent<T> : IDynamicGridUIComponent<T>, IDynami
|
|
|
}
|
|
|
}
|
|
|
|
|
|
+ private void CancelEdit()
|
|
|
+ {
|
|
|
+ var obj = _editingObject;
|
|
|
+ bChanged = false;
|
|
|
+ _editingObject = null;
|
|
|
+ _tree.SelectionController.CurrentCellManager.EndEdit(false);
|
|
|
+ if(obj is not null)
|
|
|
+ {
|
|
|
+ UpdateRow(obj.Row, obj.Node);
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
private void _tree_CurrentCellEndEdit(object? sender, CurrentCellEndEditEventArgs e)
|
|
|
{
|
|
|
if (_editingObject is not null && bChanged)
|