文章目录
用处及效果
使用分页控件效果

不使用分页控件效果

准备工作
我们需要元素控件,需要列表控件,另外为了具有更好的扩展性,元素控件实现接口,方便进行扩展
我们用到了分页控件,如果你还不了解,请移步查看
我们这里的元素控件用到圆角,故继承基类控件UCControlBase,如果不了解,请移步查看
开始
添加一个接口,用来约束元素控件
public interface IListViewItem
{
/// <summary>
/// 数据源
/// </summary>
object DataSource { get; set; }
/// <summary>
/// 选中项事件
/// </summary>
event EventHandler SelectedItemEvent;
/// <summary>
/// 选中处理,一般用以更改选中效果
/// </summary>
/// <param name="blnSelected">是否选中</param>
void SetSelected(bool blnSelected);
}
添加一个元素控件,命名UCListViewItem,我们这里继承基类控件UCControlBase,实现接口IListViewItem
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 UCListViewItem : UCControlBase, IListViewItem
{
private object m_dataSource;
public object DataSource
{
get
{
return m_dataSource;
}
set
{
m_dataSource = value;
lblTitle.Text = value.ToString();
}
}
public event EventHandler SelectedItemEvent;
public UCListViewItem()
{
InitializeComponent();
lblTitle.MouseDown += lblTitle_MouseDown;
}
void lblTitle_MouseDown(object sender, MouseEventArgs e)
{
if (SelectedItemEvent != null)
{
SelectedItemEvent(this, e);
}
}
public void SetSelected(bool blnSelected)
{
if (blnSelected)
this.FillColor = Color.FromArgb(255, 247, 245);
else
this.FillColor = Color.White;
this.Refresh();
}
}
}
namespace HZH_Controls.Controls
{
partial class UCListViewItem
{
/// <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.lblTitle = new System.Windows.Forms.Label();
this.SuspendLayout();
//
// lblTitle
//
this.lblTitle.Dock = System.Windows.Forms.DockStyle.Fill;
this.lblTitle.Location = new System.Drawing.Point(0, 0);
this.lblTitle.Name = "lblTitle";
this.lblTitle.Size = new System.Drawing.Size(107, 96);
this.lblTitle.TabIndex = 0;
this.lblTitle.TextAlign = System.Drawing.ContentAlignment.MiddleCenter;
//
// UCListViewItem
//
this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.None;
this.BackColor = System.Drawing.Color.Transparent;
this.Controls.Add(this.lblTitle);
this.FillColor = System.Drawing.Color.White;
this.IsRadius = true;
this.IsShowRect = true;
this.Name = "UCListViewItem";
this.RectColor = System.Drawing.Color.FromArgb(((int)(((byte)(232)))), ((int)(((byte)(232)))), ((int)(((byte)(232)))));
this.Size = new System.Drawing.Size(107, 96);
this.ResumeLayout(false);
}
#endregion
private System.Windows.Forms.Label lblTitle;
}
}
然后需要一个列表来显示元素控件
添加一个用户控件,命名UCListView
一些属性
int m_intCellWidth = 130;//单元格宽度
int m_intCellHeight = 120;//单元格高度
private Type m_itemType = typeof(UCListViewItem);
[Description("单元格类型,如果无法满足您的需求,你可以自定义单元格控件,并实现接口IListViewItem"), Category("自定义")]
public Type ItemType
{
get { return m_itemType; }
set
{
if (!typeof(IListViewItem).IsAssignableFrom(value) || !value.IsSubclassOf(typeof(Control)))
throw new Exception("单元格控件没有继承实现接口IListViewItem");
m_itemType = value;
}
}
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");
this.panMain.AutoScroll = false;
panPage.Visible = true;
this.Controls.SetChildIndex(panMain, 0);
m_page.ShowSourceChanged += m_page_ShowSourceChanged;
m_page.Dock = DockStyle.Fill;
this.panPage.Controls.Clear();
this.panPage.Controls.Add(m_page);
GetCellCount();
this.DataSource = m_page.GetCurrentSource();
}
else
{
this.panMain.AutoScroll = true;
m_page = null;
panPage.Visible = false;
}
}
}
private object m_dataSource = null;
[Description("数据源,如果使用翻页控件,请使用翻页控件的DataSource"), Category("自定义")]
public object DataSource
{
get { return m_dataSource; }
set
{
if (value == null)
return;
if (!typeof(IList).IsAssignableFrom(value.GetType()))
{
throw new Exception("数据源不是有效的数据类型,列表");
}
m_dataSource = value;
ReloadSource();
}
}
int m_intCellCount = 0;//单元格总数
[Description("单元格总数"), Category("自定义")]
public int CellCount
{
get { return m_intCellCount; }
private set
{
m_intCellCount = value;
if (value > 0 && m_page != null)
{
m_page.PageSize = m_intCellCount;
m_page.Reload();
}
}
}
private List<object> m_selectedSource = new List<object>();
[Description("选中的数据"), Category("自定义")]
public List<object> SelectedSource
{
get { return m_selectedSource; }
set
{
m_selectedSource = value;
ReloadSource();
}
}
private bool m_isMultiple = true;
[Description("是否多选"), Category("自定义")]
public bool IsMultiple
{
get { return m_isMultiple; }
set { m_isMultiple = value; }
}
[Description("选中项事件"), Category("自定义")]
public event EventHandler SelectedItemEvent;
public delegate void ReloadGridStyleEventHandle(int intCellCount);
/// <summary>
/// 样式改变事件
/// </summary>
[Description("样式改变事件"), Category("自定义")]
public event ReloadGridStyleEventHandle ReloadGridStyleEvent;
一下辅助函数
#region 重新加载数据源
/// <summary>
/// 功能描述:重新加载数据源
/// 作 者:HZH
/// 创建日期:2019-06-27 16:47:32
/// 任务编号:POS
/// </summary>
public void ReloadSource()
{
ControlHelper.FreezeControl(this, true);
if (this.panMain.Controls.Count <= 0)
{
ReloadGridStyle();
}
if (m_dataSource == null || ((IList)m_dataSource).Count <= 0)
{
for (int i = this.panMain.Controls.Count - 1; i >= 0; i--)
{
this.panMain.Controls[i].Visible = false;
}
return;
}
int intCount = Math.Min(((IList)m_dataSource).Count, this.panMain.Controls.Count);
for (int i = 0; i < intCount; i++)
{
((IListViewItem)this.panMain.Controls[i]).DataSource = ((IList)m_dataSource)[i];
if (m_selectedSource.Contains(((IList)m_dataSource)[i]))
{
((IListViewItem)this.panMain.Controls[i]).SetSelected(true);
}
else
{
((IListViewItem)this.panMain.Controls[i]).SetSelected(false);
}
this.panMain.Controls[i].Visible = true;
}
for (int i = this.panMain.Controls.Count - 1; i >= intCount; i--)
{
if (this.panMain.Controls[i].Visible)
this.panMain.Controls[i].Visible = false;
}
ControlHelper.FreezeControl(this, false);
}
#endregion
#region 刷新表格
/// <summary>
/// 功能描述:刷新表格样式
/// 作 者:HZH
/// 创建日期:2019-06-27 16:35:25
/// 任务编号:POS
/// </summary>
public void ReloadGridStyle()
{
Form frmMain = this.FindForm();
if (frmMain != null && !frmMain.IsDisposed && frmMain.Visible && this.Visible)
{
GetCellCount();
try
{
ControlHelper.FreezeControl(this, true);
if (this.panMain.Controls.Count < m_intCellCount)
{
int intControlsCount = this.panMain.Controls.Count;
for (int i = 0; i < m_intCellCount - intControlsCount; i++)
{
Control uc = (Control)Activator.CreateInstance(m_itemType);
uc.Margin = new System.Windows.Forms.Padding(5, 5, 5, 5);
(uc as IListViewItem).SelectedItemEvent += UCListView_SelectedItemEvent;
uc.Visible = false;
this.panMain.Controls.Add(uc);
}
}
else if (this.panMain.Controls.Count > m_intCellCount)
{
int intControlsCount = this.panMain.Controls.Count;
for (int i = intControlsCount - 1; i > m_intCellCount - 1; i--)
{
this.panMain.Controls.RemoveAt(i);
}
}
foreach (Control item in this.panMain.Controls)
{
item.Size = new Size(m_intCellWidth, m_intCellHeight);
}
}
finally
{
ControlHelper.FreezeControl(this, false);
}
if (ReloadGridStyleEvent != null)
{
ReloadGridStyleEvent(m_intCellCount);
}
}
}
void UCListView_SelectedItemEvent(object sender, EventArgs e)
{
var selectedItem = sender as IListViewItem;
if (m_selectedSource.Contains(selectedItem.DataSource))
{
m_selectedSource.Remove(selectedItem.DataSource);
selectedItem.SetSelected(false);
}
else
{
if (m_isMultiple)
{
m_selectedSource.Add(selectedItem.DataSource);
selectedItem.SetSelected(true);
}
else
{
if (m_selectedSource.Count > 0)
{
int intCount = Math.Min(((IList)m_dataSource).Count, this.panMain.Controls.Count);
for (int i = 0; i < intCount; i++)
{
var item = ((IListViewItem)this.panMain.Controls[i]);
if (m_selectedSource.Contains(item.DataSource))
{
item.SetSelected(false);
break;
}
}
}
m_selectedSource = new List<object>() { selectedItem.DataSource };
selectedItem.SetSelected(true);
}
}
if (SelectedItemEvent != null)
{
SelectedItemEvent(sender, e);
}
}
#endregion
#region 获取cell总数
/// <summary>
/// 功能描述:获取cell总数
/// 作 者:HZH
/// 创建日期:2019-06-27 16:28:58
/// 任务编号:POS
/// </summary>
private void GetCellCount()
{
if (this.panMain.Width == 0)
return;
Control item = (Control)Activator.CreateInstance(m_itemType);
int intXCount = (this.panMain.Width - 10) / (item.Width + 10);
m_intCellWidth = item.Width + ((this.panMain.Width - 10) % (item.Width + 10)) / intXCount;
int intYCount = (this.panMain.Height - 10) / (item.Height + 10);
m_intCellHeight = item.Height + ((this.panMain.Height - 10) % (item.Height + 10)) / intYCount;
int intCount = intXCount * intYCount;
if (Page == null)
{
if (((IList)m_dataSource).Count > intCount)
{
intXCount = (this.panMain.Width - 10 - 20) / (item.Width + 10);
m_intCellWidth = item.Width + ((this.panMain.Width - 10 - 20) % (item.Width + 10)) / intXCount;
}
intCount = Math.Max(intCount, ((IList)m_dataSource).Count);
}
CellCount = intCount;
}
#endregion
一些事件
private void panMain_Resize(object sender, EventArgs e)
{
ReloadGridStyle();
}
void m_page_ShowSourceChanged(object currentSource)
{
this.DataSource = currentSource;
}
你会发现,有个ItemType属性,这个用来定义列表呈现那种子元素,这么用的好处就是,当你觉得我写的这个元素控件UCListViewItem并不能满足你需求的时候,你可以添加一个自定义控件,并实现接口IListViewItem,然后将你自定义的控件指定给这个属性,列表就会呈现出来了,是不是很方便,列表会自动根据你的元素控件的大小来适量调整来填充到列表中的。
还有一个Page属性,这个是用来表示用哪个分页控件,当然你也可以不用,我已经提供了2种分页控件,如果你觉得还是不满足你的话,去参考分页控件那个文章,自己添加一个分页控件吧。
最后的话
如果你喜欢的话,请到 https://gitee.com/kwwwvagaa/net_winform_custom_control 点个星星吧
作者:冰封一夏
出处: http://www.hzhcontrols.com/doc.html
本文版权归作者和博客园共有,欢迎转载,但未经作者同意必须保留此段声明,
且在文章页面明显位置给出原文连接,否则保留追究法律责任的权利。
GitHub:https://github.com/kwwwvagaa/NetWinformControl
码云:https://gitee.com/kwwwvagaa/net_winform_custom_control.git