Files
2026-09-09 18:42:38 +08:00

477 lines
17 KiB
C#
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
// ***********************************************************************
// Assembly : JinYuan.ControlLib
// Created : 08-23-2019
//
// ***********************************************************************
// <copyright file="UCDataGridViewTreeRow.cs">
// Copyright by Huang Zhenghui(黄正辉) All, QQ group:568015492 QQ:623128629 Email:623128629@qq.com
// </copyright>
//
// Blog: https://www.cnblogs.com/bfyx
// GitHub:https://github.com/kwwwvagaa/NetWinformControl
// gitee:https://gitee.com/kwwwvagaa/net_winform_custom_control.git
//
// If you use this code, please keep this note.
// ***********************************************************************
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Drawing;
using System.Data;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using System.Collections;
using JinYuan.ControlLib.UCHelper;
namespace JinYuan.ControlLib
{
/// <summary>
/// Class UCDataGridViewTreeRow.
/// Implements the <see cref="System.Windows.Forms.UserControl" />
/// Implements the <see cref="JinYuan.ControlLib.Controls.IDataGridViewRow" />
/// </summary>
/// <seealso cref="System.Windows.Forms.UserControl" />
/// <seealso cref="JinYuan.ControlLib.Controls.IDataGridViewRow" />
[ToolboxItem(false)]
public partial class UCDataGridViewTreeRow : UserControl, IDataGridViewRow
{
#region 属性
/// <summary>
/// CheckBox选中事件
/// </summary>
public event DataGridViewEventHandler CheckBoxChangeEvent;
/// <summary>
/// 点击单元格事件
/// </summary>
public event DataGridViewEventHandler CellClick;
/// <summary>
/// 数据源改变事件
/// </summary>
public event DataGridViewEventHandler SourceChanged;
/// <summary>
/// Occurs when [row custom event].
/// </summary>
public event DataGridViewRowCustomEventHandler RowCustomEvent;
/// <summary>
/// 列参数,用于创建列数和宽度
/// </summary>
/// <value>The columns.</value>
public List<DataGridViewColumnEntity> Columns
{
get;
set;
}
/// <summary>
/// 数据源
/// </summary>
/// <value>The data source.</value>
public object DataSource
{
get;
set;
}
private int rowLevel = 0;
/// <summary>
/// 折叠的第几层,用于缩进
/// </summary>
public int RowLevel
{
get { return rowLevel; }
set
{
rowLevel = value;
this.Padding = new Padding(this.panLeft.Width / 2 * value, this.Padding.Top, this.panLeft.Right, this.Padding.Bottom);
this.ucSplitLine_V1.Visible = value > 0;
}
}
/// <summary>
/// 行号,树状图目前没有给予行号
/// </summary>
/// <value>The Index of the row.</value>
public int RowIndex { get; set; }
/// <summary>
/// Gets or sets a value indicating whether this instance is show CheckBox.
/// </summary>
/// <value><c>true</c> if this instance is show CheckBox; otherwise, <c>false</c>.</value>
public bool IsShowCheckBox
{
get;
set;
}
/// <summary>
/// The m is checked
/// </summary>
private bool m_isChecked;
/// <summary>
/// 是否选中
/// </summary>
/// <value><c>true</c> if this instance is checked; otherwise, <c>false</c>.</value>
public bool IsChecked
{
get
{
return m_isChecked;
}
set
{
if (m_isChecked != value)
{
m_isChecked = value;
(this.panCells.Controls.Find("check", false)[0] as UCCheckBox).Checked = value;
}
}
}
/// <summary>
/// The m row height
/// </summary>
int m_rowHeight = 40;
/// <summary>
/// 行高
/// </summary>
/// <value>The height of the row.</value>
public int RowHeight
{
get
{
return m_rowHeight;
}
set
{
m_rowHeight = value;
this.Height = value;
}
}
private List<UCDataGridViewTreeRow> childrenRows = new List<UCDataGridViewTreeRow>();
public List<UCDataGridViewTreeRow> ChildrenRows
{
get { return childrenRows; }
set { childrenRows = value; }
}
private bool? isOpened = false;
/// <summary>
/// 是否打开状态
/// </summary>
public bool? IsOpened
{
get { return isOpened; }
set
{
isOpened = value;
if (value.HasValue)
{
panLeft.Enabled = true;
if (value.Value)
{
panLeft.BackgroundImage = Properties.Resources.caret_down;
}
else
{
panLeft.BackgroundImage = Properties.Resources.caret_right;
}
}
else
{
panLeft.BackgroundImage = null;
panLeft.Enabled = false;
}
}
}
#endregion
/// <summary>
/// Initializes a new instance of the <see cref="UCDataGridViewTreeRow" /> class.
/// </summary>
public UCDataGridViewTreeRow()
{
InitializeComponent();
}
/// <summary>
/// 绑定数据到Cell
/// </summary>
public void BindingCellData()
{
for (int i = 0; i < Columns.Count; i++)
{
DataGridViewColumnEntity com = Columns[i];
var cs = this.panCells.Controls.Find("lbl_" + com.DataField, false);
if (cs != null && cs.Length > 0)
{
var pro = DataSource.GetType().GetProperty(com.DataField);
if (pro != null)
{
var value = pro.GetValue(DataSource, null);
if (com.Format != null)
{
cs[0].Text = com.Format(value);
}
else
{
cs[0].Text = value.ToStringExt();
}
}
}
}
foreach (Control item in this.panCells.Controls)
{
if (item is IDataGridViewCustomCell)
{
IDataGridViewCustomCell cell = item as IDataGridViewCustomCell;
cell.RowCustomEvent += cell_RowCustomEvent;
cell.SetBindSource(DataSource);
}
}
IsOpened = false;
var proChildrens = DataSource.GetType().GetProperty("Childrens");
if (proChildrens != null)
{
var value = proChildrens.GetValue(DataSource, null);
if (value != null)
{
}
else
{
IsOpened = null;
}
}
else
{
IsOpened = null;
}
}
void cell_RowCustomEvent(object sender, DataGridViewRowCustomEventArgs e)
{
if (RowCustomEvent != null)
RowCustomEvent(sender, e);
}
/// <summary>
/// Handles the MouseDown event of the Item control.
/// </summary>
/// <param name="sender">The source of the event.</param>
/// <param name="e">The <see cref="MouseEventArgs" /> instance containing the event data.</param>
void Item_MouseDown(object sender, MouseEventArgs e)
{
if (CellClick != null)
{
CellClick(this, new DataGridViewEventArgs()
{
CellControl = this,
CellIndex = (sender as Control).Tag.ToInt()
});
}
}
/// <summary>
/// 设置选中状态,通常为设置颜色即可
/// </summary>
/// <param name="blnSelected">是否选中</param>
public void SetSelect(bool blnSelected)
{
if (blnSelected)
{
this.panMain.BackColor = Color.FromArgb(255, 247, 245);
}
else
{
this.panMain.BackColor = Color.Transparent;
}
}
/// <summary>
/// 添加单元格元素,仅做添加控件操作,不做数据绑定,数据绑定使用BindingCells
/// </summary>
public void ReloadCells()
{
try
{
ControlHelper.FreezeControl(this, true);
this.panCells.Controls.Clear();
this.panCells.ColumnStyles.Clear();
int intColumnsCount = Columns.Count();
if (Columns != null && intColumnsCount > 0)
{
if (IsShowCheckBox)
{
intColumnsCount++;
}
this.panCells.ColumnCount = intColumnsCount;
bool blnFirst = true;
for (int i = 0; i < intColumnsCount; i++)
{
Control c = null;
if (i == 0 && IsShowCheckBox)
{
this.panCells.ColumnStyles.Add(new System.Windows.Forms.ColumnStyle(SizeType.Absolute, 30F));
UCCheckBox box = new UCCheckBox();
box.Name = "check";
box.TextValue = "";
box.Size = new Size(30, 30);
box.Dock = DockStyle.Fill;
box.CheckedChangeEvent += box_CheckedChangeEvent;
c = box;
}
else
{
var item = Columns[i - (IsShowCheckBox ? 1 : 0)];
var w = item.Width - (blnFirst ? (this.panLeft.Width / 2 * rowLevel) : 0);
if (w < 5)
w = 5;
this.panCells.ColumnStyles.Add(new System.Windows.Forms.ColumnStyle(item.WidthType, w));
blnFirst = false;
if (item.CustomCellType == null)
{
Label lbl = new Label();
lbl.Tag = i - (IsShowCheckBox ? 1 : 0);
lbl.Name = "lbl_" + item.DataField;
lbl.Font = new Font("微软雅黑", 12);
lbl.ForeColor = Color.Black;
lbl.AutoSize = false;
lbl.Dock = DockStyle.Fill;
lbl.TextAlign = item.TextAlign;
lbl.MouseDown += (a, b) =>
{
Item_MouseDown(a, b);
};
c = lbl;
}
else
{
Control cc = (Control)Activator.CreateInstance(item.CustomCellType);
cc.Dock = DockStyle.Fill;
c = cc;
}
}
this.panCells.Controls.Add(c, i, 0);
}
}
}
finally
{
ControlHelper.FreezeControl(this, false);
}
}
void box_CheckedChangeEvent(object sender, EventArgs e)
{
IsChecked = ((UCCheckBox)sender).Checked;
}
/// <summary>
/// Handles the MouseDown event of the panLeft control.
/// </summary>
/// <param name="sender">The source of the event.</param>
/// <param name="e">The <see cref="MouseEventArgs" /> instance containing the event data.</param>
private void panLeft_MouseDown(object sender, MouseEventArgs e)
{
try
{
if (!IsOpened.HasValue)
return;
ControlHelper.FreezeControl(this.FindForm(), true);
if (!IsOpened.Value)
{
IsOpened = !IsOpened;
if (childrenRows.Count > 0)
{
childrenRows.ForEach(p =>
{
p.IsChecked = IsChecked;
p.Visible = true;
});
}
else
{
var proChildrens = DataSource.GetType().GetProperty("Childrens");
if (proChildrens != null)
{
var value = proChildrens.GetValue(DataSource, null);
int intSourceCount = 0;
if (value is DataTable)
{
intSourceCount = (value as DataTable).Rows.Count;
}
else if (typeof(IList).IsAssignableFrom(value.GetType()))
{
intSourceCount = (value as IList).Count;
}
for (int i = intSourceCount - 1; i >= 0; i--)
{
UCDataGridViewTreeRow row = new UCDataGridViewTreeRow();
if (value is DataTable)
{
row.DataSource = (value as DataTable).Rows[i];
}
else
{
row.DataSource = (value as IList)[i];
}
row.RowLevel = RowLevel + 1;
row.Columns = Columns;
row.IsShowCheckBox = IsShowCheckBox;
row.ReloadCells();
row.BindingCellData();
Control rowControl = (row as Control);
row.RowHeight = m_rowHeight;
rowControl.Width = this.Width;
//rowControl.Dock = DockStyle.Top;
row.CellClick += (a, b) => { CellClick(rowControl, b); };
row.CheckBoxChangeEvent += (a, b) => { CheckBoxChangeEvent(rowControl, b); };
row.RowCustomEvent += (a, b) => { if (RowCustomEvent != null) { RowCustomEvent(a, b); } };
row.SourceChanged += SourceChanged;
ChildrenRows.Add(row);
row.RowIndex = ChildrenRows.IndexOf(row);
this.Parent.Controls.Add(rowControl);
var index = this.Parent.Controls.GetChildIndex(this);
this.Parent.Controls.SetChildIndex(row, index+1);
}
}
}
}
else
{
HideChildrenRows(this);
this.Height = m_rowHeight;
}
}
finally
{
ControlHelper.FreezeControl(this.FindForm(), false);
}
}
private void HideChildrenRows(UCDataGridViewTreeRow row)
{
if (row.ChildrenRows.Count > 0)
{
foreach (var item in row.ChildrenRows)
{
HideChildrenRows(item);
item.Hide();
}
row.IsOpened = false;
}
}
}
}