DotNet 4.8.1 build of DotNetBar
This commit is contained in:
@@ -0,0 +1,533 @@
|
||||
using System;
|
||||
using System.Drawing;
|
||||
|
||||
namespace DevComponents.DotNetBar.SuperGrid
|
||||
{
|
||||
/// <summary>
|
||||
/// Defines the collection of Virtual Rows
|
||||
/// </summary>
|
||||
public class GridVirtualRows
|
||||
{
|
||||
#region Private Variables
|
||||
|
||||
private GridContainer _Container;
|
||||
|
||||
private const int MaxRows = 50;
|
||||
private const int MaxBuckets = 100;
|
||||
|
||||
private int _BucketHead;
|
||||
private VPageBucket _LastAccessedBucket;
|
||||
private VPageBucket[] _PageBuckets;
|
||||
|
||||
#endregion
|
||||
|
||||
///<summary>
|
||||
/// GridVirtualRowList
|
||||
///</summary>
|
||||
///<param name="container"></param>
|
||||
public GridVirtualRows(GridContainer container)
|
||||
{
|
||||
_Container = container;
|
||||
|
||||
_PageBuckets = new VPageBucket[MaxBuckets];
|
||||
_PageBuckets[0] = new VPageBucket(_Container, 0);
|
||||
}
|
||||
|
||||
#region Public properties
|
||||
|
||||
#region MaxRowIndex
|
||||
|
||||
///<summary>
|
||||
/// MaxRowIndex
|
||||
///</summary>
|
||||
///<exception cref="Exception"></exception>
|
||||
public int MaxRowIndex
|
||||
{
|
||||
get { return (GetMaxRowIndex()); }
|
||||
set { TruncateRowIndex(value); }
|
||||
}
|
||||
|
||||
#region TruncateRowIndex
|
||||
|
||||
private void TruncateRowIndex(int index)
|
||||
{
|
||||
_LastAccessedBucket = null;
|
||||
|
||||
for (int i = 0; i < MaxBuckets; i++)
|
||||
{
|
||||
int n = (_BucketHead + i) % MaxBuckets;
|
||||
|
||||
if (_PageBuckets[n] != null)
|
||||
{
|
||||
if (_PageBuckets[n].StartIndex >= index)
|
||||
_PageBuckets[n] = null;
|
||||
|
||||
else if (_PageBuckets[n].EndIndex > index)
|
||||
{
|
||||
for (int j = 0; j < MaxRows; j++)
|
||||
{
|
||||
if (_PageBuckets[n].StartIndex + j > index)
|
||||
_PageBuckets[n].Rows[j] = null;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region GetMaxRowIndex
|
||||
|
||||
private int GetMaxRowIndex()
|
||||
{
|
||||
int maxIndex = 0;
|
||||
|
||||
for (int i = 0; i < MaxBuckets; i++)
|
||||
{
|
||||
int n = (_BucketHead + i) % MaxBuckets;
|
||||
|
||||
VPageBucket bucket = _PageBuckets[n];
|
||||
|
||||
if (bucket != null)
|
||||
{
|
||||
int index = bucket.StartIndex;
|
||||
|
||||
if (index >= maxIndex)
|
||||
{
|
||||
foreach (GridRow row in bucket.Rows)
|
||||
{
|
||||
if (row != null)
|
||||
{
|
||||
if (row.GridIndex > maxIndex)
|
||||
maxIndex = row.GridIndex;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return (maxIndex);
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#endregion
|
||||
|
||||
#region Row Indexer
|
||||
|
||||
///<summary>
|
||||
/// Row indexer
|
||||
///</summary>
|
||||
///<param name="index"></param>
|
||||
public GridRow this[int index]
|
||||
{
|
||||
get { return (GetRow(index)); }
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#endregion
|
||||
|
||||
#region FindBucket
|
||||
|
||||
private VPageBucket FindBucket(int index)
|
||||
{
|
||||
if (_LastAccessedBucket != null)
|
||||
{
|
||||
if (_LastAccessedBucket.Contains(index))
|
||||
return (_LastAccessedBucket);
|
||||
}
|
||||
|
||||
for (int i = 0; i < MaxBuckets; i++)
|
||||
{
|
||||
int n = (_BucketHead + i) % MaxBuckets;
|
||||
|
||||
if (_PageBuckets[n] != null)
|
||||
{
|
||||
if (_PageBuckets[n].Contains(index))
|
||||
return (_PageBuckets[n]);
|
||||
}
|
||||
}
|
||||
|
||||
return (null);
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region FreeRow
|
||||
|
||||
///<summary>
|
||||
/// FreeRow
|
||||
///</summary>
|
||||
///<param name="index"></param>
|
||||
///<returns></returns>
|
||||
///<exception cref="Exception"></exception>
|
||||
public void FreeRow(int index)
|
||||
{
|
||||
VPageBucket bucket = FindBucket(index);
|
||||
|
||||
if (bucket != null)
|
||||
{
|
||||
GridRow[] rows = bucket.Rows;
|
||||
GridRow row = rows[index - bucket.StartIndex];
|
||||
|
||||
if (row != null)
|
||||
{
|
||||
row.Dispose();
|
||||
rows[index - bucket.StartIndex] = null;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region IsCachedRow
|
||||
|
||||
///<summary>
|
||||
/// Gets whether the row is currently cached
|
||||
///</summary>
|
||||
public bool IsCachedRow(int index)
|
||||
{
|
||||
if (_LastAccessedBucket != null)
|
||||
{
|
||||
if (_LastAccessedBucket.Contains(index) == true)
|
||||
return (_LastAccessedBucket.IsCached(index));
|
||||
}
|
||||
|
||||
for (int i = 0; i < MaxBuckets; i++)
|
||||
{
|
||||
int n = (_BucketHead + i) % MaxBuckets;
|
||||
|
||||
if (_PageBuckets[n] != null)
|
||||
{
|
||||
if (_PageBuckets[n].Contains(index) == true)
|
||||
return (_PageBuckets[n].IsCached(index));
|
||||
}
|
||||
}
|
||||
|
||||
return (false);
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region GetRow
|
||||
|
||||
private GridRow GetRow(int index)
|
||||
{
|
||||
if (_LastAccessedBucket != null)
|
||||
{
|
||||
if (_LastAccessedBucket.Contains(index))
|
||||
return (_LastAccessedBucket[index]);
|
||||
}
|
||||
|
||||
for (int i = 0; i < MaxBuckets; i++)
|
||||
{
|
||||
int n = (_BucketHead + i) % MaxBuckets;
|
||||
|
||||
if (_PageBuckets[n] == null)
|
||||
return (NewBucketRow(n, index));
|
||||
|
||||
if (_PageBuckets[n].Contains(index))
|
||||
{
|
||||
_LastAccessedBucket = _PageBuckets[n];
|
||||
|
||||
return (_LastAccessedBucket[index]);
|
||||
}
|
||||
}
|
||||
|
||||
int bucket = _BucketHead;
|
||||
|
||||
GridPanel panel = _Container.GridPanel;
|
||||
|
||||
if (panel != null)
|
||||
{
|
||||
for (int i = 0; i < MaxBuckets; i++)
|
||||
{
|
||||
bucket = (_BucketHead + i) % MaxBuckets;
|
||||
|
||||
if (panel.FrozenRowCount > 0)
|
||||
{
|
||||
if (_PageBuckets[bucket].Contains(0))
|
||||
continue;
|
||||
}
|
||||
|
||||
if (panel.ActiveRow != null)
|
||||
{
|
||||
if (_PageBuckets[bucket].Contains(panel.ActiveRow.Index))
|
||||
continue;
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
_BucketHead = (bucket + 1) % MaxBuckets;
|
||||
|
||||
return (NewBucketRow(bucket, index));
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region NewBucketRow
|
||||
|
||||
private GridRow NewBucketRow(int n, int index)
|
||||
{
|
||||
int startIndex = (index / MaxRows) * MaxRows;
|
||||
|
||||
if (_PageBuckets[n] != null)
|
||||
_PageBuckets[n].Reset(_Container, startIndex);
|
||||
else
|
||||
_PageBuckets[n] = new VPageBucket(_Container, startIndex);
|
||||
|
||||
_LastAccessedBucket = _PageBuckets[n];
|
||||
|
||||
return (_LastAccessedBucket[index]);
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region Clear
|
||||
|
||||
///<summary>
|
||||
/// Clear
|
||||
///</summary>
|
||||
public void Clear()
|
||||
{
|
||||
for (int i = 0; i < MaxBuckets; i++)
|
||||
{
|
||||
if (_PageBuckets[i] != null)
|
||||
_PageBuckets[i].Reset(null, 0);
|
||||
|
||||
_PageBuckets[i] = null;
|
||||
}
|
||||
|
||||
_BucketHead = 0;
|
||||
_LastAccessedBucket = null;
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region VPageBucket
|
||||
|
||||
private class VPageBucket
|
||||
{
|
||||
#region Static data
|
||||
|
||||
static private GridLayoutInfo _layoutInfo = new GridLayoutInfo(null, Rectangle.Empty);
|
||||
static private GridLayoutStateInfo _stateInfo = new GridLayoutStateInfo(null, 0);
|
||||
|
||||
#endregion
|
||||
|
||||
#region Private variables
|
||||
|
||||
private GridContainer _Container;
|
||||
private int _StartIndex;
|
||||
private int _EndIndex;
|
||||
|
||||
private GridRow[] _Rows;
|
||||
|
||||
#endregion
|
||||
|
||||
public VPageBucket(GridContainer container, int startIndex)
|
||||
{
|
||||
_Container = container;
|
||||
_StartIndex = startIndex;
|
||||
_EndIndex = startIndex + MaxRows - 1;
|
||||
|
||||
_Rows = new GridRow[MaxRows];
|
||||
}
|
||||
|
||||
#region Public properties
|
||||
|
||||
#region EndIndex
|
||||
|
||||
public int EndIndex
|
||||
{
|
||||
get { return (_EndIndex); }
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region Row Indexer
|
||||
|
||||
///<summary>
|
||||
/// Row indexer
|
||||
///</summary>
|
||||
///<param name="index"></param>
|
||||
public GridRow this[int index]
|
||||
{
|
||||
get { return (GetRow(index)); }
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region Rows
|
||||
|
||||
public GridRow[] Rows
|
||||
{
|
||||
get { return (_Rows); }
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region StartIndex
|
||||
|
||||
public int StartIndex
|
||||
{
|
||||
get { return (_StartIndex); }
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#endregion
|
||||
|
||||
#region Contains
|
||||
|
||||
public bool Contains(int index)
|
||||
{
|
||||
return (index >= _StartIndex && index <= _EndIndex);
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region IsCached
|
||||
|
||||
public bool IsCached(int index)
|
||||
{
|
||||
if (Contains(index) == true)
|
||||
return (_Rows[index - _StartIndex] != null);
|
||||
|
||||
return (false);
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region GetRow
|
||||
|
||||
private GridRow GetRow(int index)
|
||||
{
|
||||
int n = index - _StartIndex;
|
||||
|
||||
if (_Rows[n] == null)
|
||||
_Rows[n] = AllocNewGridRow(index);
|
||||
|
||||
GridRow row = _Rows[n];
|
||||
|
||||
if (row.ArrangeLayoutCount != row.SuperGrid.ArrangeLayoutCount)
|
||||
ArrangeRow(row.GridPanel, row);
|
||||
|
||||
return (row);
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region Reset
|
||||
|
||||
public void Reset(GridContainer container, int startIndex)
|
||||
{
|
||||
for (int i = 0; i < MaxRows; i++)
|
||||
{
|
||||
GridRow row = _Rows[i];
|
||||
|
||||
if (row != null)
|
||||
{
|
||||
row.Dispose();
|
||||
|
||||
_Rows[i] = null;
|
||||
}
|
||||
}
|
||||
|
||||
_Container = container;
|
||||
_StartIndex = startIndex;
|
||||
_EndIndex = startIndex + MaxRows - 1;
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region AllocNewGridRow
|
||||
|
||||
private GridRow AllocNewGridRow(int index)
|
||||
{
|
||||
GridPanel panel = _Container.GridPanel;
|
||||
|
||||
if (panel != null)
|
||||
{
|
||||
GridRow row = new GridRow();
|
||||
|
||||
row.Parent = _Container;
|
||||
|
||||
row.GridIndex = index;
|
||||
row.Index = index;
|
||||
row.RowIndex = index;
|
||||
row.FullIndex = index;
|
||||
|
||||
row.MergeUpdateCount = _Container.MergeUpdateCount;
|
||||
row.MergeUpdateCount--;
|
||||
|
||||
row.Loading = true;
|
||||
|
||||
try
|
||||
{
|
||||
GridColumnCollection columns = panel.Columns;
|
||||
|
||||
if (columns.Count > 0)
|
||||
{
|
||||
for (int i = 0; i < columns.Count; i++)
|
||||
{
|
||||
GridColumn col = panel.Columns[i];
|
||||
|
||||
GridCell cell = new GridCell(col.DefaultNewRowCellValue);
|
||||
|
||||
cell.Parent = row;
|
||||
cell.ColumnIndex = i;
|
||||
|
||||
row.Cells.Add(cell);
|
||||
}
|
||||
}
|
||||
|
||||
ArrangeRow(panel, row);
|
||||
|
||||
if (columns.Count > 0)
|
||||
{
|
||||
_Container.SuperGrid.DoLoadVirtualRowEvent(panel, row);
|
||||
_Container.SuperGrid.DoVirtualRowLoadedEvent(panel, row);
|
||||
}
|
||||
}
|
||||
finally
|
||||
{
|
||||
row.Loading = false;
|
||||
}
|
||||
|
||||
return (row);
|
||||
}
|
||||
|
||||
return (null);
|
||||
}
|
||||
|
||||
#region ArrangeRow
|
||||
|
||||
private void ArrangeRow(GridPanel panel, GridRow row)
|
||||
{
|
||||
Rectangle r = panel.BoundsRelative;
|
||||
|
||||
int vrh = Dpi.Height(panel.VirtualRowHeight);
|
||||
|
||||
r.Y += (panel.FixedRowHeight - (panel.FrozenRowCount * vrh));
|
||||
r.Y += (row.Index * vrh);
|
||||
|
||||
r.Size = new Size(panel.ColumnHeader.Size.Width, vrh);
|
||||
|
||||
_layoutInfo.ClientBounds = r;
|
||||
_stateInfo.GridPanel = panel;
|
||||
|
||||
row.FixedRowHeight = r.Size.Height;
|
||||
row.Arrange(_layoutInfo, _stateInfo, r);
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#endregion
|
||||
}
|
||||
|
||||
#endregion
|
||||
}
|
||||
}
|
Reference in New Issue
Block a user