Prechádzať zdrojové kódy

产品跟踪表1.新增查询条件:是否显示装配信息2.查询修改(显示某工序的装配组件)

qinqi 3 rokov pred
rodič
commit
f41f69f794

+ 7 - 0
DK.Basics/BaseControls/BaseControls.csproj

@@ -109,6 +109,13 @@
     <Compile Include="DataGridView\C_DGV_ListBoxComboBox\C_DGV_ListBoxComboBox.Designer.cs">
       <DependentUpon>C_DGV_ListBoxComboBox.cs</DependentUpon>
     </Compile>
+    <Compile Include="DataGridView\dkDataGridView.designer.cs">
+      <DependentUpon>dkDataGridView.cs</DependentUpon>
+    </Compile>
+    <Compile Include="DataGridView\TreeGridCell.cs" />
+    <Compile Include="DataGridView\TreeGridEvents.cs" />
+    <Compile Include="DataGridView\TreeGridNode.cs" />
+    <Compile Include="DataGridView\TreeGridNodeCollection.cs" />
     <Compile Include="ListBox\C_ListBox.cs">
       <SubType>Component</SubType>
     </Compile>

+ 356 - 6
DK.Basics/BaseControls/DataGridView/C_DataGridView.cs

@@ -131,6 +131,9 @@ namespace Dongke.IBOSS.PRD.Basics.BaseControls
         private ContextMenuStrip _ctxCell;
         private ToolStripMenuItem _mnuFrozen = new ToolStripMenuItem();
         private ToolStripRefine _mnuRefine = new ToolStripRefine();                                         // 条件过滤
+        private Label _titleLabel = null;               // 周兴 2020-6-11 增加 用户显示行数
+        private DataTable _nodeTable = null;            // 有节点时直接放数据源
+        private List<TreeGridNode> _nodeList = null;
         private ToolStripMenuItem _mnuFilter = new ToolStripMenuItem();                                     // 过滤
         private ToolStripMenuItem _mnuFilterExcept = new ToolStripMenuItem();                               // 除外过滤
         private ToolStripMenuItem _mnuUnfilter = new ToolStripMenuItem();                                   // 清除过滤
@@ -176,6 +179,8 @@ namespace Dongke.IBOSS.PRD.Basics.BaseControls
         private DataTable dt;//绑定的表
         private string filter = "";//filter字符串
         private bool _isOpenTotalRow = false;
+        private bool _isHasNode = false;
+        private bool _virtualNodes = false;
         private DataGridViewColumnInfo[] _columnInfos = null;
 
         #endregion
@@ -196,7 +201,23 @@ namespace Dongke.IBOSS.PRD.Basics.BaseControls
                 _isClearSelected = value;
             }
         }
+        public bool VirtualNodes
+        {
+            get { return _virtualNodes; }
+            set { _virtualNodes = value; }
+        }
 
+        public bool HasNode
+        {
+            get
+            {
+                return this._isHasNode;
+            }
+            set
+            {
+                this._isHasNode = value;
+            }
+        }
         [System.ComponentModel.DefaultValue(false)]
         [System.ComponentModel.Description("删除标识。")]
         public bool IsShowDelete
@@ -1848,13 +1869,91 @@ namespace Dongke.IBOSS.PRD.Basics.BaseControls
 			this.EndEdit();
 			this.CommitEdit(DataGridViewDataErrorContexts.Commit);
 		}
-		#endregion
+        #endregion
 
-		#region 私有方法
-		/// <summary>
-		/// 设置列表的背景颜色
-		/// </summary>
-		public void SetDataGridViewRowColor()
+        #region 私有方法
+        /// <summary>
+        /// 设置行数的显示
+        /// </summary>
+        private void SetTitleRowsCount()
+        {
+            if (IsDispRowCount && this.RowHeadersVisible)
+            {
+                if (_titleLabel == null)
+                {
+                    // 设定位置
+                    _titleLabel = new Label();
+                    _titleLabel.BackColor = Color.Transparent;
+                    _titleLabel.ForeColor = Color.White;
+                    _titleLabel.AutoSize = false;
+                    _titleLabel.TextAlign = System.Drawing.ContentAlignment.MiddleCenter;
+                }
+
+                _titleLabel.Location = new Point(0, 0);
+                _titleLabel.Size = new Size(this.RowHeadersWidth, this.ColumnHeadersHeight);
+
+                // KeyDown事件
+                _titleLabel.KeyDown += (sender, e) =>
+                {
+                    this.OnKeyDown(e);
+                };
+
+                // 当前选择行的Index
+                int currentIndex = 0;
+                if (this.CurrentRow != null)
+                {
+                    currentIndex = this.CurrentRow.Index;
+                }
+
+                int rowCount = this.Rows.Count;
+                //DataTable table = this.DataSource as DataTable;
+                DataTable table = null;
+                if (this.CurrentDataTable != null)
+                {
+                    table = this.CurrentDataTable.DefaultView.ToTable();
+                }
+                else
+                {
+                    table = this.DataSource as DataTable;
+                }
+
+                if (this.HasNode)
+                {
+                    table = _nodeTable;
+                }
+
+                if (table != null && table.Rows.Count > 0)
+                {
+                    rowCount = table.Rows.Count;
+
+                    if (this.HasNode && _nodeList.Count > 0)
+                    {
+                        rowCount = _nodeList.Count;
+                    }
+                    //if (this.AllowUserToAddRows)
+                    //{
+                    //	rowCount--;
+                    //}
+                    string comment = string.Format("{0}/{1}", currentIndex + 1, rowCount);
+                    _titleLabel.Text = comment;
+                    _titleLabel.Refresh();
+                    _titleLabel.Visible = true;
+                    this.Controls.Add(_titleLabel);
+                }
+                else
+                {
+                    // 如果没有数据源,那么不显示行数label,否则全部隐藏列后,keydown事件不好使
+                    if (_titleLabel != null)
+                    {
+                        _titleLabel.Visible = false;
+                    }
+                }
+            }
+        }
+        /// <summary>
+        /// 设置列表的背景颜色
+        /// </summary>
+        public void SetDataGridViewRowColor()
 		{
 			try
 			{
@@ -3972,6 +4071,257 @@ namespace Dongke.IBOSS.PRD.Basics.BaseControls
             return retColumn;
         }
         #endregion
+
+        internal protected virtual bool CollapseNode(TreeGridNode node)
+        {
+            if (node.IsExpanded)
+            {
+                CollapsingEventArgs exp = new CollapsingEventArgs(node);
+                this.OnNodeCollapsing(exp);
+
+                if (!exp.Cancel)
+                {
+                    this.LockVerticalScrollBarUpdate(true);
+                    this.SuspendLayout();
+                    _inExpandCollapse = true;
+                    node.IsExpanded = false;
+
+                    foreach (TreeGridNode childNode in node.Nodes)
+                    {
+                        Debug.Assert(childNode.RowIndex != -1, "Row is NOT in the grid.");
+                        this.UnSiteNode(childNode);
+
+                        if (_nodeList.Contains(childNode))
+                        {
+                            _nodeList.Remove(childNode);
+                        }
+                    }
+
+                    CollapsedEventArgs exped = new CollapsedEventArgs(node);
+                    this.OnNodeCollapsed(exped);
+                    //TODO: Convert this to a specific NodeCell property
+                    _inExpandCollapse = false;
+                    this.LockVerticalScrollBarUpdate(false);
+                    this.ResumeLayout(true);
+                    this.InvalidateCell(node.Cells[0]);
+
+                    // 行数
+                    SetTitleRowsCount();
+                }
+
+                return !exp.Cancel;
+            }
+            else
+            {
+                // row isn't expanded, so we didn't do anything.				
+                return false;
+            }
+        }
+
+        internal protected virtual void SiteNode(TreeGridNode node)
+        {
+            //TODO: Raise exception if parent node is not the root or is not sited.
+            int rowIndex = -1;
+            TreeGridNode currentRow;
+            node._grid = this;
+
+            if (node.Parent != null && node.Parent.IsRoot == false)
+            {
+                // row is a child
+                Debug.Assert(node.Parent != null && node.Parent.IsExpanded == true);
+
+                if (node.Index > 0)
+                {
+                    currentRow = node.Parent.Nodes[node.Index - 1];
+                }
+                else
+                {
+                    currentRow = node.Parent;
+                }
+            }
+            else
+            {
+                // row is being added to the root
+                if (node.Index > 0)
+                {
+                    currentRow = node.Parent.Nodes[node.Index - 1];
+                }
+                else
+                {
+                    currentRow = null;
+                }
+
+            }
+
+            if (currentRow != null)
+            {
+                while (currentRow.Level >= node.Level)
+                {
+                    if (currentRow.RowIndex < base.Rows.Count - 1)
+                    {
+                        currentRow = base.Rows[currentRow.RowIndex + 1] as TreeGridNode;
+                        Debug.Assert(currentRow != null);
+                    }
+                    else
+                        // no more rows, site this node at the end.
+                        break;
+
+                }
+                if (currentRow == node.Parent)
+                    rowIndex = currentRow.RowIndex + 1;
+                else if (currentRow.Level < node.Level)
+                    rowIndex = currentRow.RowIndex;
+                else
+                    rowIndex = currentRow.RowIndex + 1;
+            }
+            else
+                rowIndex = 0;
+
+
+            Debug.Assert(rowIndex != -1);
+            this.SiteNode(node, rowIndex);
+
+            Debug.Assert(node.IsSited);
+            node.IsExpanded = _isExpandAll;
+            if (node.IsExpanded)
+            {
+                // add all child rows to display
+                foreach (TreeGridNode childNode in node.Nodes)
+                {
+                    //TODO: could use the more efficient SiteRow with index.
+                    this.SiteNode(childNode);
+                }
+            }
+        }
+
+        private bool _isExpandAll = false;
+
+        internal protected virtual void SiteNode(TreeGridNode node, int index)
+        {
+            if (index < base.Rows.Count)
+            {
+                base.Rows.Insert(index, node);
+            }
+            else
+            {
+                // for the last item.
+                base.Rows.Add(node);
+            }
+        }
+        internal protected virtual bool ExpandNode(TreeGridNode node)
+        {
+            if (!node.IsExpanded || this._virtualNodes)
+            {
+                ExpandingEventArgs exp = new ExpandingEventArgs(node);
+                this.OnNodeExpanding(exp);
+
+                if (!exp.Cancel)
+                {
+                    this.LockVerticalScrollBarUpdate(true);
+                    this.SuspendLayout();
+                    _inExpandCollapse = true;
+                    node.IsExpanded = true;
+
+                    //TODO Convert this to a InsertRange
+                    foreach (TreeGridNode childNode in node.Nodes)
+                    {
+                        Debug.Assert(childNode.RowIndex == -1, "Row is already in the grid.");
+                        this.SiteNode(childNode);
+
+                        _nodeList.Add(childNode);
+                        //this.BaseRows.Insert(rowIndex + 1, childRow);
+                        //TODO : remove -- just a test.
+                        //childNode.Cells[0].Value = "child";
+                    }
+
+                    ExpandedEventArgs exped = new ExpandedEventArgs(node);
+                    this.OnNodeExpanded(exped);
+                    //TODO: Convert this to a specific NodeCell property
+                    _inExpandCollapse = false;
+                    this.LockVerticalScrollBarUpdate(false);
+                    this.ResumeLayout(true);
+                    this.InvalidateCell(node.Cells[0]);
+
+                    // 行数
+                    SetTitleRowsCount();
+                }
+
+                return !exp.Cancel;
+            }
+            else
+            {
+                // row is already expanded, so we didn't do anything.
+                return false;
+            }
+        }
+        internal protected virtual void UnSiteNode(TreeGridNode node)
+        {
+            if (node != null && (node.IsSited || node.IsRoot))
+            {
+                // remove child rows first
+                foreach (TreeGridNode childNode in node.Nodes)
+                {
+                    this.UnSiteNode(childNode);
+                }
+
+                // now remove this row except for the root
+                if (!node.IsRoot)
+                {
+                    // zx 解决加载树形结构页面关闭时的bug
+                    try
+                    {
+                        if (base.Rows.Contains(node))
+                        {
+                            base.Rows.Remove(node);
+                            // Row isn't sited in the grid anymore after remove. Note that we cannot
+                            // Use the RowRemoved event since we cannot map from the row index to
+                            // the index of the expandable row/node.
+                            node.UnSited();
+                        }
+                    }
+                    catch (Exception ex)
+                    {
+                    }
+                }
+            }
+        }
+
+        #region 树形结构
+        public event ExpandingEventHandler NodeExpanding;
+        public event ExpandedEventHandler NodeExpanded;
+        public event CollapsingEventHandler NodeCollapsing;
+        public event CollapsedEventHandler NodeCollapsed;
+
+        protected virtual void OnNodeExpanding(ExpandingEventArgs e)
+        {
+            if (this.NodeExpanding != null)
+            {
+                NodeExpanding(this, e);
+            }
+        }
+        protected virtual void OnNodeExpanded(ExpandedEventArgs e)
+        {
+            if (this.NodeExpanded != null)
+            {
+                NodeExpanded(this, e);
+            }
+        }
+        protected virtual void OnNodeCollapsing(CollapsingEventArgs e)
+        {
+            if (this.NodeCollapsing != null)
+            {
+                NodeCollapsing(this, e);
+            }
+
+        }
+        protected virtual void OnNodeCollapsed(CollapsedEventArgs e)
+        {
+            if (this.NodeCollapsed != null)
+            {
+                NodeCollapsed(this, e);
+            }
+        }
+        #endregion
     }
 
     #region 剪贴板处理

+ 320 - 0
DK.Basics/BaseControls/DataGridView/TreeGridCell.cs

@@ -0,0 +1,320 @@
+//---------------------------------------------------------------------
+// 
+//  Copyright (c) Microsoft Corporation.  All rights reserved.
+// 
+//THIS CODE AND INFORMATION ARE PROVIDED AS IS WITHOUT WARRANTY OF ANY
+//KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE
+//IMPLIED WARRANTIES OF MERCHANTABILITY AND/OR FITNESS FOR A
+//PARTICULAR PURPOSE.
+//---------------------------------------------------------------------
+using System.Drawing;
+using System.Windows.Forms;
+using System.Threading;
+ 
+
+namespace Dongke.IBOSS.PRD.Basics.BaseControls
+{
+	/// <summary>
+	/// Summary description for TreeGridCell.
+	/// </summary>
+	public class TreeGridCell : DataGridViewTextBoxCell
+	{
+		private const int INDENT_WIDTH = 20;
+		private const int INDENT_MARGIN = 5;
+		private int glyphWidth;
+		private int calculatedLeftPadding;
+		internal bool IsSited;
+		private Padding _previousPadding;
+		private int _imageWidth = 0;
+		private int _imageHeight = 0;
+		private Image _image1;
+		private Image _image2;
+
+		public TreeGridCell()
+		{
+			glyphWidth = 15;
+			calculatedLeftPadding = 0;
+			this.IsSited = false;
+			//_image1 = (Image)System.Resources.UpgradeReport_Minus;
+			//_image2 = (Image)Resources.UpgradeReport_Plus;
+		}
+
+		public override object Clone()
+		{
+			TreeGridCell c = (TreeGridCell)base.Clone();
+			c.glyphWidth = this.glyphWidth;
+			c.calculatedLeftPadding = this.calculatedLeftPadding;
+			return c;
+		}
+
+		internal protected virtual void UnSited()
+		{
+			// The row this cell is in is being removed from the grid.
+			this.IsSited = false;
+			this.Style.Padding = this._previousPadding;
+		}
+
+		internal protected virtual void Sited()
+		{
+			// when we are added to the DGV we can realize our style
+			this.IsSited = true;
+
+			// remember what the previous padding size is so it can be restored when unsiting
+			this._previousPadding = this.Style.Padding;
+
+			this.UpdateStyle();
+		}
+
+		internal protected virtual void UpdateStyle()
+		{
+			// styles shouldn't be modified when we are not sited.
+			if (this.IsSited == false) return;
+
+			int level = this.Level;
+
+			Padding p = this._previousPadding;
+			Size preferredSize;
+
+			using (Graphics g = this.OwningNode._grid.CreateGraphics())
+			{
+				preferredSize = this.GetPreferredSize(g, this.InheritedStyle, this.RowIndex, new Size(0, 0));
+			}
+
+			//Image image = this.OwningNode.Image;
+
+			//if (image != null)
+			//{
+			//	// calculate image size
+			//	_imageWidth = image.Width + 2;
+			//	_imageHeight = image.Height + 2;
+
+			//}
+			//else
+			//{
+			//	_imageWidth = glyphWidth;
+			//	_imageHeight = 0;
+			//}
+
+			// TODO: Make this cleaner
+			if (preferredSize.Height < _imageHeight)
+			{
+
+				this.Style.Padding = new Padding(p.Left + (level * INDENT_WIDTH) + _imageWidth + INDENT_MARGIN,
+												 p.Top + (_imageHeight / 2), p.Right, p.Bottom + (_imageHeight / 2));
+			}
+			else
+			{
+				this.Style.Padding = new Padding(p.Left + (level * INDENT_WIDTH) + _imageWidth + INDENT_MARGIN,
+												 p.Top, p.Right, p.Bottom);
+
+			}
+
+			calculatedLeftPadding = ((level - 1) * glyphWidth) + _imageWidth + INDENT_MARGIN;
+		}
+
+		public int Level
+		{
+			get
+			{
+				TreeGridNode row = this.OwningNode;
+				if (row != null)
+				{
+					return row.Level;
+				}
+				else
+					return -1;
+			}
+		}
+
+		protected virtual int GlyphMargin
+		{
+			get
+			{
+				return ((this.Level - 1) * INDENT_WIDTH) + INDENT_MARGIN;
+			}
+		}
+
+		protected virtual int GlyphOffset
+		{
+			get
+			{
+				return ((this.Level - 1) * INDENT_WIDTH);
+			}
+		}
+
+		//protected override void Paint(Graphics graphics, Rectangle clipBounds,
+		//	Rectangle cellBounds, int rowIndex, DataGridViewElementStates cellState,
+		//	object value, object formattedValue, string errorText, DataGridViewCellStyle cellStyle,
+		//	DataGridViewAdvancedBorderStyle advancedBorderStyle, DataGridViewPaintParts paintParts)
+		//{
+
+		//	TreeGridNode node = this.OwningNode;
+		//	if (node == null) return;
+
+		//	//Image image = node.Image;
+
+		//	if (this._imageHeight == 0 && image != null) this.UpdateStyle();
+
+		//	// paint the cell normally
+		//	base.Paint(graphics, clipBounds, cellBounds, rowIndex, cellState, value,
+		//		formattedValue, errorText, cellStyle, advancedBorderStyle, paintParts);
+
+		//	// TODO: Indent width needs to take image size into account
+		//	Rectangle glyphRect = new Rectangle(cellBounds.X + this.GlyphMargin,
+		//		cellBounds.Y, INDENT_WIDTH, cellBounds.Height - 1);
+		//	int glyphHalf = glyphRect.Width / 2;
+
+		//	//TODO: This painting code needs to be rehashed to be cleaner
+		//	int level = this.Level;
+
+		//	// Paint tree lines			
+		//	if (node._grid != null && node._grid.ShowLines)
+		//	{
+		//		using (Pen linePen = new Pen(SystemBrushes.ControlDark, 1.0f))
+		//		{
+		//			linePen.DashStyle = System.Drawing.Drawing2D.DashStyle.Dot;
+		//			bool isLastSibling = node.IsLastSibling;
+		//			bool isFirstSibling = node.IsFirstSibling;
+		//			if (node.Level == 1)
+		//			{
+		//				// the Root nodes display their lines differently
+		//				if (isFirstSibling && isLastSibling)
+		//				{
+		//					// only node, both first and last. Just draw horizontal line
+		//					graphics.DrawLine(linePen, glyphRect.X + 4, cellBounds.Top
+		//						+ cellBounds.Height / 2, glyphRect.Right, cellBounds.Top + cellBounds.Height / 2);
+		//				}
+		//				else if (isLastSibling)
+		//				{
+		//					// last sibling doesn't draw the line extended below. Paint horizontal then vertical
+		//					graphics.DrawLine(linePen, glyphRect.X + 4, cellBounds.Top
+		//						+ cellBounds.Height / 2, glyphRect.Right, cellBounds.Top + cellBounds.Height / 2);
+		//					graphics.DrawLine(linePen, glyphRect.X + 4, cellBounds.Top, glyphRect.X + 4,
+		//						cellBounds.Top + cellBounds.Height / 2);
+		//				}
+		//				else if (isFirstSibling)
+		//				{
+		//					// first sibling doesn't draw the line extended above. Paint horizontal then vertical
+		//					graphics.DrawLine(linePen, glyphRect.X + 4, cellBounds.Top
+		//						+ cellBounds.Height / 2, glyphRect.Right, cellBounds.Top + cellBounds.Height / 2);
+		//					graphics.DrawLine(linePen, glyphRect.X + 4, cellBounds.Top
+		//						+ cellBounds.Height / 2, glyphRect.X + 4, cellBounds.Bottom);
+		//				}
+		//				else
+		//				{
+		//					// normal drawing draws extended from top to bottom. Paint horizontal then vertical
+		//					graphics.DrawLine(linePen, glyphRect.X + 4, cellBounds.Top
+		//						+ cellBounds.Height / 2, glyphRect.Right, cellBounds.Top + cellBounds.Height / 2);
+		//					graphics.DrawLine(linePen, glyphRect.X + 4, cellBounds.Top, glyphRect.X + 4, cellBounds.Bottom);
+		//				}
+		//			}
+		//			else
+		//			{
+		//				if (isLastSibling)
+		//				{
+		//					// last sibling doesn't draw the line extended below. Paint horizontal then vertical
+		//					graphics.DrawLine(linePen, glyphRect.X + 4, cellBounds.Top
+		//						+ cellBounds.Height / 2, glyphRect.Right, cellBounds.Top + cellBounds.Height / 2);
+		//					graphics.DrawLine(linePen, glyphRect.X + 4, cellBounds.Top,
+		//						glyphRect.X + 4, cellBounds.Top + cellBounds.Height / 2);
+		//				}
+		//				else
+		//				{
+		//					// normal drawing draws extended from top to bottom. Paint horizontal then vertical
+		//					graphics.DrawLine(linePen, glyphRect.X + 4, cellBounds.Top
+		//						+ cellBounds.Height / 2, glyphRect.Right, cellBounds.Top + cellBounds.Height / 2);
+		//					graphics.DrawLine(linePen, glyphRect.X + 4, cellBounds.Top, glyphRect.X + 4, cellBounds.Bottom);
+		//				}
+
+		//				// paint lines of previous levels to the root
+		//				TreeGridNode previousNode = node.Parent;
+		//				int horizontalStop = (glyphRect.X + 4) - INDENT_WIDTH;
+
+		//				while (!previousNode.IsRoot)
+		//				{
+		//					if (previousNode.HasChildren && !previousNode.IsLastSibling)
+		//					{
+		//						// paint vertical line
+		//						graphics.DrawLine(linePen, horizontalStop, cellBounds.Top, horizontalStop, cellBounds.Bottom);
+		//					}
+		//					previousNode = previousNode.Parent;
+		//					horizontalStop = horizontalStop - INDENT_WIDTH;
+		//				}
+		//			}
+		//		}
+		//	}
+		//	if (node.HasChildren || (node._grid != null && node._grid.VirtualNodes))
+		//	{
+		//		Point pp = new Point();
+		//		//Paint node glyphs				
+		//		if (node.IsExpanded)
+		//		{
+		//			pp = new Point(glyphRect.X + this.glyphWidth, cellBounds.Height / 4 + cellBounds.Y);
+		//			graphics.DrawImage(_image1, pp);
+		//		}
+		//		else
+		//		{
+		//			pp = new Point(glyphRect.X + this.glyphWidth, cellBounds.Height / 4 + cellBounds.Y);
+		//			graphics.DrawImage(_image2, pp);
+		//		}
+		//	}
+		//}
+		protected override void OnMouseUp(DataGridViewCellMouseEventArgs e)
+		{
+			base.OnMouseUp(e);
+
+			TreeGridNode node = this.OwningNode;
+			if (node != null)
+				node._grid._inExpandCollapseMouseCapture = false;
+		}
+		//protected override void OnMouseDown(DataGridViewCellMouseEventArgs e)
+		//{
+		//	if (e.Location.X > this.InheritedStyle.Padding.Left)
+		//	{
+		//		base.OnMouseDown(e);
+		//	}
+		//	else
+		//	{
+		//		// Expand the node
+		//		//TODO: Calculate more precise location
+		//		TreeGridNode node = this.OwningNode;
+		//		if (node != null)
+		//		{
+		//			node._grid._inExpandCollapseMouseCapture = true;
+		//			if (node.IsExpanded)
+		//				node.Collapse();
+		//			else
+		//				node.Expand();
+		//		}
+		//	}
+		//}
+		public TreeGridNode OwningNode
+		{
+			get { return base.OwningRow as TreeGridNode; }
+		}
+	}
+
+	public class TreeGridColumn : DataGridViewTextBoxColumn
+	{
+		internal Image _defaultNodeImage;
+
+		public TreeGridColumn()
+		{
+			this.CellTemplate = new TreeGridCell();
+		}
+
+		// Need to override Clone for design-time support.
+		public override object Clone()
+		{
+			TreeGridColumn c = (TreeGridColumn)base.Clone();
+			c._defaultNodeImage = this._defaultNodeImage;
+			return c;
+		}
+
+		public Image DefaultNodeImage
+		{
+			get { return _defaultNodeImage; }
+			set { _defaultNodeImage = value; }
+		}
+	}
+}

+ 82 - 0
DK.Basics/BaseControls/DataGridView/TreeGridEvents.cs

@@ -0,0 +1,82 @@
+//---------------------------------------------------------------------
+// 
+//  Copyright (c) Microsoft Corporation.  All rights reserved.
+// 
+//THIS CODE AND INFORMATION ARE PROVIDED AS IS WITHOUT WARRANTY OF ANY
+//KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE
+//IMPLIED WARRANTIES OF MERCHANTABILITY AND/OR FITNESS FOR A
+//PARTICULAR PURPOSE.
+//---------------------------------------------------------------------
+using System;
+using System.Collections.Generic;
+using System.Text;
+
+namespace Dongke.IBOSS.PRD.Basics.BaseControls
+{
+	public class TreeGridNodeEventBase
+	{
+		private TreeGridNode _node;
+
+		public TreeGridNodeEventBase(TreeGridNode node)
+		{
+			this._node = node;
+		}
+
+		public TreeGridNode Node
+		{
+			get { return _node; }
+		}
+	}
+	public class CollapsingEventArgs : System.ComponentModel.CancelEventArgs
+	{
+		private TreeGridNode _node;
+
+		private CollapsingEventArgs() { }
+		public CollapsingEventArgs(TreeGridNode node)
+			: base()
+		{
+			this._node = node;
+		}
+		public TreeGridNode Node
+		{
+			get { return _node; }
+		}
+
+	}
+	public class CollapsedEventArgs : TreeGridNodeEventBase
+	{
+		public CollapsedEventArgs(TreeGridNode node)
+			: base(node)
+		{
+		}
+	}
+
+	public class ExpandingEventArgs:System.ComponentModel.CancelEventArgs
+	{
+		private TreeGridNode _node;
+
+		private ExpandingEventArgs() { }
+		public ExpandingEventArgs(TreeGridNode node):base()
+		{
+			this._node = node;
+		}
+		public TreeGridNode Node
+		{
+			get { return _node; }
+		}
+
+	}
+	public class ExpandedEventArgs : TreeGridNodeEventBase
+	{
+		public ExpandedEventArgs(TreeGridNode node):base(node)
+		{
+		}
+	}
+
+	public delegate void ExpandingEventHandler(object sender, ExpandingEventArgs e);
+	public delegate void ExpandedEventHandler(object sender, ExpandedEventArgs e);
+
+	public delegate void CollapsingEventHandler(object sender, CollapsingEventArgs e);
+	public delegate void CollapsedEventHandler(object sender, CollapsedEventArgs e);
+
+}

+ 566 - 0
DK.Basics/BaseControls/DataGridView/TreeGridNode.cs

@@ -0,0 +1,566 @@
+//---------------------------------------------------------------------
+// 
+//  Copyright (c) Microsoft Corporation.  All rights reserved.
+// 
+//THIS CODE AND INFORMATION ARE PROVIDED AS IS WITHOUT WARRANTY OF ANY
+//KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE
+//IMPLIED WARRANTIES OF MERCHANTABILITY AND/OR FITNESS FOR A
+//PARTICULAR PURPOSE.
+//---------------------------------------------------------------------
+using System;
+using System.ComponentModel;
+using System.Drawing;
+using System.Drawing.Design;
+using System.Text;
+using System.Windows.Forms;
+
+namespace Dongke.IBOSS.PRD.Basics.BaseControls
+{
+	[
+		ToolboxItem(false),
+		DesignTimeVisible(false)
+	]
+	public class TreeGridNode : DataGridViewRow//, IComponent
+	{
+		internal C_DataGridView _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(dkDataGridView 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 = new 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
+		{
+			get
+			{
+				return 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()
+		{
+			return (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()
+		{
+			return (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)
+		{
+			try
+			{
+				// 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;
+							//}
+							if (cell.GetType().FullName == "Dongke.Finance.Framework.Controls.TreeGridCell")
+							{
+								treeCell = (TreeGridCell)cell;
+								break;
+							}
+						}
+					}
+					else
+					{
+						treeCell = e.Element as TreeGridCell;
+					}
+
+					if (treeCell != null)
+						_treeCell = treeCell;
+				}
+			}
+			catch (Exception ex)
+			{
+				throw ex;
+			}
+		}
+
+		[Category("Data"), Description("The collection of root nodes in the treelist.")]
+		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
+		{
+			get
+			{
+				return this._parent;
+			}
+		}
+
+		[Browsable(false),
+		 DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]
+		public virtual bool HasChildren
+		{
+			get
+			{
+				return (this.childrenNodes != null && this.Nodes.Count != 0);
+			}
+		}
+
+		[Browsable(false)]
+		public bool IsSited
+		{
+			get
+			{
+				return this._isSited;
+			}
+		}
+		[Browsable(false)]
+		public bool IsFirstSibling
+		{
+			get
+			{
+				return (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()
+		{
+			return 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);
+
+			//TODO: 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)
+		{
+			//TODO: 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);
+		//}
+	}
+
+}

+ 292 - 0
DK.Basics/BaseControls/DataGridView/TreeGridNodeCollection.cs

@@ -0,0 +1,292 @@
+//---------------------------------------------------------------------
+// 
+//  Copyright (c) Microsoft Corporation.  All rights reserved.
+// 
+//THIS CODE AND INFORMATION ARE PROVIDED AS IS WITHOUT WARRANTY OF ANY
+//KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE
+//IMPLIED WARRANTIES OF MERCHANTABILITY AND/OR FITNESS FOR A
+//PARTICULAR PURPOSE.
+//---------------------------------------------------------------------
+using System;
+using System.Collections;
+using System.Collections.Generic;
+using System.Data;
+using System.Windows.Forms;
+
+namespace Dongke.IBOSS.PRD.Basics.BaseControls
+{
+	public class TreeGridNodeCollection : IList<TreeGridNode>, IList
+	{
+		internal List<TreeGridNode> _list;
+		internal TreeGridNode _owner;
+		internal TreeGridNodeCollection(TreeGridNode owner)
+		{
+			this._owner = owner;
+			this._list = new List<TreeGridNode>();
+		}
+
+		#region Public Members
+		public void Add(TreeGridNode item)
+		{
+			// The row needs to exist in the child collection before the parent is notified.
+			item._grid = this._owner._grid;
+
+			bool hadChildren = this._owner.HasChildren;
+			item._owner = this;
+
+			this._list.Add(item);
+
+			this._owner.AddChildNode(item);
+
+			// if the owner didn't have children but now does (asserted) and it is sited update it
+			if (!hadChildren && this._owner.IsSited)
+			{
+				this._owner._grid.InvalidateRow(this._owner.RowIndex);
+			}
+		}
+
+		public TreeGridNode Add(string text)
+		{
+			TreeGridNode node = new TreeGridNode();
+			this.Add(node);
+
+			node.Cells[0].Value = text;
+			return node;
+		}
+
+		public TreeGridNode Add(params object[] values)
+		{
+			TreeGridNode node = new TreeGridNode();
+			this.Add(node);
+
+			int cell = 0;
+
+			if (values.Length > node.Cells.Count)
+				throw new ArgumentOutOfRangeException("values");
+
+			foreach (object o in values)
+			{
+				node.Cells[cell].Value = o;
+				cell++;
+			}
+			return node;
+		}
+
+		// 重载方法
+		public TreeGridNode Add(DataRow row, DataColumnCollection DataSourceColumns, DataGridViewColumnCollection columns,
+			SortedList<int, string> sortInlist, out SortedList<int, string> sortlist, TreeGridNode pNode = null)
+		{
+			try
+			{
+				TreeGridNode node = new TreeGridNode();
+				this.Add(node);
+
+				for (int i = 0; i < columns.Count; i++)
+				{
+					if (!sortInlist.ContainsValue(columns[i].DataPropertyName))
+					{
+						if (DataSourceColumns.Contains(columns[i].DataPropertyName))
+						{
+							node.Cells[columns[i].DataPropertyName].Value = row[columns[i].DataPropertyName];
+						}
+						sortInlist.Add(node.Cells[columns[i].DataPropertyName].ColumnIndex, columns[i].DataPropertyName);
+					}
+					else
+					{
+						int e = sortInlist.IndexOfValue(columns[i].DataPropertyName);
+						if (DataSourceColumns.Contains(columns[i].DataPropertyName))
+						{
+							node.Cells[e].Value = row[columns[i].DataPropertyName];
+						}
+						//node.Cells[e].Value = row[columns[i].DataPropertyName];
+					}
+				}
+				sortlist = sortInlist;
+				return node;
+			}
+			catch (Exception ex)
+			{
+				throw ex;
+			}
+		}
+
+		public void Insert(int index, TreeGridNode item)
+		{
+			// The row needs to exist in the child collection before the parent is notified.
+			item._grid = this._owner._grid;
+			item._owner = this;
+
+			this._list.Insert(index, item);
+
+			this._owner.InsertChildNode(index, item);
+		}
+
+		public bool Remove(TreeGridNode item)
+		{
+			// The parent is notified first then the row is removed from the child collection.
+			this._owner.RemoveChildNode(item);
+			item._grid = null;
+			return this._list.Remove(item);
+		}
+
+		public void RemoveAt(int index)
+		{
+			TreeGridNode row = this._list[index];
+
+			// The parent is notified first then the row is removed from the child collection.
+			this._owner.RemoveChildNode(row);
+			row._grid = null;
+			this._list.RemoveAt(index);
+		}
+
+		public void Clear()
+		{
+			// The parent is notified first then the row is removed from the child collection.
+			this._owner.ClearNodes();
+			this._list.Clear();
+		}
+
+		public int IndexOf(TreeGridNode item)
+		{
+			return this._list.IndexOf(item);
+		}
+
+		public TreeGridNode this[int index]
+		{
+			get
+			{
+				return this._list[index];
+			}
+			set
+			{
+				throw new Exception("The method or operation is not implemented.");
+			}
+		}
+
+		public bool Contains(TreeGridNode item)
+		{
+			return this._list.Contains(item);
+		}
+
+		public void CopyTo(TreeGridNode[] array, int arrayIndex)
+		{
+			throw new Exception("The method or operation is not implemented.");
+		}
+
+		public int Count
+		{
+			get { return this._list.Count; }
+		}
+
+		public bool IsReadOnly
+		{
+			get { return false; }
+		}
+		#endregion
+
+		#region IList Interface
+		void System.Collections.IList.Remove(object value)
+		{
+			this.Remove(value as TreeGridNode);
+		}
+
+
+		int System.Collections.IList.Add(object value)
+		{
+			TreeGridNode item = value as TreeGridNode;
+			this.Add(item);
+			return item.Index;
+		}
+
+		void System.Collections.IList.RemoveAt(int index)
+		{
+			this.RemoveAt(index);
+		}
+
+
+		void System.Collections.IList.Clear()
+		{
+			this.Clear();
+		}
+
+		bool System.Collections.IList.IsReadOnly
+		{
+			get { return this.IsReadOnly; }
+		}
+
+		bool System.Collections.IList.IsFixedSize
+		{
+			get { return false; }
+		}
+
+		int System.Collections.IList.IndexOf(object item)
+		{
+			return this.IndexOf(item as TreeGridNode);
+		}
+
+		void System.Collections.IList.Insert(int index, object value)
+		{
+			this.Insert(index, value as TreeGridNode);
+		}
+		int System.Collections.ICollection.Count
+		{
+			get { return this.Count; }
+		}
+		bool System.Collections.IList.Contains(object value)
+		{
+			return this.Contains(value as TreeGridNode);
+		}
+		void System.Collections.ICollection.CopyTo(Array array, int index)
+		{
+			throw new Exception("The method or operation is not implemented.");
+		}
+		object System.Collections.IList.this[int index]
+		{
+			get
+			{
+				return this[index];
+			}
+			set
+			{
+				throw new Exception("The method or operation is not implemented.");
+			}
+		}
+
+
+
+		#region IEnumerable<ExpandableRow> Members
+
+		public IEnumerator<TreeGridNode> GetEnumerator()
+		{
+			return this._list.GetEnumerator();
+		}
+
+		#endregion
+
+
+		#region IEnumerable Members
+
+		System.Collections.IEnumerator System.Collections.IEnumerable.GetEnumerator()
+		{
+			return this.GetEnumerator();
+		}
+
+		#endregion
+		#endregion
+
+		#region ICollection Members
+
+		bool System.Collections.ICollection.IsSynchronized
+		{
+			get { throw new Exception("The method or operation is not implemented."); }
+		}
+
+		object System.Collections.ICollection.SyncRoot
+		{
+			get { throw new Exception("The method or operation is not implemented."); }
+		}
+
+		#endregion
+	}
+
+}

+ 36 - 0
DK.Basics/BaseControls/DataGridView/dkDataGridView.designer.cs

@@ -0,0 +1,36 @@
+namespace Dongke.IBOSS.Framework.Controls
+{
+	partial class dkDataGridView
+	{
+		/// <summary>
+		/// 必需的设计器变量。
+		/// </summary>
+		//private System.ComponentModel.IContainer components = null;
+
+		/// <summary> 
+		/// 清理所有正在使用的资源。
+		/// </summary>
+		/// <param name="disposing">如果应释放托管资源,为 true;否则为 false。</param>
+		//protected override void Dispose(bool disposing)
+		//{
+		//	//if (disposing && (components != null))
+		//	//{
+		//	//    components.Dispose();
+		//	//}
+		//	base.Dispose(disposing);
+		//}
+
+		#region 组件设计器生成的代码
+
+		/// <summary>
+		/// 设计器支持所需的方法 - 不要
+		/// 使用代码编辑器修改此方法的内容。
+		/// </summary>
+		//private void InitializeComponent()
+		//{
+		//    components = new System.ComponentModel.Container();
+		//}
+
+		#endregion
+	}
+}

+ 81 - 4
DK.Client/ReportModule/R02/M01/F_RPT_020101_1.Designer.cs

@@ -1,4 +1,5 @@
-namespace Dongke.IBOSS.PRD.Client.ReportModule
+
+namespace Dongke.IBOSS.PRD.Client.ReportModule
 {
     partial class F_RPT_020101_1
     {
@@ -70,7 +71,7 @@
 			this.ScrapFlag = new System.Windows.Forms.DataGridViewCheckBoxColumn();
 			this.IsPublicBody = new System.Windows.Forms.DataGridViewCheckBoxColumn();
 			this.dgvProductionDetail = new Dongke.IBOSS.PRD.Basics.BaseControls.C_DataGridView();
-			this.ProductionLineCode = new System.Windows.Forms.DataGridViewTextBoxColumn();
+			this.ProductionLineCode = new Dongke.IBOSS.PRD.Basics.BaseControls.TreeGridColumn();
 			this.ProductionLineName = new System.Windows.Forms.DataGridViewTextBoxColumn();
 			this.ProcedureCode = new System.Windows.Forms.DataGridViewTextBoxColumn();
 			this.ProcedureName = new System.Windows.Forms.DataGridViewTextBoxColumn();
@@ -81,6 +82,11 @@
 			this.CreateUserName = new System.Windows.Forms.DataGridViewTextBoxColumn();
 			this.LEVELNAME = new System.Windows.Forms.DataGridViewTextBoxColumn();
 			this.Finprocedurename = new System.Windows.Forms.DataGridViewTextBoxColumn();
+			this.IdnrkInformation = new Dongke.IBOSS.PRD.Basics.BaseControls.TreeGridColumn();
+			this.ParentID = new System.Windows.Forms.DataGridViewTextBoxColumn();
+			this.radioYes = new Dongke.IBOSS.PRD.Basics.BaseControls.C_RadioButton();
+			this.radioNo = new Dongke.IBOSS.PRD.Basics.BaseControls.C_RadioButton();
+			this.c_Label1 = new Dongke.IBOSS.PRD.Basics.BaseControls.C_Label();
 			this.gbxCondition.SuspendLayout();
 			this.tsrOperate.SuspendLayout();
 			((System.ComponentModel.ISupportInitialize)(this.dgvProductionFollowing)).BeginInit();
@@ -93,6 +99,9 @@
             | System.Windows.Forms.AnchorStyles.Right)));
 			this.gbxCondition.BackColor = System.Drawing.Color.Transparent;
 			this.gbxCondition.BackgroundImage = ((System.Drawing.Image)(resources.GetObject("gbxCondition.BackgroundImage")));
+			this.gbxCondition.Controls.Add(this.c_Label1);
+			this.gbxCondition.Controls.Add(this.radioNo);
+			this.gbxCondition.Controls.Add(this.radioYes);
 			this.gbxCondition.Controls.Add(this.txtBarCode);
 			this.gbxCondition.Controls.Add(this.btnClearCondition);
 			this.gbxCondition.Controls.Add(this.btnSearch);
@@ -259,6 +268,7 @@
 			this.dgvProductionFollowing.EnableHeadersVisualStyles = false;
 			this.dgvProductionFollowing.Font = new System.Drawing.Font("宋体", 9F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(134)));
 			this.dgvProductionFollowing.FormatQuantityColumns = null;
+			this.dgvProductionFollowing.HasNode = false;
 			this.dgvProductionFollowing.HorizontalMergeColumn = null;
 			this.dgvProductionFollowing.IsAutoCountSum = true;
 			this.dgvProductionFollowing.IsAutoResizeColumns = false;
@@ -287,6 +297,7 @@
 			this.dgvProductionFollowing.Tag = true;
 			this.dgvProductionFollowing.TotalSumColumns = null;
 			this.dgvProductionFollowing.ViewRowFilter = "";
+			this.dgvProductionFollowing.VirtualNodes = false;
 			// 
 			// Barcode
 			// 
@@ -483,13 +494,16 @@
             this.CreateUserCode,
             this.CreateUserName,
             this.LEVELNAME,
-            this.Finprocedurename});
+            this.Finprocedurename,
+            this.IdnrkInformation,
+            this.ParentID});
 			this.dgvProductionDetail.ColumnTreeView = null;
 			this.dgvProductionDetail.ContextMenuVisible = ((Dongke.IBOSS.PRD.Basics.BaseControls.C_DataGridView.ContextMenuVisibleFlags)((Dongke.IBOSS.PRD.Basics.BaseControls.C_DataGridView.ContextMenuVisibleFlags.Refine | Dongke.IBOSS.PRD.Basics.BaseControls.C_DataGridView.ContextMenuVisibleFlags.FileOut)));
 			this.dgvProductionDetail.DynamicColumnName = "";
 			this.dgvProductionDetail.EnableHeadersVisualStyles = false;
 			this.dgvProductionDetail.Font = new System.Drawing.Font("宋体", 9F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(134)));
 			this.dgvProductionDetail.FormatQuantityColumns = null;
+			this.dgvProductionDetail.HasNode = false;
 			this.dgvProductionDetail.HorizontalMergeColumn = null;
 			this.dgvProductionDetail.IsAutoCountSum = true;
 			this.dgvProductionDetail.IsAutoResizeColumns = false;
@@ -518,13 +532,16 @@
 			this.dgvProductionDetail.Tag = true;
 			this.dgvProductionDetail.TotalSumColumns = null;
 			this.dgvProductionDetail.ViewRowFilter = "";
+			this.dgvProductionDetail.VirtualNodes = false;
 			// 
 			// ProductionLineCode
 			// 
 			this.ProductionLineCode.DataPropertyName = "ProductionLineCode";
+			this.ProductionLineCode.DefaultNodeImage = null;
 			this.ProductionLineCode.HeaderText = "生产线编码";
 			this.ProductionLineCode.Name = "ProductionLineCode";
 			this.ProductionLineCode.ReadOnly = true;
+			this.ProductionLineCode.Resizable = System.Windows.Forms.DataGridViewTriState.True;
 			this.ProductionLineCode.Visible = false;
 			// 
 			// ProductionLineName
@@ -603,6 +620,61 @@
 			this.Finprocedurename.Name = "Finprocedurename";
 			this.Finprocedurename.ReadOnly = true;
 			// 
+			// IdnrkInformation
+			// 
+			this.IdnrkInformation.DataPropertyName = "IdnrkInformation";
+			this.IdnrkInformation.DefaultNodeImage = null;
+			this.IdnrkInformation.HeaderText = "组件信息";
+			this.IdnrkInformation.Name = "IdnrkInformation";
+			this.IdnrkInformation.ReadOnly = true;
+			this.IdnrkInformation.Resizable = System.Windows.Forms.DataGridViewTriState.True;
+			// 
+			// ParentID
+			// 
+			this.ParentID.DataPropertyName = "ParentID";
+			this.ParentID.HeaderText = "ParentID";
+			this.ParentID.Name = "ParentID";
+			this.ParentID.ReadOnly = true;
+			this.ParentID.Visible = false;
+			// 
+			// radioYes
+			// 
+			this.radioYes.AutoSize = true;
+			this.radioYes.Checked = true;
+			this.radioYes.Font = new System.Drawing.Font("宋体", 9F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(134)));
+			this.radioYes.Location = new System.Drawing.Point(281, 26);
+			this.radioYes.Name = "radioYes";
+			this.radioYes.Size = new System.Drawing.Size(35, 16);
+			this.radioYes.TabIndex = 14;
+			this.radioYes.TabStop = true;
+			this.radioYes.Text = "是";
+			this.radioYes.UseVisualStyleBackColor = true;
+			this.radioYes.CheckedChanged += new System.EventHandler(this.radioYes_CheckedChanged);
+			// 
+			// radioNo
+			// 
+			this.radioNo.AutoSize = true;
+			this.radioNo.Font = new System.Drawing.Font("宋体", 9F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(134)));
+			this.radioNo.Location = new System.Drawing.Point(322, 26);
+			this.radioNo.Name = "radioNo";
+			this.radioNo.Size = new System.Drawing.Size(35, 16);
+			this.radioNo.TabIndex = 15;
+			this.radioNo.Text = "否";
+			this.radioNo.UseVisualStyleBackColor = true;
+			this.radioNo.CheckedChanged += new System.EventHandler(this.radioNo_CheckedChanged);
+			// 
+			// c_Label1
+			// 
+			this.c_Label1.AutoSize = true;
+			this.c_Label1.BackColor = System.Drawing.Color.Transparent;
+			this.c_Label1.Font = new System.Drawing.Font("宋体", 9F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(134)));
+			this.c_Label1.ForeColor = System.Drawing.SystemColors.ControlText;
+			this.c_Label1.Location = new System.Drawing.Point(194, 28);
+			this.c_Label1.Name = "c_Label1";
+			this.c_Label1.Size = new System.Drawing.Size(77, 12);
+			this.c_Label1.TabIndex = 16;
+			this.c_Label1.Text = "显示装配信息";
+			// 
 			// F_RPT_020101_1
 			// 
 			this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 12F);
@@ -659,7 +731,7 @@
         private System.Windows.Forms.DataGridViewCheckBoxColumn SpecialRepairFlag;
         private System.Windows.Forms.DataGridViewCheckBoxColumn ScrapFlag;
         private System.Windows.Forms.DataGridViewCheckBoxColumn IsPublicBody;
-		private System.Windows.Forms.DataGridViewTextBoxColumn ProductionLineCode;
+		private Basics.BaseControls.TreeGridColumn ProductionLineCode;
 		private System.Windows.Forms.DataGridViewTextBoxColumn ProductionLineName;
 		private System.Windows.Forms.DataGridViewTextBoxColumn ProcedureCode;
 		private System.Windows.Forms.DataGridViewTextBoxColumn ProcedureName;
@@ -670,5 +742,10 @@
 		private System.Windows.Forms.DataGridViewTextBoxColumn CreateUserName;
 		private System.Windows.Forms.DataGridViewTextBoxColumn LEVELNAME;
 		private System.Windows.Forms.DataGridViewTextBoxColumn Finprocedurename;
+		private Basics.BaseControls.TreeGridColumn IdnrkInformation;
+		private System.Windows.Forms.DataGridViewTextBoxColumn ParentID;
+		private Basics.BaseControls.C_Label c_Label1;
+		private Basics.BaseControls.C_RadioButton radioNo;
+		private Basics.BaseControls.C_RadioButton radioYes;
 	}
 }

+ 72 - 5
DK.Client/ReportModule/R02/M01/F_RPT_020101_1.cs

@@ -131,9 +131,44 @@ namespace Dongke.IBOSS.PRD.Client.ReportModule
 						if (dsQuery.Tables.Count > 1)
 						{
 							this.dgvProductionFollowing.DataSource = dsQuery.Tables[0];
-							this.dgvProductionDetail.DataSource = dsQuery.Tables[1];
-						}
-						else
+
+							DataTable detailTable = dsQuery.Tables[1];
+                            DataColumn column = new DataColumn("ParentID");
+                            detailTable.Columns.Add(column);
+							for (int i = 0; i < detailTable.Rows.Count; i++)
+							{
+                                detailTable.Rows[i]["ParentID"] = 0;
+
+                            }
+
+                            this.dgvProductionDetail.DataSource = detailTable;
+                             
+
+							if (!this.radioNo.Checked && this.radioYes.Checked && dsQuery.Tables.Count > 2)
+							{
+                                DataTable idnrkInformation = dsQuery.Tables[2];
+                                DataTable newDatable = detailTable.Clone();
+
+                                DataColumn columns = new DataColumn("IdnrkInformation");
+                                newDatable.Columns.Add(columns);
+
+                                for (int i = 0; i < detailTable.Rows.Count; i++)
+								{
+                                    newDatable.ImportRow(detailTable.Rows[i]);
+									for (int j = 0; j < idnrkInformation.Rows.Count; j++)
+									{
+                                        if (detailTable.Rows[i]["ProcedureName"].ToString() == idnrkInformation.Rows[j]["ProcedureName"].ToString())
+                                        {
+                                            newDatable.ImportRow(idnrkInformation.Rows[j]); 
+                                        }
+                                    }
+									
+
+                                }
+                                this.dgvProductionDetail.DataSource = newDatable;
+                            }
+                        }
+                        else
 						{
 							this.dgvProductionFollowing.DataSource = dsQuery.Tables[0];
 						}
@@ -227,6 +262,38 @@ namespace Dongke.IBOSS.PRD.Client.ReportModule
                 this.btnSearch_Click(null, null);
             }
         }
-        #endregion
-    }
+		#endregion
+        /// <summary>
+        /// 是否变化按钮
+        /// </summary>
+        /// <param name="sender"></param>
+        /// <param name="e"></param>
+		private void radioYes_CheckedChanged(object sender, EventArgs e)
+		{
+			if (this.radioYes.Checked)
+			{
+                this.radioNo.Checked = false;
+			}
+			else
+			{
+                this.radioNo.Checked = true;
+            }
+        }
+        /// <summary>
+        /// 是否变化按钮
+        /// </summary>
+        /// <param name="sender"></param>
+        /// <param name="e"></param>
+		private void radioNo_CheckedChanged(object sender, EventArgs e)
+		{
+            if (this.radioNo.Checked)
+            {
+                this.radioYes.Checked = false;
+            }
+            else
+            {
+                this.radioYes.Checked = true;
+            }
+        }
+	}
 }

+ 6 - 0
DK.Client/ReportModule/R02/M01/F_RPT_020101_1.resx

@@ -245,6 +245,12 @@
   <metadata name="Finprocedurename.UserAddedColumn" type="System.Boolean, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
     <value>True</value>
   </metadata>
+  <metadata name="IdnrkInformation.UserAddedColumn" type="System.Boolean, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
+    <value>True</value>
+  </metadata>
+  <metadata name="ParentID.UserAddedColumn" type="System.Boolean, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
+    <value>True</value>
+  </metadata>
   <metadata name="$this.TrayHeight" type="System.Int32, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
     <value>44</value>
   </metadata>

+ 33 - 0
DK.Service/ReportModuleLogic/ReportModuleLogic.cs

@@ -106,6 +106,39 @@ namespace Dongke.IBOSS.PRD.Service.ReportModuleLogic
                     sre.Status = Constant.ServiceResultStatus.NoSearchResults;
                     return sre;
                 }
+                
+
+                string sqlString = @"
+               SELECT T.RELATIONID as ParentID,  
+                       P.PROCEDURENAME,
+                       '【装配组件】' AS ProductionLineName,
+                       T.PROCEDUREID, 
+                       T.CreateTime,
+                       U.USERCODE AS CreateUserCode,
+                       U.USERNAME AS CreateUserName,
+                       '【组件编码:' || T.IDNRK || ', 组件名称:' || T.IDNRKNAME || ', 组件唯一编码:' || T.IDNRKONLYCODE || ', 批次:' || T.CHARG || '】' as IdnrkInformation
+                  FROM TP_PM_BARCODEIDNRKREL T
+                  LEFT JOIN TP_PC_PROCEDURE P
+                    ON T.PROCEDUREID = P.PROCEDUREID
+                    LEFT JOIN tp_mst_user u
+                    ON u.UserID = T.Createuserid
+                 WHERE T.ACCOUNTID = :ACCOUNTID
+                   AND INSTR(T.BARCODE, :BARCODE) > 0";
+                
+                OracleParameter[] parameters = new OracleParameter[]
+                {
+                    new OracleParameter(":ACCOUNTID", OracleDbType.Int32, user.AccountID, ParameterDirection.Input),
+                    new OracleParameter(":BARCODE", OracleDbType.Varchar2, se.Barcode, ParameterDirection.Input),
+                };
+
+                DataTable dt = conn.GetSqlResultToDt(sqlString, parameters);
+				if (dt != null && dt.Rows.Count > 0)
+				{
+                    dt.TableName = "IdnrkTable";
+                    data.Tables.Add(dt.Copy());
+
+                }
+
                 sre.Data = new DataSet();
                 sre.Data = data;
                 return sre;