123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252 |
- using InABox.Core;
- using NPOI.HSSF.Record;
- using System;
- using System.Collections.Generic;
- using System.Diagnostics.CodeAnalysis;
- using System.Linq;
- using System.Text;
- using System.Threading;
- using System.Threading.Tasks;
- using System.Windows;
- namespace InABox.DynamicGrid;
- public class CoreTableColumnSchema(CoreTable table) : IDynamicGridColumnSchema
- {
- private DynamicGridColumn[] _columns = table.Columns.Select(DynamicGridColumn.FromCoreColumn).NotNull().ToArray();
- public IEnumerable<string> ColumnNames => _columns.Select(x => x.ColumnName);
- public DynamicGridColumn GetColumn(string column)
- {
- return _columns.First(x => x.ColumnName == column);
- }
- public string? GetComment(string column)
- {
- return null;
- }
- public bool IsVisible(string column)
- {
- return true;
- }
- }
- public class CoreTableGrid : BaseDynamicGrid
- {
- public CoreTable Table { get; set; } = new();
- public IDynamicGridColumnSchema? ColumnSchema { get; set; }
- #region Config
- protected override void Init()
- {
- }
- protected override void DoReconfigure(DynamicGridOptions options)
- {
- // We can add rows by default, but not edit them.
- options.EditRows = false;
- }
- #endregion
- #region Row Manipulation
- protected override void NewRow()
- {
- // This makes use of the fact that MasterData will be equivalent to Table (see 'ReloadData()').
- var row = Table.NewRow(true);
- Table.Rows.Add(row);
- var dataRow = Data.NewRow();
- dataRow.LoadValues(row.Values);
- Data.Rows.Add(dataRow);
- _recordmap[dataRow] = row;
- InvalidateGrid();
- SelectedRows = [dataRow];
- DoChanged();
- }
- protected override bool EditRows(CoreRow[]? rows)
- {
- if(rows is null)
- {
- var row = Table.NewRow(true);
- Table.Rows.Add(row);
- var dataRow = Data.NewRow();
- dataRow.LoadValues(row.Values);
- Data.Rows.Add(dataRow);
- _recordmap[dataRow] = row;
- InvalidateGrid();
- SelectedRows = [dataRow];
- DoChanged();
- return true;
- }
- else
- {
- // It's not obvious how to edit a row, without this being overriden by a subclass. Hence, we have turned off editing,
- // and the case that 'rows' is null is just basically adding a new row.
- return false;
- }
- }
- public override void DeleteRows(params CoreRow[] rows)
- {
- foreach(var row in rows)
- {
- // This relies on MasterData being equivalent to Table.
- if(_recordmap.Remove(row, out var tableRow))
- {
- Table.Rows.Remove(tableRow);
- }
- }
- }
- protected override void MoveRows(CoreRow[] rows, int index, bool isCopy = false)
- {
- CoreRow? targetRow;
- if(index < Data.Rows.Count)
- {
- var targetDataRow = Data.Rows[index];
- targetRow = _recordmap.GetValueOrDefault(targetDataRow);
- }
- else
- {
- var lastDataRow = Data.Rows.LastOrDefault();
- if(lastDataRow is null)
- {
- targetRow = null;
- }
- else if(!_recordmap.TryGetValue(lastDataRow, out var lastTargetRow))
- {
- targetRow = null;
- }
- else if(lastTargetRow == Table.Rows.LastOrDefault())
- {
- targetRow = null;
- }
- else
- {
- targetRow = Table.Rows[lastTargetRow.Index + 1];
- }
- }
-
- if (isCopy)
- {
- rows = rows.ToArray(x =>
- {
- var row = Table.NewRow();
- row.LoadValues(x.Values);
- return row;
- });
- }
- else
- {
- foreach(var row in rows)
- {
- if(_recordmap.TryGetValue(row, out var tableRow))
- {
- Table.Rows.Remove(tableRow);
- }
- }
- }
- if(targetRow is not null)
- {
- var idx = Table.Rows.IndexOf(targetRow);
- Table.Rows.InsertRange(idx, rows);
- }
- else
- {
- Table.Rows.AddRange(rows);
- }
- Refresh(false, true);
- SelectedRows = rows.Select(row =>
- {
- return _recordmap.FirstOrDefault(x => x.Value == row).Key;
- }).NotNull().ToArray();
- }
- #endregion
- #region Columns
- private IDynamicGridColumnSchema GetColumnSchema()
- {
- return ColumnSchema ?? new CoreTableColumnSchema(Table);
- }
- protected override bool SelectColumns([NotNullWhen(true)] out DynamicGridColumns? columns)
- {
- var editor = new DynamicGridColumnsEditor(GetColumnSchema(), null)
- {
- WindowStartupLocation = WindowStartupLocation.CenterScreen
- };
- editor.DirectEdit = IsDirectEditMode();
- editor.Columns.AddRange(VisibleColumns);
- if (editor.ShowDialog().Equals(true))
- {
- columns = editor.Columns;
- return true;
- }
- else
- {
- columns = null;
- return false;
- }
- }
- private DynamicGridColumns? _columns;
- protected override DynamicGridColumns LoadColumns()
- {
- return _columns ?? base.LoadColumns();
- }
- public override DynamicGridColumns GenerateColumns()
- {
- var schema = GetColumnSchema();
- var columns = new DynamicGridColumns();
- columns.AddRange(schema.ColumnNames.Select(schema.GetColumn));
- return columns;
- }
- protected override void SaveColumns(DynamicGridColumns columns)
- {
- _columns = columns;
- }
- #endregion
- #region Data
- protected override void ReloadData(CancellationToken token, Action<CoreTable?, Exception?> action)
- {
- // I think this is all we need to do. If we were to do paging or something like that, this would fail,
- // since we would be adding the table to itself; but for now this will suffice.
- action(Table, null);
- }
- public override void OnItemSourceChanged(object value)
- {
- if(value is CoreTable table)
- {
- Table = table;
- Refresh(true, true);
- }
- }
- #endregion
- }
|