using AdvancedDataGridView;
using CommonFroms.G2D;
using CommonLang.Property;
using System;
using System.Collections;
using System.Collections.Generic;
using System.ComponentModel;
using System.Drawing;
using System.Linq;
using System.Reflection;
using System.Text;
using System.Windows.Forms;
namespace CommonFroms.Utils.TreeGrid
{
public class G2DTreeGridDocument : TreeGridNode
{
private object mValue;
public G2DTreeDataGrid OwnerTreeGrid { get; private set; }
public G2DTreeGridValueNode DocumentElement { get; private set; }
public object Value
{
get { return mValue; }
set
{
this.mValue = value;
this.Cells[1].Value = "Document";
this.Cells[2].Value = "";
this.Cells[3].Value = "";
this.DocumentElement = CreateValueNode("Document", value.GetType(), null);
this.Nodes.Clear();
this.Nodes.Add(DocumentElement);
this.DocumentElement.BindValue(value, null);
}
}
public G2DTreeGridDocument(G2DTreeDataGrid tree)
{
this.OwnerTreeGrid = tree;
}
///
/// 创建节点
///
///
///
///
///
public G2DTreeGridValueNode CreateValueNode(string name, Type type, object owner)
{
if (type.IsArray)
{
return new G2DTreeGridArrayNode(this, name, type, owner);
}
else if (type.IsPrimitive)
{
return new G2DTreeGridLeafValueNode(this, name, type, owner);
}
else if (type.IsEnum)
{
return new G2DTreeGridLeafValueNode(this, name, type, owner);
}
else if (typeof(string).Equals(type))
{
return new G2DTreeGridLeafValueNode(this, name, type, owner);
}
else if (type.IsClass)
{
if (typeof(IDictionary).IsAssignableFrom(type))
{
return new G2DTreeGridMapNode(this, name, type, owner);
}
else if (typeof(IList).IsAssignableFrom(type))
{
return new G2DTreeGridListNode(this, name, type, owner);
}
else
{
return new G2DTreeGridFieldsValueNode(this, name, type, owner);
}
}
else
{
return new G2DTreeGridFieldsValueNode(this, name, type, owner);
}
}
}
//---------------------------------------------------------------------------------------------------------------
///
/// 值类型节点基类
///
public abstract class G2DTreeGridValueNode : TreeGridNode
{
public string Name { get; private set; }
public G2DTreeGridDocument CurrentDocument { get; private set; }
public G2DTreeGridValueNode ParentValueNode { get { return Parent as G2DTreeGridValueNode; } }
public object OwnerIndexer { get { return mOwnerIndexer; } }
public object OwnerObject { get { return mOwnerObject; } }
public Type ValueType { get { return mValueType; } }
public object Value { get { return mValue; } }
public DescAttribute FieldDesc
{
get
{
if (OwnerIndexer is FieldInfo)
{
return PropertyUtil.GetAttribute(OwnerIndexer as FieldInfo);
}
return null;
}
}
public bool IsRootValue
{
get { return this.OwnerObject == null; }
}
public bool IsLeaf
{
get
{
if (mValueType.IsPrimitive)
{
return true;
}
if (mValueType.IsEnum)
{
return true;
}
if (mValueType.Equals(typeof(string)))
{
return true;
}
if (mValueType.IsClass)
{
return false;
}
return false;
}
}
public bool IsCollection
{
get
{
if (mValueType.IsArray)
{
return true;
}
if (typeof(IList).IsAssignableFrom(mValueType))
{
return true;
}
return false;
}
}
public bool IsFieldReadonly
{
get
{
return !IsLeaf;
}
}
private readonly Type mValueType;
private readonly object mOwnerObject;
private object mOwnerIndexer;
private object mValue;
public G2DTreeGridValueNode(G2DTreeGridDocument doc, string name, Type type, object owner)
{
this.CurrentDocument = doc;
this.Name = name;
this.mValueType = type;
this.mOwnerObject = owner;
}
public G2DTreeGridValueNode GetChild(string key)
{
foreach (G2DTreeGridValueNode c in Nodes)
{
if (string.Equals(c.Name, key))
{
return c;
}
}
return null;
}
public void Refresh()
{
this.Image = ToFieldImage();
this.Cells[1].Value = ToFieldString();
this.Cells[1].ToolTipText = ToFieldToolTip();
this.Cells[1].ContextMenuStrip = CurrentDocument.OwnerTreeGrid.menuNode;
this.Cells[2].Value = ToValueString();
this.Cells[2].ValueType = mValueType;
this.Cells[2].ReadOnly = IsFieldReadonly;
(this.Cells[2] as G2DTreeGridValueCell).SetValueEditType(ValueType);
this.Cells[3].Value = ToFieldCatagory();
this.Cells[3].ToolTipText = ToFieldToolTip();
}
protected void AppendChild(G2DTreeGridValueNode child)
{
if (child.ParentValueNode != null)
{
throw new Exception(string.Format("Child already have a parent : child={0} parent={1}", child.Name, child.ParentValueNode.Name));
}
this.Nodes.Add(child);
}
///
/// 如果是复合类,产生子节点
///
protected abstract void GenChilds();
///
/// 设置当前节点值(此操作 将改变当前节点结构)
///
protected abstract void SetFieldValue(G2DTreeGridValueNode child, object value);
internal void BindValue(object value, object key)
{
this.mValue = value;
this.mOwnerIndexer = key;
this.Nodes.Clear();
this.GenChilds();
this.Refresh();
}
///
/// 设置当前节点值(此操作 将改变当前节点结构)
///
///
public void SetValue(object value)
{
if (ParentValueNode != null)
{
ParentValueNode.SetFieldValue(this, value);
}
this.Refresh();
}
//----------------------------------------------------------------------
#region _Cells_
public virtual string ToFieldString()
{
return Name;
}
public virtual Image ToFieldImage()
{
return CurrentDocument.OwnerTreeGrid.img_icon_men;
}
public virtual string ToFieldToolTip()
{
if (FieldDesc != null)
{
return FieldDesc.Desc;
}
return null;
}
public virtual string ToFieldCatagory()
{
if (FieldDesc != null)
{
return FieldDesc.Category;
}
return null;
}
public virtual string ToValueString()
{
return Value + "";
}
public virtual string ToTypeString()
{
return PropertyUtil.ToTypeDefineString(mValueType);
}
#endregion
//----------------------------------------------------------------------
#region _Operators_
protected internal virtual void OnMenuOpening(CancelEventArgs e)
{
if (ParentValueNode == null)
{
e.Cancel = true;
return;
}
CurrentDocument.OwnerTreeGrid.menuNode.SuspendLayout();
try
{
foreach (ToolStripItem drop in CurrentDocument.OwnerTreeGrid.menuNode.Items)
{
drop.Visible = false;
}
if (ParentValueNode.IsCollection)
{
CurrentDocument.OwnerTreeGrid.menuNode_Delete.Visible = true;
CurrentDocument.OwnerTreeGrid.menuNode_Up.Visible = true;
CurrentDocument.OwnerTreeGrid.menuNode_Down.Visible = true;
}
else if (IsLeaf)
{
e.Cancel = true;
}
else if (IsCollection)
{
CurrentDocument.OwnerTreeGrid.menuNode_New.Visible = true;
}
else
{
if (Value != null)
{
CurrentDocument.OwnerTreeGrid.menuNode_Delete.Visible = true;
}
else
{
CurrentDocument.OwnerTreeGrid.menuNode_New.Visible = true;
}
}
}
finally
{
CurrentDocument.OwnerTreeGrid.menuNode.ResumeLayout();
}
}
protected internal virtual void OnNewContentClick()
{
object value = G2DCreateInstanceDialog.ShowCreateInstanceDialog(ValueType);
SetValue(value);
}
protected internal virtual void OnDelContentClick()
{
if (ParentValueNode != null)
{
if (ParentValueNode.IsCollection)
{
ParentValueNode.OnRemoveListItemClick(this);
}
else if (!IsLeaf)
{
SetValue(null);
}
}
}
protected internal virtual void OnMoveListItemIndexClick(int d) { }
protected internal virtual void OnRemoveListItemClick(G2DTreeGridValueNode node) { }
#endregion
//----------------------------------------------------------------------
}
//---------------------------------------------------------------------------------------------------------------
///
/// 表示基础类型
///
public class G2DTreeGridLeafValueNode : G2DTreeGridValueNode
{
public G2DTreeGridLeafValueNode(G2DTreeGridDocument doc, string name, Type type, object owner)
: base(doc, name, type, owner)
{
}
protected override void GenChilds()
{
}
protected override void SetFieldValue(G2DTreeGridValueNode child, object value)
{
}
}
//---------------------------------------------------------------------------------------------------------------
///
/// 表示类
///
public class G2DTreeGridFieldsValueNode : G2DTreeGridValueNode
{
public G2DTreeGridFieldsValueNode(G2DTreeGridDocument doc, string name, Type type, object owner)
: base(doc, name, type, owner)
{
}
protected override void GenChilds()
{
if (Value != null && !IsLeaf)
{
foreach (FieldInfo field in ValueType.GetFields())
{
if (!field.IsStatic && !field.IsLiteral && !field.IsInitOnly && field.IsPublic)
{
Type ft = field.FieldType;
object fv = field.GetValue(Value);
if (fv != null) { ft = fv.GetType(); }
G2DTreeGridValueNode fe = CurrentDocument.CreateValueNode(field.Name, ft, Value);
AppendChild(fe);
fe.BindValue(fv, field);
}
}
}
}
protected override void SetFieldValue(G2DTreeGridValueNode child, object value)
{
child = GetChild(child.Name) as G2DTreeGridValueNode;
if (child != null)
{
FieldInfo field = child.OwnerIndexer as FieldInfo;
field.SetValue(this.Value, value);
child.BindValue(value, field);
}
}
}
//---------------------------------------------------------------------------------------------------------------
///
/// 表示数组
///
public class G2DTreeGridArrayNode : G2DTreeGridValueNode
{
readonly public Type ElementType;
readonly public int Rank;
public ListAttribute ListDesc
{
get
{
if (OwnerIndexer is FieldInfo)
{
return PropertyUtil.GetAttribute(OwnerIndexer as FieldInfo);
}
return null;
}
}
public Array ArrayValue
{
get
{
if (Value != null) { return (Array)Value; } return null;
}
}
public int ArrayLength
{
get
{
if (Value != null) { return ((Array)Value).Length; } return 0;
}
}
public G2DTreeGridArrayNode(G2DTreeGridDocument doc, string name, Type type, object owner)
: base(doc, name, type, owner)
{
this.ElementType = ValueType.GetElementType();
this.Rank = ValueType.GetArrayRank();
}
protected override void GenChilds()
{
if (Value != null)
{
Array array = (Array)Value;
int i = 0;
foreach (object v in array)
{
if (v != null)
{
Type vtype = v.GetType();
G2DTreeGridValueNode ei = CurrentDocument.CreateValueNode(string.Format("[{0}]", i), vtype, Value);
AppendChild(ei);
ei.BindValue(v, i);
}
i++;
}
}
}
protected override void SetFieldValue(G2DTreeGridValueNode child, object value)
{
child = GetChild(child.Name) as G2DTreeGridValueNode;
if (child != null)
{
int i = (int)child.OwnerIndexer;
Array array = (Array)this.Value;
array.SetValue(value, i);
child.BindValue(value, i);
}
}
public override string ToValueString()
{
if (Value != null)
{
Array array = (Array)Value;
return "Length="+array.GetLength(1).ToString();
}
return "null";
}
protected internal override void OnNewContentClick()
{
object item = G2DCreateInstanceDialog.ShowCreateInstanceDialog(ElementType);
if (item != null)
{
Array dst = (Array)ReflectionUtil.CreateInstance(ValueType, ArrayLength + 1);
if (ArrayValue != null)
{
Array.Copy(ArrayValue, dst, ArrayLength);
}
dst.SetValue(item, ArrayLength);
SetValue(dst);
}
}
protected internal override void OnMoveListItemIndexClick(int d) { }
protected internal override void OnRemoveListItemClick(G2DTreeGridValueNode node)
{
if (ArrayLength > 0)
{
Array src = ArrayValue;
int newLen = ArrayLength - 1;
Array dst = (Array)ReflectionUtil.CreateInstance(ValueType, newLen);
for (int i = 0, j = 0; i < newLen && j < newLen; i++, j++)
{
if (i.Equals(node.OwnerIndexer))
{
i++;
if (i >= newLen) { break; }
}
dst.SetValue(src.GetValue(i), j);
}
}
}
}
//---------------------------------------------------------------------------------------------------------------
///
/// 表示列表
///
public class G2DTreeGridListNode : G2DTreeGridValueNode
{
readonly public Type GenericElementType;
public ListAttribute ListDesc
{
get
{
if (OwnerIndexer is FieldInfo)
{
return PropertyUtil.GetAttribute(OwnerIndexer as FieldInfo);
}
return null;
}
}
public IList ListValue
{
get
{
if (Value != null) { return (IList)Value; } return null;
}
}
public int ListCount
{
get
{
if (Value != null) { return ((IList)Value).Count; } return 0;
}
}
public G2DTreeGridListNode(G2DTreeGridDocument doc, string name, Type type, object owner)
: base(doc, name, type, owner)
{
if (ValueType.IsGenericType)
{
GenericElementType = ValueType.GetGenericArguments()[0];
}
}
protected override void GenChilds()
{
if (Value != null)
{
IList list = (IList)Value;
int i = 0;
foreach (object v in list)
{
if (v != null)
{
Type vtype = v.GetType();
G2DTreeGridValueNode ei = CurrentDocument.CreateValueNode(string.Format("[{0}]", i), vtype, Value);
AppendChild(ei);
ei.BindValue(v, i);
}
i++;
}
}
}
protected override void SetFieldValue(G2DTreeGridValueNode child, object value)
{
child = GetChild(child.Name) as G2DTreeGridValueNode;
if (child != null)
{
int i = (int)child.OwnerIndexer;
IList list = (IList)this.Value;
list[i] = value;
child.BindValue(value, i);
}
}
public override string ToValueString()
{
if (Value != null)
{
IList array = (IList)Value;
return "Count=" + array.Count.ToString();
}
return "null";
}
protected internal override void OnNewContentClick()
{
object item = G2DCreateInstanceDialog.ShowCreateInstanceDialog(GenericElementType);
if (item != null)
{
IList dst = ListValue;
if (dst == null)
{
dst = (IList)ReflectionUtil.CreateInstance(ValueType);
}
dst.Add(item);
SetValue(dst);
}
}
protected internal override void OnMoveListItemIndexClick(int d) { }
protected internal override void OnRemoveListItemClick(G2DTreeGridValueNode node)
{
IList dst = ListValue;
if (dst != null)
{
dst.Remove(node.Value);
SetValue(dst);
}
}
}
//---------------------------------------------------------------------------------------------------------------
///
/// 表示字典
///
public class G2DTreeGridMapNode : G2DTreeGridValueNode
{
readonly public Type GenericKeyType;
readonly public Type GenericValueType;
public IDictionary MapValue
{
get
{
if (Value != null) { return (IDictionary)Value; } return null;
}
}
public G2DTreeGridMapNode(G2DTreeGridDocument doc, string name, Type type, object owner)
: base(doc, name, type, owner)
{
if (ValueType.IsGenericType)
{
GenericKeyType = ValueType.GetGenericArguments()[0];
GenericValueType = ValueType.GetGenericArguments()[1];
}
else
{
GenericKeyType = null;
GenericValueType = null;
}
}
protected override void GenChilds()
{
if (Value != null)
{
IDictionary map = (IDictionary)Value;
foreach (object k in map.Keys)
{
object v = map[k];
if (v != null)
{
Type vtype = v.GetType();
G2DTreeGridValueNode ei = CurrentDocument.CreateValueNode(string.Format("[{0}]", k), vtype, this.Value);
AppendChild(ei);
ei.BindValue(v, k);
}
}
}
}
protected override void SetFieldValue(G2DTreeGridValueNode child, object value)
{
child = GetChild(child.Name) as G2DTreeGridValueNode;
if (child != null)
{
IDictionary map = (IDictionary)this.Value;
map[child.OwnerIndexer] = value;
child.BindValue(value, child.OwnerIndexer);
}
}
}
//---------------------------------------------------------------------------------------------------------------
}