|
@@ -998,6 +998,13 @@ public abstract class DynamicGrid<T> : DynamicGrid, IDynamicGridUIComponentParen
|
|
|
return result;
|
|
|
}
|
|
|
|
|
|
+ private class RowRange(int rowIdx, int size)
|
|
|
+ {
|
|
|
+ public int RowIdx { get; set; } = rowIdx;
|
|
|
+
|
|
|
+ public int Size { get; set; } = size;
|
|
|
+ }
|
|
|
+
|
|
|
public virtual void Refresh(bool reloadcolumns, bool reloaddata)
|
|
|
{
|
|
|
if (bRefreshing)
|
|
@@ -1048,21 +1055,33 @@ public abstract class DynamicGrid<T> : DynamicGrid, IDynamicGridUIComponentParen
|
|
|
}
|
|
|
else if (table is not null)
|
|
|
{
|
|
|
- MasterData = table;
|
|
|
- Dispatcher.Invoke(() =>
|
|
|
+ if(table.Offset == 0 || MasterData is null)
|
|
|
{
|
|
|
- ProcessData();
|
|
|
- DoAfterRefresh();
|
|
|
- bRefreshing = false;
|
|
|
- IsReady = true;
|
|
|
- });
|
|
|
+ MasterData = table;
|
|
|
+ Dispatcher.Invoke(() =>
|
|
|
+ {
|
|
|
+ ProcessData(null);
|
|
|
+ DoAfterRefresh();
|
|
|
+ bRefreshing = false;
|
|
|
+ IsReady = true;
|
|
|
+ });
|
|
|
+ }
|
|
|
+ else
|
|
|
+ {
|
|
|
+ int idx = MasterData.Rows.Count;
|
|
|
+ MasterData.AddPage(table);
|
|
|
+ Dispatcher.Invoke(() =>
|
|
|
+ {
|
|
|
+ ProcessData(new(idx, table.Rows.Count));
|
|
|
+ });
|
|
|
+ }
|
|
|
}
|
|
|
}
|
|
|
);
|
|
|
}
|
|
|
else
|
|
|
{
|
|
|
- ProcessData();
|
|
|
+ ProcessData(null);
|
|
|
DoAfterRefresh();
|
|
|
bRefreshing = false;
|
|
|
IsReady = true;
|
|
@@ -1121,15 +1140,27 @@ public abstract class DynamicGrid<T> : DynamicGrid, IDynamicGridUIComponentParen
|
|
|
}
|
|
|
|
|
|
|
|
|
- private void ProcessData()
|
|
|
+ /// <summary>
|
|
|
+ /// Process the data from <see cref="MasterData"/> according to <paramref name="range"/>.
|
|
|
+ /// </summary>
|
|
|
+ /// <remarks>
|
|
|
+ /// Set <paramref name="range"/> to <see langword="null"/> if this is the first page of data to be loaded. This will thus update the grid accordingly,
|
|
|
+ /// clearing all current rows, resetting columns, selection, etc. If the <paramref name="range"/> is provided, this will add to the grid the rows
|
|
|
+ /// according to the range from <see cref="MasterData"/>.
|
|
|
+ /// </remarks>
|
|
|
+ /// <param name="initialLoad"></param>
|
|
|
+ private void ProcessData(RowRange? range)
|
|
|
{
|
|
|
- Data.Columns.Clear();
|
|
|
- Data.Setters.Clear();
|
|
|
- if (MasterData != null)
|
|
|
- foreach (var column in MasterData.Columns)
|
|
|
- Data.Columns.Add(column);
|
|
|
+ if(range is null)
|
|
|
+ {
|
|
|
+ Data.Columns.Clear();
|
|
|
+ Data.Setters.Clear();
|
|
|
+ if (MasterData != null)
|
|
|
+ foreach (var column in MasterData.Columns)
|
|
|
+ Data.Columns.Add(column);
|
|
|
+ }
|
|
|
|
|
|
- LoadData();
|
|
|
+ LoadData(range);
|
|
|
}
|
|
|
|
|
|
protected readonly Dictionary<CoreRow, CoreRow> _recordmap = new();
|
|
@@ -1183,11 +1214,18 @@ public abstract class DynamicGrid<T> : DynamicGrid, IDynamicGridUIComponentParen
|
|
|
Refresh(false, false);
|
|
|
}
|
|
|
|
|
|
- private void FilterRows(CoreTable from, CoreTable into, Dictionary<CoreRow, CoreRow>? recordMap = null, Func<CoreRow, bool>? filter = null)
|
|
|
+ /// <summary>
|
|
|
+ /// Filter all given rows into <paramref name="into"/>, given that they match <paramref name="filter"/> and <see cref="FilterRecord(CoreRow)"/>.
|
|
|
+ /// If <paramref name="recordMap"/> is given, also updates the map from <paramref name="from"/> to <paramref name="into"/>.
|
|
|
+ /// </summary>
|
|
|
+ private IList<CoreRow> FilterRows(
|
|
|
+ IEnumerable<CoreRow> from,
|
|
|
+ CoreTable into,
|
|
|
+ Dictionary<CoreRow, CoreRow>? recordMap = null,
|
|
|
+ Func<CoreRow, bool>? filter = null)
|
|
|
{
|
|
|
- into.Rows.Clear();
|
|
|
- recordMap?.Clear();
|
|
|
- foreach (var row in from.Rows.ToArray())
|
|
|
+ var newRows = new List<CoreRow>();
|
|
|
+ foreach (var row in from)
|
|
|
if (FilterRecord(row) && filter?.Invoke(row) != false)
|
|
|
{
|
|
|
var newrow = into.NewRow();
|
|
@@ -1196,29 +1234,36 @@ public abstract class DynamicGrid<T> : DynamicGrid, IDynamicGridUIComponentParen
|
|
|
var value = i < row.Values.Count ? row.Values[i] : null;
|
|
|
if (into.Columns[i].DataType.IsNumeric())
|
|
|
value = into.Columns[i].DataType.IsDefault(value) ? null : value;
|
|
|
- //else if (Data.Columns[i].DataType == typeof(String[]))
|
|
|
- // value = String.Join("\n", value as String[]);
|
|
|
newrow.Values.Add(value);
|
|
|
}
|
|
|
|
|
|
- //newrow.Values.AddRange(row.Values);
|
|
|
- //if ((OnFilterRecord == null) || (OnFilterRecord(row)))
|
|
|
+ newRows.Add(newrow);
|
|
|
into.Rows.Add(newrow);
|
|
|
recordMap?.TryAdd(newrow, row);
|
|
|
}
|
|
|
+ return newRows;
|
|
|
}
|
|
|
|
|
|
- private void LoadData()
|
|
|
+ private void LoadData(RowRange? range)
|
|
|
{
|
|
|
- ResetClipBuffer();
|
|
|
if (MasterData is null)
|
|
|
return;
|
|
|
- FilterRows(MasterData, Data, _recordmap);
|
|
|
+ if(range is null)
|
|
|
+ {
|
|
|
+ ResetClipBuffer();
|
|
|
+ Data.Rows.Clear();
|
|
|
+ _recordmap.Clear();
|
|
|
|
|
|
- InvalidateGrid();
|
|
|
+ FilterRows(MasterData.Rows, Data, _recordmap);
|
|
|
|
|
|
- //ScrollBar.Value = _CurrentRow <= 0 ? 0 : _CurrentRow;
|
|
|
- SelectedRows = Array.Empty<CoreRow>();
|
|
|
+ InvalidateGrid();
|
|
|
+ SelectedRows = Array.Empty<CoreRow>();
|
|
|
+ }
|
|
|
+ else
|
|
|
+ {
|
|
|
+ var newRows = FilterRows(Enumerable.Range(range.RowIdx, range.Size).Select(i => MasterData.Rows[i]), Data, _recordmap);
|
|
|
+ UIComponent.AddPage(newRows);
|
|
|
+ }
|
|
|
}
|
|
|
|
|
|
//IncrementalList<T> _data = null;
|
|
@@ -2042,7 +2087,7 @@ public abstract class DynamicGrid<T> : DynamicGrid, IDynamicGridUIComponentParen
|
|
|
var newData = new CoreTable();
|
|
|
newData.LoadColumns(columns);
|
|
|
|
|
|
- FilterRows(data, newData, filter: row =>
|
|
|
+ FilterRows(data.Rows, newData, filter: row =>
|
|
|
{
|
|
|
foreach(var (_, predicate) in predicates)
|
|
|
{
|