Analysis-Services/AlmToolkit/BismNormalizer/TabularCompare/UI/TreeGridNode.cs
2023-09-28 08:08:39 -07:00

507 lines
11 KiB
C#

using System;
using System.Windows.Forms;
using System.Drawing;
using System.Collections.Generic;
using System.Diagnostics;
using System.ComponentModel;
using System.ComponentModel.Design;
using System.ComponentModel.Design.Serialization;
using System.Drawing.Design;
using System.Text;
namespace BismNormalizer.TabularCompare.UI
{
[
ToolboxItem(false),
DesignTimeVisible(false)
]
public class TreeGridNode : DataGridViewRow//, IComponent
{
internal TreeGridView _grid;
internal TreeGridNode _parent;
internal TreeGridNodeCollection _owner;
internal bool IsExpanded;
internal bool IsRoot;
internal bool _isSited;
internal bool _isFirstSibling;
internal bool _isLastSibling;
internal Image _image;
internal int _imageIndex;
private Random rndSeed = new Random();
public int UniqueValue = -1;
TreeGridCell _treeCell;
TreeGridNodeCollection childrenNodes;
private int _index;
private int _level;
private bool childCellsCreated = false;
// needed for IComponent
private ISite site = null;
private EventHandler disposed = null;
internal TreeGridNode(TreeGridView owner)
: this()
{
this._grid = owner;
this.IsExpanded = true;
}
public TreeGridNode()
{
_index = -1;
_level = -1;
IsExpanded = false;
UniqueValue = this.rndSeed.Next();
_isSited = false;
_isFirstSibling = false;
_isLastSibling = false;
_imageIndex = -1;
}
public override object Clone()
{
TreeGridNode r = (TreeGridNode)base.Clone();
r.UniqueValue = -1;
r._level = this._level;
r._grid = this._grid;
r._parent = this.Parent;
r._imageIndex = this._imageIndex;
if (r._imageIndex == -1)
r.Image = this.Image;
r.IsExpanded = this.IsExpanded;
//r.treeCell = new TreeGridCell();
return r;
}
internal protected virtual void UnSited()
{
// This row is being removed from being displayed on the grid.
TreeGridCell cell;
foreach (DataGridViewCell DGVcell in this.Cells)
{
cell = DGVcell as TreeGridCell;
if (cell != null)
{
cell.UnSited();
}
}
this._isSited = false;
}
internal protected virtual void Sited()
{
// This row is being added to the grid.
this._isSited = true;
this.childCellsCreated = true;
Debug.Assert(this._grid != null);
TreeGridCell cell;
foreach (DataGridViewCell DGVcell in this.Cells)
{
cell = DGVcell as TreeGridCell;
if (cell != null)
{
cell.Sited();// Level = this.Level;
}
}
}
// Represents the index of this row in the Grid
[System.ComponentModel.Description("Represents the index of this row in the Grid. Advanced usage."),
System.ComponentModel.EditorBrowsableAttribute(System.ComponentModel.EditorBrowsableState.Advanced),
Browsable(false),
DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]
public int RowIndex => base.Index;
// Represents the index of this row based upon its position in the collection.
[Browsable(false),
DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]
public new int Index
{
get
{
if (_index == -1)
{
// get the index from the collection if unknown
_index = this._owner.IndexOf(this);
}
return _index;
}
internal set
{
_index = value;
}
}
[Browsable(false),
EditorBrowsable( EditorBrowsableState.Never),
DesignerSerializationVisibility( DesignerSerializationVisibility.Hidden)]
public ImageList ImageList
{
get
{
if (this._grid != null)
return this._grid.ImageList;
else
return null;
}
}
private bool ShouldSerializeImageIndex() => (this._imageIndex != -1 && this._image == null);
[Category("Appearance"),
Description("..."), DefaultValue(-1),
TypeConverter(typeof(ImageIndexConverter)),
Editor("System.Windows.Forms.Design.ImageIndexEditor", typeof(UITypeEditor))]
public int ImageIndex
{
get { return _imageIndex; }
set
{
_imageIndex = value;
if (_imageIndex != -1)
{
// when a imageIndex is provided we do not store the image.
this._image = null;
}
if (this._isSited)
{
// when the image changes the cell's style must be updated
this._treeCell.UpdateStyle();
if (this.Displayed)
this._grid.InvalidateRow(this.RowIndex);
}
}
}
private bool ShouldSerializeImage() => (this._imageIndex == -1 && this._image != null);
public Image Image
{
get {
if (_image == null && _imageIndex != -1)
{
if (this.ImageList != null && this._imageIndex < this.ImageList.Images.Count)
{
// get image from image index
return this.ImageList.Images[this._imageIndex];
}
else
return null;
}
else
{
// image from image property
return this._image;
};
}
set
{
_image = value;
if (_image != null)
{
// when a image is provided we do not store the imageIndex.
this._imageIndex = -1;
}
if (this._isSited)
{
// when the image changes the cell's style must be updated
this._treeCell.UpdateStyle();
if (this.Displayed)
this._grid.InvalidateRow(this.RowIndex);
}
}
}
protected override DataGridViewCellCollection CreateCellsInstance()
{
DataGridViewCellCollection cells = base.CreateCellsInstance();
cells.CollectionChanged += cells_CollectionChanged;
return cells;
}
void cells_CollectionChanged(object sender, System.ComponentModel.CollectionChangeEventArgs e)
{
// Exit if there already is a tree cell for this row
if (_treeCell != null) return;
if (e.Action == System.ComponentModel.CollectionChangeAction.Add || e.Action == System.ComponentModel.CollectionChangeAction.Refresh)
{
TreeGridCell treeCell = null;
if (e.Element == null)
{
foreach (DataGridViewCell cell in base.Cells)
{
if (cell.GetType().IsAssignableFrom(typeof(TreeGridCell)))
{
treeCell = (TreeGridCell)cell;
break;
}
}
}
else
{
treeCell = e.Element as TreeGridCell;
}
if (treeCell != null)
_treeCell = treeCell;
}
}
[Category("Data"),
Description("The collection of root nodes in the treelist."),
DesignerSerializationVisibility(DesignerSerializationVisibility.Content)] //,
//Editor(typeof(CollectionEditor), typeof(UITypeEditor))]
public TreeGridNodeCollection Nodes
{
get
{
if (childrenNodes == null)
{
childrenNodes = new TreeGridNodeCollection(this);
}
return childrenNodes;
}
set { ;}
}
// Create a new Cell property because by default a row is not in the grid and won't
// have any cells. We have to fabricate the cell collection ourself.
[Browsable(false),
DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]
public new DataGridViewCellCollection Cells
{
get
{
if (!childCellsCreated && this.DataGridView == null)
{
if (this._grid == null) return null;
this.CreateCells(this._grid);
childCellsCreated = true;
}
return base.Cells;
}
}
[Browsable(false),
DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]
public int Level
{
get {
if (this._level == -1)
{
// calculate level
int walk = 0;
TreeGridNode walkRow = this.Parent;
while (walkRow != null)
{
walk++;
walkRow = walkRow.Parent;
}
this._level = walk;
}
return this._level; }
}
[Browsable(false),
DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]
public TreeGridNode Parent => this._parent;
[Browsable(false),
DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]
public virtual bool HasChildren => (this.childrenNodes != null && this.Nodes.Count != 0);
[Browsable(false)]
public bool IsSited => this._isSited;
[Browsable(false)]
public bool IsFirstSibling => (this.Index == 0);
[Browsable(false)]
public bool IsLastSibling
{
get
{
TreeGridNode parent = this.Parent;
if (parent != null && parent.HasChildren)
{
return (this.Index == parent.Nodes.Count - 1);
}
else
return true;
}
}
public virtual bool Collapse() => this._grid.CollapseNode(this);
public virtual bool Expand()
{
if (this._grid != null)
return this._grid.ExpandNode(this);
else
{
this.IsExpanded = true;
return true;
}
}
internal protected virtual bool InsertChildNode(int index, TreeGridNode node)
{
node._parent = this;
node._grid = this._grid;
// ensure that all children of this node has their grid set
if (this._grid != null)
UpdateChildNodes(node);
//TO_DO: do we need to use index parameter?
if ((this._isSited || this.IsRoot) && this.IsExpanded)
this._grid.SiteNode(node);
return true;
}
internal protected virtual bool InsertChildNodes(int index, params TreeGridNode[] nodes)
{
foreach (TreeGridNode node in nodes)
{
this.InsertChildNode(index, node);
}
return true;
}
internal protected virtual bool AddChildNode(TreeGridNode node)
{
node._parent = this;
node._grid = this._grid;
// ensure that all children of this node has their grid set
if (this._grid != null)
UpdateChildNodes(node);
if ((this._isSited || this.IsRoot) && this.IsExpanded && !node._isSited)
this._grid.SiteNode(node);
return true;
}
internal protected virtual bool AddChildNodes(params TreeGridNode[] nodes)
{
//TO_DO: Convert the final call into an SiteNodes??
foreach (TreeGridNode node in nodes)
{
this.AddChildNode(node);
}
return true;
}
internal protected virtual bool RemoveChildNode(TreeGridNode node)
{
if ((this.IsRoot || this._isSited) && this.IsExpanded )
{
//We only unsite out child node if we are sited and expanded.
this._grid.UnSiteNode(node);
}
node._grid = null;
node._parent = null;
return true;
}
internal protected virtual bool ClearNodes()
{
if (this.HasChildren)
{
for (int i = this.Nodes.Count - 1; i >= 0; i--)
{
this.Nodes.RemoveAt(i);
}
}
return true;
}
[
Browsable(false),
EditorBrowsable(EditorBrowsableState.Advanced)
]
public event EventHandler Disposed
{
add
{
this.disposed += value;
}
remove
{
this.disposed -= value;
}
}
[
Browsable(false),
DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)
]
public ISite Site
{
get
{
return this.site;
}
set
{
this.site = value;
}
}
private void UpdateChildNodes(TreeGridNode node)
{
if (node.HasChildren)
{
foreach (TreeGridNode childNode in node.Nodes)
{
childNode._grid = node._grid;
this.UpdateChildNodes(childNode);
}
}
}
public override string ToString()
{
StringBuilder sb = new StringBuilder(36);
sb.Append("TreeGridNode { Index=");
sb.Append(this.RowIndex.ToString(System.Globalization.CultureInfo.CurrentCulture));
sb.Append(" }");
return sb.ToString();
}
//protected override void Dispose(bool disposing) {
// if (disposing)
// {
// lock(this)
// {
// if (this.site != null && this.site.Container != null)
// {
// this.site.Container.Remove(this);
// }
// if (this.disposed != null)
// {
// this.disposed(this, EventArgs.Empty);
// }
// }
// }
// base.Dispose(disposing);
//}
}
}