官网

http://www.hzhcontrols.com

前提

入行已经7,8年了,一直想做一套漂亮点的自定义控件,于是就有了本系列文章。

GitHub:https://github.com/kwwwvagaa/NetWinformControl

码云:https://gitee.com/kwwwvagaa/net_winform_custom_control.git

如果觉得写的还行,请点个 star 支持一下吧

欢迎前来交流探讨: 企鹅群568015492 

idkey=6e08741ef16fe53bf0314c1c9e336c4f626047943a8b76bac062361bab6b4f8d">

目录

https://www.cnblogs.com/bfyx/p/11364884.html

准备工作

表格控件将拆分为2部分,1:行元素控件,2:列表控件

为了具有更好的扩展性,更加的open,使用接口对行元素进行约束,当行样式或功能不满足你的需求的时候,可以自定义一个行元素,实现接口控件,然后将类型指定给列表控件即可

表格控件用到了分页控件,如果你还没有对分页控件进行了解,请移步查看

(十二)c#Winform自定义控件-分页控件

开始

定义一些辅助东西

  public class DataGridViewCellEntity
{
public string Title { get; set; }
public int Width { get; set; }
public System.Windows.Forms.SizeType WidthType { get; set; } }
     public class DataGridViewEventArgs : EventArgs
{
public Control CellControl { get; set; }
public int CellIndex { get; set; }
public int RowIndex { get; set; } }
     [Serializable]
[ComVisible(true)]
public delegate void DataGridViewEventHandler(object sender, DataGridViewEventArgs e);
   public class DataGridViewColumnEntity
{
public string HeadText { get; set; }
public int Width { get; set; }
public System.Windows.Forms.SizeType WidthType { get; set; }
public string DataField { get; set; }
public Func<object, string> Format { get; set; }
}

定义行接口

  public interface IDataGridViewRow
{
/// <summary>
/// CheckBox选中事件
/// </summary>
event DataGridViewEventHandler CheckBoxChangeEvent;
/// <summary>
/// 点击单元格事件
/// </summary>
event DataGridViewEventHandler CellClick;
/// <summary>
/// 数据源改变事件
/// </summary>
event DataGridViewEventHandler SourceChanged;
/// <summary>
/// 列参数,用于创建列数和宽度
/// </summary>
List<DataGridViewColumnEntity> Columns { get; set; }
bool IsShowCheckBox { get; set; }
/// <summary>
/// 是否选中
/// </summary>
bool IsChecked { get; set; } /// <summary>
/// 数据源
/// </summary>
object DataSource { get; set; }
/// <summary>
/// 添加单元格元素,仅做添加控件操作,不做数据绑定,数据绑定使用BindingCells
/// </summary>
void ReloadCells();
/// <summary>
/// 绑定数据到Cell
/// </summary>
/// <param name="intIndex">cell下标</param>
/// <returns>返回true则表示已处理过,否则将进行默认绑定(通常只针对有Text值的控件)</returns>
void BindingCellData();
/// <summary>
/// 设置选中状态,通常为设置颜色即可
/// </summary>
/// <param name="blnSelected">是否选中</param>
void SetSelect(bool blnSelected);
}

创建行控件

添加一个用户控件,命名UCDataGridViewRow,实现接口IDataGridViewRow

属性

   #region 属性
public event DataGridViewEventHandler CheckBoxChangeEvent; public event DataGridViewEventHandler CellClick; public event DataGridViewEventHandler SourceChanged; public List<DataGridViewColumnEntity> Columns
{
get;
set;
} public object DataSource
{
get;
set;
} public bool IsShowCheckBox
{
get;
set;
}
private bool m_isChecked;
public bool IsChecked
{
get
{
return m_isChecked;
} set
{
if (m_isChecked != value)
{
m_isChecked = value;
(this.panCells.Controls.Find("check", false)[] as UCCheckBox).Checked = value;
}
}
} #endregion

实现接口

    public void BindingCellData()
{
for (int i = ; i < Columns.Count; i++)
{
DataGridViewColumnEntity com = Columns[i];
var cs = this.panCells.Controls.Find("lbl_" + com.DataField, false);
if (cs != null && cs.Length > )
{
var pro = DataSource.GetType().GetProperty(com.DataField);
if (pro != null)
{
var value = pro.GetValue(DataSource, null);
if (com.Format != null)
{
cs[].Text = com.Format(value);
}
else
{
cs[].Text = value.ToStringExt();
}
}
}
}
} public void SetSelect(bool blnSelected)
{
if (blnSelected)
{
this.BackColor = Color.FromArgb(, , );
}
else
{
this.BackColor = Color.Transparent;
}
} public void ReloadCells()
{
try
{
ControlHelper.FreezeControl(this, true);
this.panCells.Controls.Clear();
this.panCells.ColumnStyles.Clear(); int intColumnsCount = Columns.Count();
if (Columns != null && intColumnsCount > )
{
if (IsShowCheckBox)
{
intColumnsCount++;
}
this.panCells.ColumnCount = intColumnsCount;
for (int i = ; i < intColumnsCount; i++)
{
Control c = null;
if (i == && 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(, );
box.Dock = DockStyle.Fill;
box.CheckedChangeEvent += (a, b) =>
{
IsChecked = box.Checked;
if (CheckBoxChangeEvent != null)
{
CheckBoxChangeEvent(a, new DataGridViewEventArgs()
{
CellControl = box,
CellIndex =
});
}
};
c = box;
}
else
{
var item = Columns[i - (IsShowCheckBox ? : )];
this.panCells.ColumnStyles.Add(new System.Windows.Forms.ColumnStyle(item.WidthType, item.Width)); Label lbl = new Label();
lbl.Tag = i - (IsShowCheckBox ? : );
lbl.Name = "lbl_" + item.DataField;
lbl.Font = new Font("微软雅黑", );
lbl.ForeColor = Color.Black;
lbl.AutoSize = false;
lbl.Dock = DockStyle.Fill;
lbl.TextAlign = ContentAlignment.MiddleCenter;
lbl.MouseDown += (a, b) =>
{
Item_MouseDown(a, b);
};
c = lbl;
}
this.panCells.Controls.Add(c, i, );
} }
}
finally
{
ControlHelper.FreezeControl(this, false);
}
}

节点选中事件

    void Item_MouseDown(object sender, MouseEventArgs e)
{
if (CellClick != null)
{
CellClick(sender, new DataGridViewEventArgs()
{
CellControl = this,
CellIndex = (sender as Control).Tag.ToInt()
});
}
}

完整的代码

 // 版权所有  黄正辉  交流群:568015492   QQ:623128629
// 文件名称:UCDataGridViewRow.cs
// 创建日期:2019-08-15 15:59:31
// 功能描述:DataGridView
// 项目地址:https://gitee.com/kwwwvagaa/net_winform_custom_control
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; namespace HZH_Controls.Controls
{
[ToolboxItem(false)]
public partial class UCDataGridViewRow : UserControl, IDataGridViewRow
{ #region 属性
public event DataGridViewEventHandler CheckBoxChangeEvent; public event DataGridViewEventHandler CellClick; public event DataGridViewEventHandler SourceChanged; public List<DataGridViewColumnEntity> Columns
{
get;
set;
} public object DataSource
{
get;
set;
} public bool IsShowCheckBox
{
get;
set;
}
private bool m_isChecked;
public bool IsChecked
{
get
{
return m_isChecked;
} set
{
if (m_isChecked != value)
{
m_isChecked = value;
(this.panCells.Controls.Find("check", false)[] as UCCheckBox).Checked = value;
}
}
} #endregion public UCDataGridViewRow()
{
InitializeComponent();
} public void BindingCellData()
{
for (int i = ; i < Columns.Count; i++)
{
DataGridViewColumnEntity com = Columns[i];
var cs = this.panCells.Controls.Find("lbl_" + com.DataField, false);
if (cs != null && cs.Length > )
{
var pro = DataSource.GetType().GetProperty(com.DataField);
if (pro != null)
{
var value = pro.GetValue(DataSource, null);
if (com.Format != null)
{
cs[].Text = com.Format(value);
}
else
{
cs[].Text = value.ToStringExt();
}
}
}
}
} void Item_MouseDown(object sender, MouseEventArgs e)
{
if (CellClick != null)
{
CellClick(sender, new DataGridViewEventArgs()
{
CellControl = this,
CellIndex = (sender as Control).Tag.ToInt()
});
}
} public void SetSelect(bool blnSelected)
{
if (blnSelected)
{
this.BackColor = Color.FromArgb(, , );
}
else
{
this.BackColor = Color.Transparent;
}
} public void ReloadCells()
{
try
{
ControlHelper.FreezeControl(this, true);
this.panCells.Controls.Clear();
this.panCells.ColumnStyles.Clear(); int intColumnsCount = Columns.Count();
if (Columns != null && intColumnsCount > )
{
if (IsShowCheckBox)
{
intColumnsCount++;
}
this.panCells.ColumnCount = intColumnsCount;
for (int i = ; i < intColumnsCount; i++)
{
Control c = null;
if (i == && 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(, );
box.Dock = DockStyle.Fill;
box.CheckedChangeEvent += (a, b) =>
{
IsChecked = box.Checked;
if (CheckBoxChangeEvent != null)
{
CheckBoxChangeEvent(a, new DataGridViewEventArgs()
{
CellControl = box,
CellIndex =
});
}
};
c = box;
}
else
{
var item = Columns[i - (IsShowCheckBox ? : )];
this.panCells.ColumnStyles.Add(new System.Windows.Forms.ColumnStyle(item.WidthType, item.Width)); Label lbl = new Label();
lbl.Tag = i - (IsShowCheckBox ? : );
lbl.Name = "lbl_" + item.DataField;
lbl.Font = new Font("微软雅黑", );
lbl.ForeColor = Color.Black;
lbl.AutoSize = false;
lbl.Dock = DockStyle.Fill;
lbl.TextAlign = ContentAlignment.MiddleCenter;
lbl.MouseDown += (a, b) =>
{
Item_MouseDown(a, b);
};
c = lbl;
}
this.panCells.Controls.Add(c, i, );
} }
}
finally
{
ControlHelper.FreezeControl(this, false);
}
} }
}
 namespace HZH_Controls.Controls
{
partial class UCDataGridViewRow
{
/// <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()
{
this.ucSplitLine_H1 = new HZH_Controls.Controls.UCSplitLine_H();
this.panCells = new System.Windows.Forms.TableLayoutPanel();
this.SuspendLayout();
//
// ucSplitLine_H1
//
this.ucSplitLine_H1.BackColor = System.Drawing.Color.FromArgb(((int)(((byte)()))), ((int)(((byte)()))), ((int)(((byte)()))));
this.ucSplitLine_H1.Dock = System.Windows.Forms.DockStyle.Bottom;
this.ucSplitLine_H1.Location = new System.Drawing.Point(, );
this.ucSplitLine_H1.Name = "ucSplitLine_H1";
this.ucSplitLine_H1.Size = new System.Drawing.Size(, );
this.ucSplitLine_H1.TabIndex = ;
this.ucSplitLine_H1.TabStop = false;
//
// panCells
//
this.panCells.ColumnCount = ;
this.panCells.ColumnStyles.Add(new System.Windows.Forms.ColumnStyle(System.Windows.Forms.SizeType.Percent, 100F));
this.panCells.ColumnStyles.Add(new System.Windows.Forms.ColumnStyle(System.Windows.Forms.SizeType.Absolute, 20F));
this.panCells.Dock = System.Windows.Forms.DockStyle.Fill;
this.panCells.Location = new System.Drawing.Point(, );
this.panCells.Name = "panCells";
this.panCells.RowCount = ;
this.panCells.RowStyles.Add(new System.Windows.Forms.RowStyle(System.Windows.Forms.SizeType.Percent, 100F));
this.panCells.RowStyles.Add(new System.Windows.Forms.RowStyle(System.Windows.Forms.SizeType.Absolute, 20F));
this.panCells.Size = new System.Drawing.Size(, );
this.panCells.TabIndex = ;
//
// UCDataGridViewItem
//
this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.None;
this.BackColor = System.Drawing.Color.White;
this.Controls.Add(this.panCells);
this.Controls.Add(this.ucSplitLine_H1);
this.Name = "UCDataGridViewItem";
this.Size = new System.Drawing.Size(, );
this.ResumeLayout(false); } #endregion private UCSplitLine_H ucSplitLine_H1;
private System.Windows.Forms.TableLayoutPanel panCells;
}
}

接下来就是列表控件了

添加一个用户控件,命名UCDataGridView

属性

  #region 属性
private Font m_headFont = new Font("微软雅黑", 12F);
/// <summary>
/// 标题字体
/// </summary>
[Description("标题字体"), Category("自定义")]
public Font HeadFont
{
get { return m_headFont; }
set { m_headFont = value; }
}
private Color m_headTextColor = Color.Black;
/// <summary>
/// 标题字体颜色
/// </summary>
[Description("标题文字颜色"), Category("自定义")]
public Color HeadTextColor
{
get { return m_headTextColor; }
set { m_headTextColor = value; }
} private bool m_isShowHead = true;
/// <summary>
/// 是否显示标题
/// </summary>
[Description("是否显示标题"), Category("自定义")]
public bool IsShowHead
{
get { return m_isShowHead; }
set
{
m_isShowHead = value;
panHead.Visible = value;
if (m_page != null)
{
ResetShowCount();
m_page.PageSize = m_showCount;
}
}
}
private int m_headHeight = ;
/// <summary>
/// 标题高度
/// </summary>
[Description("标题高度"), Category("自定义")]
public int HeadHeight
{
get { return m_headHeight; }
set
{
m_headHeight = value;
panHead.Height = value;
}
} private bool m_isShowCheckBox = false;
/// <summary>
/// 是否显示复选框
/// </summary>
[Description("是否显示选择框"), Category("自定义")]
public bool IsShowCheckBox
{
get { return m_isShowCheckBox; }
set
{
if (value != m_isShowCheckBox)
{
m_isShowCheckBox = value;
LoadColumns();
}
}
} private int m_rowHeight = ;
/// <summary>
/// 行高
/// </summary>
[Description("数据行高"), Category("自定义")]
public int RowHeight
{
get { return m_rowHeight; }
set { m_rowHeight = value; }
} private int m_showCount = ;
/// <summary>
///
/// </summary>
[Description("可显示个数"), Category("自定义")]
public int ShowCount
{
get { return m_showCount; }
private set
{
m_showCount = value;
if (m_page != null)
{
m_page.PageSize = value;
}
}
} private List<DataGridViewColumnEntity> m_columns;
/// <summary>
/// 列
/// </summary>
[Description("列"), Category("自定义")]
public List<DataGridViewColumnEntity> Columns
{
get { return m_columns; }
set
{
m_columns = value;
LoadColumns();
}
} private object m_dataSource;
/// <summary>
/// 数据源,支持列表或table,如果使用翻页控件,请使用翻页控件的DataSource
/// </summary>
[Description("数据源,支持列表或table,如果使用翻页控件,请使用翻页控件的DataSource"), Category("自定义")]
public object DataSource
{
get { return m_dataSource; }
set
{
if (value == null)
return;
if (!(m_dataSource is DataTable) && (!typeof(IList).IsAssignableFrom(value.GetType())))
{
throw new Exception("数据源不是有效的数据类型,请使用Datatable或列表");
} m_dataSource = value;
ReloadSource();
}
} public List<IDataGridViewRow> Rows { get; private set; } private Type m_rowType = typeof(UCDataGridViewRow);
/// <summary>
/// 行元素类型,默认UCDataGridViewItem
/// </summary>
[Description("行控件类型,默认UCDataGridViewRow,如果不满足请自定义行控件实现接口IDataGridViewRow"), Category("自定义")]
public Type RowType
{
get { return m_rowType; }
set
{
if (value == null)
return;
if (!typeof(IDataGridViewRow).IsAssignableFrom(value) || !value.IsSubclassOf(typeof(Control)))
throw new Exception("行控件没有实现IDataGridViewRow接口");
m_rowType = value;
}
}
IDataGridViewRow m_selectRow = null;
/// <summary>
/// 选中的节点
/// </summary>
[Description("选中行"), Category("自定义")]
public IDataGridViewRow SelectRow
{
get { return m_selectRow; }
private set { m_selectRow = value; }
} /// <summary>
/// 选中的行,如果显示CheckBox,则以CheckBox选中为准
/// </summary>
[Description("选中的行,如果显示CheckBox,则以CheckBox选中为准"), Category("自定义")]
public List<IDataGridViewRow> SelectRows
{
get
{
if (m_isShowCheckBox)
{
return Rows.FindAll(p => p.IsChecked);
}
else
return new List<IDataGridViewRow>() { m_selectRow };
}
} private UCPagerControlBase m_page = null;
/// <summary>
/// 翻页控件
/// </summary>
[Description("翻页控件,如果UCPagerControl不满足你的需求,请自定义翻页控件并继承UCPagerControlBase"), Category("自定义")]
public UCPagerControlBase Page
{
get { return m_page; }
set
{
m_page = value;
if (value != null)
{
if (!typeof(IPageControl).IsAssignableFrom(value.GetType()) || !value.GetType().IsSubclassOf(typeof(UCPagerControlBase)))
throw new Exception("翻页控件没有继承UCPagerControlBase");
panPage.Visible = value != null;
m_page.ShowSourceChanged += page_ShowSourceChanged;
m_page.Dock = DockStyle.Fill;
this.panPage.Controls.Clear();
this.panPage.Controls.Add(m_page);
ResetShowCount();
m_page.PageSize = ShowCount;
this.DataSource = m_page.GetCurrentSource();
}
else
{
m_page = null;
}
}
} void page_ShowSourceChanged(object currentSource)
{
this.DataSource = currentSource;
} #region 事件
[Description("选中标题选择框事件"), Category("自定义")]
public EventHandler HeadCheckBoxChangeEvent;
[Description("标题点击事件"), Category("自定义")]
public EventHandler HeadColumnClickEvent;
[Description("项点击事件"), Category("自定义")]
public event DataGridViewEventHandler ItemClick;
[Description("数据源改变事件"), Category("自定义")]
public event DataGridViewEventHandler SourceChanged;
#endregion
#endregion

一些私有的方法

   #region 私有方法
#region 加载column
/// <summary>
/// 功能描述:加载column
/// 作  者:HZH
/// 创建日期:2019-08-08 17:51:50
/// 任务编号:POS
/// </summary>
private void LoadColumns()
{
try
{
if (DesignMode)
{ return; } ControlHelper.FreezeControl(this.panHead, true);
this.panColumns.Controls.Clear();
this.panColumns.ColumnStyles.Clear(); if (m_columns != null && m_columns.Count() > )
{
int intColumnsCount = m_columns.Count();
if (m_isShowCheckBox)
{
intColumnsCount++;
}
this.panColumns.ColumnCount = intColumnsCount;
for (int i = ; i < intColumnsCount; i++)
{
Control c = null;
if (i == && m_isShowCheckBox)
{
this.panColumns.ColumnStyles.Add(new System.Windows.Forms.ColumnStyle(SizeType.Absolute, 30F)); UCCheckBox box = new UCCheckBox();
box.TextValue = "";
box.Size = new Size(, );
box.CheckedChangeEvent += (a, b) =>
{
Rows.ForEach(p => p.IsChecked = box.Checked);
if (HeadCheckBoxChangeEvent != null)
{
HeadCheckBoxChangeEvent(a, b);
}
};
c = box;
}
else
{
var item = m_columns[i - (m_isShowCheckBox ? : )];
this.panColumns.ColumnStyles.Add(new System.Windows.Forms.ColumnStyle(item.WidthType, item.Width));
Label lbl = new Label();
lbl.Name = "dgvColumns_" + i;
lbl.Text = item.HeadText;
lbl.Font = m_headFont;
lbl.ForeColor = m_headTextColor;
lbl.TextAlign = ContentAlignment.MiddleCenter;
lbl.AutoSize = false;
lbl.Dock = DockStyle.Fill;
lbl.MouseDown += (a, b) =>
{
if (HeadColumnClickEvent != null)
{
HeadColumnClickEvent(a, b);
}
};
c = lbl;
}
this.panColumns.Controls.Add(c, i, );
} }
}
finally
{
ControlHelper.FreezeControl(this.panHead, false);
}
}
#endregion /// <summary>
/// 功能描述:获取显示个数
/// 作  者:HZH
/// 创建日期:2019-03-05 10:02:58
/// 任务编号:POS
/// </summary>
/// <returns>返回值</returns>
private void ResetShowCount()
{
if (DesignMode)
{ return; }
ShowCount = this.panRow.Height / (m_rowHeight);
int intCha = this.panRow.Height % (m_rowHeight);
m_rowHeight += intCha / ShowCount;
}
#endregion

几个事件

  #region 事件
void RowSourceChanged(object sender, DataGridViewEventArgs e)
{
if (SourceChanged != null)
SourceChanged(sender, e);
}
private void SetSelectRow(Control item, DataGridViewEventArgs e)
{
try
{
ControlHelper.FreezeControl(this, true);
if (item == null)
return;
if (item.Visible == false)
return;
this.FindForm().ActiveControl = this;
this.FindForm().ActiveControl = item;
if (m_selectRow != null)
{
if (m_selectRow == item)
return;
m_selectRow.SetSelect(false);
}
m_selectRow = item as IDataGridViewRow;
m_selectRow.SetSelect(true);
if (ItemClick != null)
{
ItemClick(item, e);
}
if (this.panRow.Controls.Count > )
{
if (item.Location.Y < )
{
this.panRow.AutoScrollPosition = new Point(, Math.Abs(this.panRow.Controls[this.panRow.Controls.Count - ].Location.Y) + item.Location.Y);
}
else if (item.Location.Y + m_rowHeight > this.panRow.Height)
{
this.panRow.AutoScrollPosition = new Point(, Math.Abs(this.panRow.AutoScrollPosition.Y) + item.Location.Y - this.panRow.Height + m_rowHeight);
}
}
}
finally
{
ControlHelper.FreezeControl(this, false);
}
}
private void UCDataGridView_Resize(object sender, EventArgs e)
{
ResetShowCount();
ReloadSource();
}
#endregion

对外公开的函数

  #region 公共函数
/// <summary>
/// 刷新数据
/// </summary>
public void ReloadSource()
{
if (DesignMode)
{ return; }
try
{
if (m_columns == null || m_columns.Count <= )
return; ControlHelper.FreezeControl(this.panRow, true);
this.panRow.Controls.Clear();
Rows = new List<IDataGridViewRow>();
if (m_dataSource != null)
{
int intIndex = ;
Control lastItem = null; int intSourceCount = ;
if (m_dataSource is DataTable)
{
intSourceCount = (m_dataSource as DataTable).Rows.Count;
}
else if (typeof(IList).IsAssignableFrom(m_dataSource.GetType()))
{
intSourceCount = (m_dataSource as IList).Count;
} foreach (Control item in this.panRow.Controls)
{ if (intIndex >= intSourceCount)
{
item.Visible = false;
}
else
{
var row = (item as IDataGridViewRow);
row.IsShowCheckBox = m_isShowCheckBox;
if (m_dataSource is DataTable)
{
row.DataSource = (m_dataSource as DataTable).Rows[intIndex];
}
else
{
row.DataSource = (m_dataSource as IList)[intIndex];
}
row.BindingCellData();
item.Height = m_rowHeight;
item.Visible = true;
item.BringToFront();
if (lastItem == null)
lastItem = item;
Rows.Add(row);
}
intIndex++;
} if (intIndex < intSourceCount)
{
for (int i = intIndex; i < intSourceCount; i++)
{
IDataGridViewRow row = (IDataGridViewRow)Activator.CreateInstance(m_rowType);
if (m_dataSource is DataTable)
{
row.DataSource = (m_dataSource as DataTable).Rows[i];
}
else
{
row.DataSource = (m_dataSource as IList)[i];
}
row.Columns = m_columns;
List<Control> lstCells = new List<Control>();
row.IsShowCheckBox = m_isShowCheckBox;
row.ReloadCells();
row.BindingCellData(); Control rowControl = (row as Control);
rowControl.Height = m_rowHeight;
this.panRow.Controls.Add(rowControl);
rowControl.Dock = DockStyle.Top;
row.CellClick += (a, b) => { SetSelectRow(rowControl, b); };
row.CheckBoxChangeEvent += (a, b) => { SetSelectRow(rowControl, b); };
row.SourceChanged += RowSourceChanged;
rowControl.BringToFront();
Rows.Add(row); if (lastItem == null)
lastItem = rowControl;
}
}
if (lastItem != null && intSourceCount == m_showCount)
{
lastItem.Height = this.panRow.Height - (m_showCount - ) * m_rowHeight;
}
}
}
finally
{
ControlHelper.FreezeControl(this.panRow, false);
}
} /// <summary>
/// 快捷键
/// </summary>
/// <param name="msg"></param>
/// <param name="keyData"></param>
/// <returns></returns>
protected override bool ProcessCmdKey(ref Message msg, Keys keyData)
{
if (keyData == Keys.Up)
{
Previous();
}
else if (keyData == Keys.Down)
{
Next();
}
else if (keyData == Keys.Home)
{
First();
}
else if (keyData == Keys.End)
{
End();
}
return base.ProcessCmdKey(ref msg, keyData);
}
/// <summary>
/// 选中第一个
/// </summary>
public void First()
{
if (Rows == null || Rows.Count <= )
return;
Control c = null;
c = (Rows[] as Control);
SetSelectRow(c, new DataGridViewEventArgs() { RowIndex = });
}
/// <summary>
/// 选中上一个
/// </summary>
public void Previous()
{
if (Rows == null || Rows.Count <= )
return;
Control c = null; int index = Rows.IndexOf(m_selectRow);
if (index - >= )
{
c = (Rows[index - ] as Control);
SetSelectRow(c, new DataGridViewEventArgs() { RowIndex = index - });
}
}
/// <summary>
/// 选中下一个
/// </summary>
public void Next()
{
if (Rows == null || Rows.Count <= )
return;
Control c = null; int index = Rows.IndexOf(m_selectRow);
if (index + < Rows.Count)
{
c = (Rows[index + ] as Control);
SetSelectRow(c, new DataGridViewEventArgs() { RowIndex = index + });
}
}
/// <summary>
/// 选中最后一个
/// </summary>
public void End()
{
if (Rows == null || Rows.Count <= )
return;
Control c = null;
c = (Rows[Rows.Count - ] as Control);
SetSelectRow(c, new DataGridViewEventArgs() { RowIndex = Rows.Count - });
} #endregion

完整代码

 // 版权所有  黄正辉  交流群:568015492   QQ:623128629
// 文件名称:UCDataGridView.cs
// 创建日期:2019-08-15 15:59:25
// 功能描述:DataGridView
// 项目地址:https://gitee.com/kwwwvagaa/net_winform_custom_control
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; namespace HZH_Controls.Controls
{
public partial class UCDataGridView : UserControl
{
#region 属性
private Font m_headFont = new Font("微软雅黑", 12F);
/// <summary>
/// 标题字体
/// </summary>
[Description("标题字体"), Category("自定义")]
public Font HeadFont
{
get { return m_headFont; }
set { m_headFont = value; }
}
private Color m_headTextColor = Color.Black;
/// <summary>
/// 标题字体颜色
/// </summary>
[Description("标题文字颜色"), Category("自定义")]
public Color HeadTextColor
{
get { return m_headTextColor; }
set { m_headTextColor = value; }
} private bool m_isShowHead = true;
/// <summary>
/// 是否显示标题
/// </summary>
[Description("是否显示标题"), Category("自定义")]
public bool IsShowHead
{
get { return m_isShowHead; }
set
{
m_isShowHead = value;
panHead.Visible = value;
if (m_page != null)
{
ResetShowCount();
m_page.PageSize = m_showCount;
}
}
}
private int m_headHeight = ;
/// <summary>
/// 标题高度
/// </summary>
[Description("标题高度"), Category("自定义")]
public int HeadHeight
{
get { return m_headHeight; }
set
{
m_headHeight = value;
panHead.Height = value;
}
} private bool m_isShowCheckBox = false;
/// <summary>
/// 是否显示复选框
/// </summary>
[Description("是否显示选择框"), Category("自定义")]
public bool IsShowCheckBox
{
get { return m_isShowCheckBox; }
set
{
if (value != m_isShowCheckBox)
{
m_isShowCheckBox = value;
LoadColumns();
}
}
} private int m_rowHeight = ;
/// <summary>
/// 行高
/// </summary>
[Description("数据行高"), Category("自定义")]
public int RowHeight
{
get { return m_rowHeight; }
set { m_rowHeight = value; }
} private int m_showCount = ;
/// <summary>
///
/// </summary>
[Description("可显示个数"), Category("自定义")]
public int ShowCount
{
get { return m_showCount; }
private set
{
m_showCount = value;
if (m_page != null)
{
m_page.PageSize = value;
}
}
} private List<DataGridViewColumnEntity> m_columns;
/// <summary>
/// 列
/// </summary>
[Description("列"), Category("自定义")]
public List<DataGridViewColumnEntity> Columns
{
get { return m_columns; }
set
{
m_columns = value;
LoadColumns();
}
} private object m_dataSource;
/// <summary>
/// 数据源,支持列表或table,如果使用翻页控件,请使用翻页控件的DataSource
/// </summary>
[Description("数据源,支持列表或table,如果使用翻页控件,请使用翻页控件的DataSource"), Category("自定义")]
public object DataSource
{
get { return m_dataSource; }
set
{
if (value == null)
return;
if (!(m_dataSource is DataTable) && (!typeof(IList).IsAssignableFrom(value.GetType())))
{
throw new Exception("数据源不是有效的数据类型,请使用Datatable或列表");
} m_dataSource = value;
ReloadSource();
}
} public List<IDataGridViewRow> Rows { get; private set; } private Type m_rowType = typeof(UCDataGridViewRow);
/// <summary>
/// 行元素类型,默认UCDataGridViewItem
/// </summary>
[Description("行控件类型,默认UCDataGridViewRow,如果不满足请自定义行控件实现接口IDataGridViewRow"), Category("自定义")]
public Type RowType
{
get { return m_rowType; }
set
{
if (value == null)
return;
if (!typeof(IDataGridViewRow).IsAssignableFrom(value) || !value.IsSubclassOf(typeof(Control)))
throw new Exception("行控件没有实现IDataGridViewRow接口");
m_rowType = value;
}
}
IDataGridViewRow m_selectRow = null;
/// <summary>
/// 选中的节点
/// </summary>
[Description("选中行"), Category("自定义")]
public IDataGridViewRow SelectRow
{
get { return m_selectRow; }
private set { m_selectRow = value; }
} /// <summary>
/// 选中的行,如果显示CheckBox,则以CheckBox选中为准
/// </summary>
[Description("选中的行,如果显示CheckBox,则以CheckBox选中为准"), Category("自定义")]
public List<IDataGridViewRow> SelectRows
{
get
{
if (m_isShowCheckBox)
{
return Rows.FindAll(p => p.IsChecked);
}
else
return new List<IDataGridViewRow>() { m_selectRow };
}
} private UCPagerControlBase m_page = null;
/// <summary>
/// 翻页控件
/// </summary>
[Description("翻页控件,如果UCPagerControl不满足你的需求,请自定义翻页控件并继承UCPagerControlBase"), Category("自定义")]
public UCPagerControlBase Page
{
get { return m_page; }
set
{
m_page = value;
if (value != null)
{
if (!typeof(IPageControl).IsAssignableFrom(value.GetType()) || !value.GetType().IsSubclassOf(typeof(UCPagerControlBase)))
throw new Exception("翻页控件没有继承UCPagerControlBase");
panPage.Visible = value != null;
m_page.ShowSourceChanged += page_ShowSourceChanged;
m_page.Dock = DockStyle.Fill;
this.panPage.Controls.Clear();
this.panPage.Controls.Add(m_page);
ResetShowCount();
m_page.PageSize = ShowCount;
this.DataSource = m_page.GetCurrentSource();
}
else
{
m_page = null;
}
}
} void page_ShowSourceChanged(object currentSource)
{
this.DataSource = currentSource;
} #region 事件
[Description("选中标题选择框事件"), Category("自定义")]
public EventHandler HeadCheckBoxChangeEvent;
[Description("标题点击事件"), Category("自定义")]
public EventHandler HeadColumnClickEvent;
[Description("项点击事件"), Category("自定义")]
public event DataGridViewEventHandler ItemClick;
[Description("数据源改变事件"), Category("自定义")]
public event DataGridViewEventHandler SourceChanged;
#endregion
#endregion public UCDataGridView()
{
InitializeComponent();
} #region 私有方法
#region 加载column
/// <summary>
/// 功能描述:加载column
/// 作  者:HZH
/// 创建日期:2019-08-08 17:51:50
/// 任务编号:POS
/// </summary>
private void LoadColumns()
{
try
{
if (DesignMode)
{ return; } ControlHelper.FreezeControl(this.panHead, true);
this.panColumns.Controls.Clear();
this.panColumns.ColumnStyles.Clear(); if (m_columns != null && m_columns.Count() > )
{
int intColumnsCount = m_columns.Count();
if (m_isShowCheckBox)
{
intColumnsCount++;
}
this.panColumns.ColumnCount = intColumnsCount;
for (int i = ; i < intColumnsCount; i++)
{
Control c = null;
if (i == && m_isShowCheckBox)
{
this.panColumns.ColumnStyles.Add(new System.Windows.Forms.ColumnStyle(SizeType.Absolute, 30F)); UCCheckBox box = new UCCheckBox();
box.TextValue = "";
box.Size = new Size(, );
box.CheckedChangeEvent += (a, b) =>
{
Rows.ForEach(p => p.IsChecked = box.Checked);
if (HeadCheckBoxChangeEvent != null)
{
HeadCheckBoxChangeEvent(a, b);
}
};
c = box;
}
else
{
var item = m_columns[i - (m_isShowCheckBox ? : )];
this.panColumns.ColumnStyles.Add(new System.Windows.Forms.ColumnStyle(item.WidthType, item.Width));
Label lbl = new Label();
lbl.Name = "dgvColumns_" + i;
lbl.Text = item.HeadText;
lbl.Font = m_headFont;
lbl.ForeColor = m_headTextColor;
lbl.TextAlign = ContentAlignment.MiddleCenter;
lbl.AutoSize = false;
lbl.Dock = DockStyle.Fill;
lbl.MouseDown += (a, b) =>
{
if (HeadColumnClickEvent != null)
{
HeadColumnClickEvent(a, b);
}
};
c = lbl;
}
this.panColumns.Controls.Add(c, i, );
} }
}
finally
{
ControlHelper.FreezeControl(this.panHead, false);
}
}
#endregion /// <summary>
/// 功能描述:获取显示个数
/// 作  者:HZH
/// 创建日期:2019-03-05 10:02:58
/// 任务编号:POS
/// </summary>
/// <returns>返回值</returns>
private void ResetShowCount()
{
if (DesignMode)
{ return; }
ShowCount = this.panRow.Height / (m_rowHeight);
int intCha = this.panRow.Height % (m_rowHeight);
m_rowHeight += intCha / ShowCount;
}
#endregion #region 公共函数
/// <summary>
/// 刷新数据
/// </summary>
public void ReloadSource()
{
if (DesignMode)
{ return; }
try
{
if (m_columns == null || m_columns.Count <= )
return; ControlHelper.FreezeControl(this.panRow, true);
this.panRow.Controls.Clear();
Rows = new List<IDataGridViewRow>();
if (m_dataSource != null)
{
int intIndex = ;
Control lastItem = null; int intSourceCount = ;
if (m_dataSource is DataTable)
{
intSourceCount = (m_dataSource as DataTable).Rows.Count;
}
else if (typeof(IList).IsAssignableFrom(m_dataSource.GetType()))
{
intSourceCount = (m_dataSource as IList).Count;
} foreach (Control item in this.panRow.Controls)
{ if (intIndex >= intSourceCount)
{
item.Visible = false;
}
else
{
var row = (item as IDataGridViewRow);
row.IsShowCheckBox = m_isShowCheckBox;
if (m_dataSource is DataTable)
{
row.DataSource = (m_dataSource as DataTable).Rows[intIndex];
}
else
{
row.DataSource = (m_dataSource as IList)[intIndex];
}
row.BindingCellData();
item.Height = m_rowHeight;
item.Visible = true;
item.BringToFront();
if (lastItem == null)
lastItem = item;
Rows.Add(row);
}
intIndex++;
} if (intIndex < intSourceCount)
{
for (int i = intIndex; i < intSourceCount; i++)
{
IDataGridViewRow row = (IDataGridViewRow)Activator.CreateInstance(m_rowType);
if (m_dataSource is DataTable)
{
row.DataSource = (m_dataSource as DataTable).Rows[i];
}
else
{
row.DataSource = (m_dataSource as IList)[i];
}
row.Columns = m_columns;
List<Control> lstCells = new List<Control>();
row.IsShowCheckBox = m_isShowCheckBox;
row.ReloadCells();
row.BindingCellData(); Control rowControl = (row as Control);
rowControl.Height = m_rowHeight;
this.panRow.Controls.Add(rowControl);
rowControl.Dock = DockStyle.Top;
row.CellClick += (a, b) => { SetSelectRow(rowControl, b); };
row.CheckBoxChangeEvent += (a, b) => { SetSelectRow(rowControl, b); };
row.SourceChanged += RowSourceChanged;
rowControl.BringToFront();
Rows.Add(row); if (lastItem == null)
lastItem = rowControl;
}
}
if (lastItem != null && intSourceCount == m_showCount)
{
lastItem.Height = this.panRow.Height - (m_showCount - ) * m_rowHeight;
}
}
}
finally
{
ControlHelper.FreezeControl(this.panRow, false);
}
} /// <summary>
/// 快捷键
/// </summary>
/// <param name="msg"></param>
/// <param name="keyData"></param>
/// <returns></returns>
protected override bool ProcessCmdKey(ref Message msg, Keys keyData)
{
if (keyData == Keys.Up)
{
Previous();
}
else if (keyData == Keys.Down)
{
Next();
}
else if (keyData == Keys.Home)
{
First();
}
else if (keyData == Keys.End)
{
End();
}
return base.ProcessCmdKey(ref msg, keyData);
}
/// <summary>
/// 选中第一个
/// </summary>
public void First()
{
if (Rows == null || Rows.Count <= )
return;
Control c = null;
c = (Rows[] as Control);
SetSelectRow(c, new DataGridViewEventArgs() { RowIndex = });
}
/// <summary>
/// 选中上一个
/// </summary>
public void Previous()
{
if (Rows == null || Rows.Count <= )
return;
Control c = null; int index = Rows.IndexOf(m_selectRow);
if (index - >= )
{
c = (Rows[index - ] as Control);
SetSelectRow(c, new DataGridViewEventArgs() { RowIndex = index - });
}
}
/// <summary>
/// 选中下一个
/// </summary>
public void Next()
{
if (Rows == null || Rows.Count <= )
return;
Control c = null; int index = Rows.IndexOf(m_selectRow);
if (index + < Rows.Count)
{
c = (Rows[index + ] as Control);
SetSelectRow(c, new DataGridViewEventArgs() { RowIndex = index + });
}
}
/// <summary>
/// 选中最后一个
/// </summary>
public void End()
{
if (Rows == null || Rows.Count <= )
return;
Control c = null;
c = (Rows[Rows.Count - ] as Control);
SetSelectRow(c, new DataGridViewEventArgs() { RowIndex = Rows.Count - });
} #endregion #region 事件
void RowSourceChanged(object sender, DataGridViewEventArgs e)
{
if (SourceChanged != null)
SourceChanged(sender, e);
}
private void SetSelectRow(Control item, DataGridViewEventArgs e)
{
try
{
ControlHelper.FreezeControl(this, true);
if (item == null)
return;
if (item.Visible == false)
return;
this.FindForm().ActiveControl = this;
this.FindForm().ActiveControl = item;
if (m_selectRow != null)
{
if (m_selectRow == item)
return;
m_selectRow.SetSelect(false);
}
m_selectRow = item as IDataGridViewRow;
m_selectRow.SetSelect(true);
if (ItemClick != null)
{
ItemClick(item, e);
}
if (this.panRow.Controls.Count > )
{
if (item.Location.Y < )
{
this.panRow.AutoScrollPosition = new Point(, Math.Abs(this.panRow.Controls[this.panRow.Controls.Count - ].Location.Y) + item.Location.Y);
}
else if (item.Location.Y + m_rowHeight > this.panRow.Height)
{
this.panRow.AutoScrollPosition = new Point(, Math.Abs(this.panRow.AutoScrollPosition.Y) + item.Location.Y - this.panRow.Height + m_rowHeight);
}
}
}
finally
{
ControlHelper.FreezeControl(this, false);
}
}
private void UCDataGridView_Resize(object sender, EventArgs e)
{
ResetShowCount();
ReloadSource();
}
#endregion
}
}
 namespace HZH_Controls.Controls
{
partial class UCDataGridView
{
/// <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()
{
this.panHead = new System.Windows.Forms.Panel();
this.panColumns = new System.Windows.Forms.TableLayoutPanel();
this.ucSplitLine_H1 = new HZH_Controls.Controls.UCSplitLine_H();
this.panRow = new System.Windows.Forms.Panel();
this.panPage = new System.Windows.Forms.Panel();
this.panHead.SuspendLayout();
this.SuspendLayout();
//
// panHead
//
this.panHead.Controls.Add(this.panColumns);
this.panHead.Controls.Add(this.ucSplitLine_H1);
this.panHead.Dock = System.Windows.Forms.DockStyle.Top;
this.panHead.Location = new System.Drawing.Point(, );
this.panHead.Name = "panHead";
this.panHead.Size = new System.Drawing.Size(, );
this.panHead.TabIndex = ;
//
// panColumns
//
this.panColumns.ColumnCount = ;
this.panColumns.ColumnStyles.Add(new System.Windows.Forms.ColumnStyle(System.Windows.Forms.SizeType.Percent, 100F));
this.panColumns.Dock = System.Windows.Forms.DockStyle.Fill;
this.panColumns.Location = new System.Drawing.Point(, );
this.panColumns.Name = "panColumns";
this.panColumns.RowCount = ;
this.panColumns.RowStyles.Add(new System.Windows.Forms.RowStyle(System.Windows.Forms.SizeType.Percent, 100F));
this.panColumns.RowStyles.Add(new System.Windows.Forms.RowStyle(System.Windows.Forms.SizeType.Absolute, 20F));
this.panColumns.Size = new System.Drawing.Size(, );
this.panColumns.TabIndex = ;
//
// ucSplitLine_H1
//
this.ucSplitLine_H1.BackColor = System.Drawing.Color.FromArgb(((int)(((byte)()))), ((int)(((byte)()))), ((int)(((byte)()))));
this.ucSplitLine_H1.Dock = System.Windows.Forms.DockStyle.Bottom;
this.ucSplitLine_H1.Location = new System.Drawing.Point(, );
this.ucSplitLine_H1.Name = "ucSplitLine_H1";
this.ucSplitLine_H1.Size = new System.Drawing.Size(, );
this.ucSplitLine_H1.TabIndex = ;
this.ucSplitLine_H1.TabStop = false;
//
// panRow
//
this.panRow.AutoScroll = true;
this.panRow.Dock = System.Windows.Forms.DockStyle.Fill;
this.panRow.Location = new System.Drawing.Point(, );
this.panRow.Name = "panRow";
this.panRow.Size = new System.Drawing.Size(, );
this.panRow.TabIndex = ;
//
// panPage
//
this.panPage.Dock = System.Windows.Forms.DockStyle.Bottom;
this.panPage.Location = new System.Drawing.Point(, );
this.panPage.Name = "panPage";
this.panPage.Size = new System.Drawing.Size(, );
this.panPage.TabIndex = ;
this.panPage.Visible = false;
//
// UCDataGridView
//
this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.None;
this.BackColor = System.Drawing.Color.White;
this.Controls.Add(this.panRow);
this.Controls.Add(this.panPage);
this.Controls.Add(this.panHead);
this.Name = "UCDataGridView";
this.Size = new System.Drawing.Size(, );
this.Resize += new System.EventHandler(this.UCDataGridView_Resize);
this.panHead.ResumeLayout(false);
this.ResumeLayout(false); } #endregion private System.Windows.Forms.Panel panHead;
private System.Windows.Forms.TableLayoutPanel panColumns;
private UCSplitLine_H ucSplitLine_H1;
private System.Windows.Forms.Panel panRow;
private System.Windows.Forms.Panel panPage; }
}

如果你仔细看,你会发现行我用了类型进行传入,当你需要更丰富的行内容的时候,可以自定义行控件,然后通过RowType属性传入

分页控件我使用了分页控件基类UCPagerControlBase,这样做的好处就是你同样可以扩展分页控件

用处及效果

调用示例

  List<DataGridViewColumnEntity> lstCulumns = new List<DataGridViewColumnEntity>();
lstCulumns.Add(new DataGridViewColumnEntity() { DataField = "ID", HeadText = "编号", Width = , WidthType = SizeType.Absolute });
lstCulumns.Add(new DataGridViewColumnEntity() { DataField = "Name", HeadText = "姓名", Width = , WidthType = SizeType.Percent });
lstCulumns.Add(new DataGridViewColumnEntity() { DataField = "Age", HeadText = "年龄", Width = , WidthType = SizeType.Percent });
lstCulumns.Add(new DataGridViewColumnEntity() { DataField = "Birthday", HeadText = "生日", Width = , WidthType = SizeType.Percent, Format = (a) => { return ((DateTime)a).ToString("yyyy-MM-dd"); } });
lstCulumns.Add(new DataGridViewColumnEntity() { DataField = "Sex", HeadText = "性别", Width = , WidthType = SizeType.Percent, Format = (a) => { return ((int)a) == ? "女" : "男"; } });
this.ucDataGridView1.Columns = lstCulumns;
this.ucDataGridView1.IsShowCheckBox = true;
List<object> lstSource = new List<object>();
for (int i = ; i < ; i++)
{
TestModel model = new TestModel()
{
ID = i.ToString(),
Age = * i,
Name = "姓名——" + i,
Birthday = DateTime.Now.AddYears(-),
Sex = i %
};
lstSource.Add(model);
} var page = new UCPagerControl2();
page.DataSource = lstSource;
this.ucDataGridView1.Page = page;
this.ucDataGridView1.First();

如果使用分页控件,则将数据源指定给分页控件,否则直接指定给表格控件数据源

最后的话

如果你喜欢的话,请到 https://gitee.com/kwwwvagaa/net_winform_custom_control 点个星 星吧

(三十二)c#Winform自定义控件-表格的更多相关文章

  1. (三十)c#Winform自定义控件-文本框(三)

    前提 入行已经7,8年了,一直想做一套漂亮点的自定义控件,于是就有了本系列文章. 开源地址:https://gitee.com/kwwwvagaa/net_winform_custom_control ...

  2. Java开发笔记(一百三十二)Swing的表格

    前面介绍了程序界面上一些简单控件的组合排列,它们用来表达相互之间联系较弱的信息倒还凑合,要是用来表达关联性较强的聚合信息就力不从心了.倘若只是简单信息的罗列,例如商品名称列表.新闻标题列表.学生姓名列 ...

  3. (八十六)c#Winform自定义控件-表格优化

    出处:http://www.hzhcontrols.com/原文:http://www.hzhcontrols.com/blog-149.html本文版权归www.hzhcontrols.com所有欢 ...

  4. Bootstrap <基础三十二>模态框(Modal)插件

    模态框(Modal)是覆盖在父窗体上的子窗体.通常,目的是显示来自一个单独的源的内容,可以在不离开父窗体的情况下有一些互动.子窗体可提供信息.交互等. 如果您想要单独引用该插件的功能,那么您需要引用  ...

  5. COJ968 WZJ的数据结构(负三十二)

    WZJ的数据结构(负三十二) 难度级别:D: 运行时间限制:5000ms: 运行空间限制:262144KB: 代码长度限制:2000000B 试题描述 给你一棵N个点的无根树,边上均有权值,每个点上有 ...

  6. NeHe OpenGL教程 第三十二课:拾取游戏

    转自[翻译]NeHe OpenGL 教程 前言 声明,此 NeHe OpenGL教程系列文章由51博客yarin翻译(2010-08-19),本博客为转载并稍加整理与修改.对NeHe的OpenGL管线 ...

  7. 三十二、Java图形化界面设计——布局管理器之CardLayout(卡片布局)

    摘自 http://blog.csdn.net/liujun13579/article/details/7773945 三十二.Java图形化界面设计--布局管理器之CardLayout(卡片布局) ...

  8. JAVA之旅(三十二)——JAVA网络请求,IP地址,TCP/UDP通讯协议概述,Socket,UDP传输,多线程UDP聊天应用

    JAVA之旅(三十二)--JAVA网络请求,IP地址,TCP/UDP通讯协议概述,Socket,UDP传输,多线程UDP聊天应用 GUI写到一半电脑系统挂了,也就算了,最多GUI还有一个提示框和实例, ...

  9. Java进阶(三十二) HttpClient使用详解

    Java进阶(三十二) HttpClient使用详解 Http协议的重要性相信不用我多说了,HttpClient相比传统JDK自带的URLConnection,增加了易用性和灵活性(具体区别,日后我们 ...

  10. Gradle 1.12用户指南翻译——第三十二章. JDepend 插件

    本文由CSDN博客万一博主翻译,其他章节的翻译请参见: http://blog.csdn.net/column/details/gradle-translation.html 翻译项目请关注Githu ...

随机推荐

  1. 20140115-SqlHelper为什么是静态的

    为什么SqlHelper(或工具类)是静态的? 静态构造函数仅调用一次(即只是在程序生命周期中实例一次),在程序驻留的应用程序域的生存期内,静态类一直保留在内存中 这样可以减少每次使用的实例过程,就是 ...

  2. 如何在vue中使用echart

    1.安装echarts依赖   npm install echarts --save 2.在main.js中全局中引用 import echarts from 'echarts' Vue.protot ...

  3. 自定义SSL证书实现单双向ssl认证记录

    自定义SSL证书: 1.ca证书 #openssl genrsa -out ca.key 2048 #openssl req -new -key ca.key -out ca.csr #openssl ...

  4. Spring Cloud 之 Zuul基础.

    一.概述  API 网关是一个更为智能的应用服务器,它的定义类似于面向对象设计模式中的 Facade 模式,它的存在就像是整个微服务架构系统的门面一样,所有的外部客户端访问都需要经过它来进行调度和过滤 ...

  5. 使用jqueryUI实现自由调整表格列宽

    今天项目中需要插入表格,用Excel表格调整列宽时,想怎么拖就怎么拖,于是乎就让插入的表格也这么让人舒服.网上查找许久,没找到好用的方案.最后发现jQuery UI中的resizable()方法可以实 ...

  6. Jmeter(1):使用TCP取样器与socket接口进行简单通信

    一个小任务:服务器与客户端连接,每次发送50个随机生成的字符,两秒发送一次 失败过太多次,然后昨晚终于跑通了,心情激动,于是清均第一篇博客就诞生了. 之前不了解jmeter,想过单纯用java编写服务 ...

  7. C#3.0新增功能09 LINQ 基础08 支持 LINQ 的 C# 功能

    连载目录    [已更新最新开发文章,点击查看详细] 查询表达式 查询表达式使用类似于 SQL 或 XQuery 的声明性语法来查询 IEnumerable 集合. 在编译时,查询语法转换为对 LIN ...

  8. jmter快速安装

    一.简介 Apache JMeter是Apache组织开发的基于Java的压力测试工具,用于接口和压力测试,所以前提是一定更要安装jdk. 二.下载安装 下载:官网下载 下载完成后运行包里的jmete ...

  9. 牛客第三场 J LRU management

    起初看到这道题的时候,草草就放过去了,开了另一道题,结果开题不顺利,总是感觉差一点就可以做出来,以至于一直到最后都没能看这道题qaq 题意:类似于操作系统上讲的LRU算法,有两个操作,0操作代表访问其 ...

  10. rabbitMQ_rpc(六)

    远程过程调用(RPC) 在前面我们已经学习了如何使用工作队列在多个消费者之间分配耗时的任务. 但是如果我们需要在远程计算机上运行功能并等待结果怎么办?那将会是一个不同的故事.此模式通常称为远程过程调用 ...