(八十二)c#Winform自定义控件-穿梭框
官网
前提
入行已经7,8年了,一直想做一套漂亮点的自定义控件,于是就有了本系列文章。
GitHub:https://github.com/kwwwvagaa/NetWinformControl
码云:https://gitee.com/kwwwvagaa/net_winform_custom_control.git
如果觉得写的还行,请点个 star 支持一下吧
欢迎前来交流探讨: 企鹅群568015492 
来都来了,点个【推荐】再走吧,谢谢
NuGet
Install-Package HZH_Controls
目录
https://www.cnblogs.com/bfyx/p/11364884.html
用处及效果

准备工作
这个用到了(一)c#Winform自定义控件-基类控件、(三)c#Winform自定义控件-有图标的按钮 、 (三十二)c#Winform自定义控件-表格 不了解的可以先移步查看一下
开始
添加一个用户控件UCTestTransfer
界面放2个表格,2个按钮即可
添加属性
/// <summary>
/// 移动数据事件
/// </summary>
[Description("移动数据事件"), Category("自定义")]
public event TransferEventHandler Transfered; /// <summary>
/// The left columns
/// </summary>
private DataGridViewColumnEntity[] leftColumns; /// <summary>
/// Gets or sets the left columns.
/// </summary>
/// <value>The left columns.</value>
[Description("左侧列表列"), Category("自定义")]
public DataGridViewColumnEntity[] LeftColumns
{
get { return leftColumns; }
set
{
leftColumns = value;
this.dgvLeft.Columns = leftColumns.ToList();
}
} /// <summary>
/// The right columns
/// </summary>
private DataGridViewColumnEntity[] rightColumns; /// <summary>
/// Gets or sets the right columns.
/// </summary>
/// <value>The right columns.</value>
[Description("右侧列表列"), Category("自定义")]
public DataGridViewColumnEntity[] RightColumns
{
get { return rightColumns; }
set
{
rightColumns = value;
this.dgvRight.Columns = leftColumns.ToList();
}
} /// <summary>
/// The left data source
/// </summary>
private object[] leftDataSource;
/// <summary>
/// 左右列表必须设置相同类型的数据源列表,如果为空必须为长度为0的数组
/// </summary>
/// <value>The left data source.</value>
[Description("左侧列表数据源"), Category("自定义"), Browsable(false), EditorBrowsable(EditorBrowsableState.Never)]
public object[] LeftDataSource
{
get { return leftDataSource; }
set
{
leftDataSource = value;
dgvLeft.DataSource = value;
}
} /// <summary>
/// The right data source
/// </summary>
private object[] rightDataSource;
/// <summary>
/// 左右列表必须设置相同类型的数据源列表,如果为空必须为长度为0的数组
/// </summary>
/// <value>The left data source.</value>
[Description("右侧列表数据源"), Category("自定义"), Browsable(false), EditorBrowsable(EditorBrowsableState.Never)]
public object[] RightDataSource
{
get { return rightDataSource; }
set
{
rightDataSource = value;
dgvRight.DataSource = value;
}
}
处理左右移动按钮事件
/// <summary>
/// Handles the BtnClick event of the btnRight control.
/// </summary>
/// <param name="sender">The source of the event.</param>
/// <param name="e">The <see cref="EventArgs"/> instance containing the event data.</param>
/// <exception cref="System.Exception">
/// 左右数据源列表不能为空
/// or
/// 左右数据源列表类型不一致,无法进行操作
/// </exception>
private void btnRight_BtnClick(object sender, EventArgs e)
{
if (LeftDataSource == null || RightDataSource == null)
{
throw new Exception("左右数据源列表不能为空");
}
if (LeftDataSource.GetType() != RightDataSource.GetType())
{
throw new Exception("左右数据源列表类型不一致,无法进行操作");
}
if (dgvLeft.SelectRows == null || dgvLeft.SelectRows.Count <= )
return;
List<object> lst = new List<object>();
dgvLeft.SelectRows.ForEach(p =>
{
lst.Add(p.DataSource);
p.IsChecked = false;
});
var lstRight = RightDataSource.ToList();
lstRight.AddRange(lst);
var lstLeft = LeftDataSource.ToList();
lstLeft.RemoveAll(p => lst.Contains(p));
RightDataSource = lstRight.ToArray();
LeftDataSource = lstLeft.ToArray();
if (Transfered != null)
{
Transfered(this, new TransferEventArgs() { TransferDataSource = lst.ToArray(), ToRightOrLeft = true });
}
} /// <summary>
/// Handles the BtnClick event of the btnLeft control.
/// </summary>
/// <param name="sender">The source of the event.</param>
/// <param name="e">The <see cref="EventArgs"/> instance containing the event data.</param>
/// <exception cref="System.Exception">
/// 左右数据源列表不能为空
/// or
/// 左右数据源列表类型不一致,无法进行操作
/// </exception>
private void btnLeft_BtnClick(object sender, EventArgs e)
{
if (LeftDataSource == null || RightDataSource == null)
{
throw new Exception("左右数据源列表不能为空");
}
if (LeftDataSource.GetType() != RightDataSource.GetType())
{
throw new Exception("左右数据源列表类型不一致,无法进行操作");
}
if (dgvRight.SelectRows == null || dgvRight.SelectRows.Count <= )
return;
List<object> lst = new List<object>();
dgvRight.SelectRows.ForEach(p =>
{
lst.Add(p.DataSource);
p.IsChecked = false;
});
var lstLeft = LeftDataSource.ToList();
lstLeft.AddRange(lst);
var lstRight = RightDataSource.ToList();
lstRight.RemoveAll(p => lst.Contains(p));
RightDataSource = lstRight.ToArray();
LeftDataSource = lstLeft.ToArray();
if (Transfered != null)
{
Transfered(this, new TransferEventArgs() { TransferDataSource = lst.ToArray(), ToRightOrLeft = false });
}
}
完整代码
// ***********************************************************************
// Assembly : HZH_Controls
// Created : 2019-10-10
//
// ***********************************************************************
// <copyright file="UCTransfer.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; namespace HZH_Controls.Controls
{
/// <summary>
/// Class UCTransfer.
/// Implements the <see cref="System.Windows.Forms.UserControl" />
/// </summary>
/// <seealso cref="System.Windows.Forms.UserControl" />
[DefaultEvent("Transfered")]
public partial class UCTransfer : UserControl
{
/// <summary>
/// 移动数据事件
/// </summary>
[Description("移动数据事件"), Category("自定义")]
public event TransferEventHandler Transfered; /// <summary>
/// The left columns
/// </summary>
private DataGridViewColumnEntity[] leftColumns; /// <summary>
/// Gets or sets the left columns.
/// </summary>
/// <value>The left columns.</value>
[Description("左侧列表列"), Category("自定义")]
public DataGridViewColumnEntity[] LeftColumns
{
get { return leftColumns; }
set
{
leftColumns = value;
this.dgvLeft.Columns = leftColumns.ToList();
}
} /// <summary>
/// The right columns
/// </summary>
private DataGridViewColumnEntity[] rightColumns; /// <summary>
/// Gets or sets the right columns.
/// </summary>
/// <value>The right columns.</value>
[Description("右侧列表列"), Category("自定义")]
public DataGridViewColumnEntity[] RightColumns
{
get { return rightColumns; }
set
{
rightColumns = value;
this.dgvRight.Columns = leftColumns.ToList();
}
} /// <summary>
/// The left data source
/// </summary>
private object[] leftDataSource;
/// <summary>
/// 左右列表必须设置相同类型的数据源列表,如果为空必须为长度为0的数组
/// </summary>
/// <value>The left data source.</value>
[Description("左侧列表数据源"), Category("自定义"), Browsable(false), EditorBrowsable(EditorBrowsableState.Never)]
public object[] LeftDataSource
{
get { return leftDataSource; }
set
{
leftDataSource = value;
dgvLeft.DataSource = value;
}
} /// <summary>
/// The right data source
/// </summary>
private object[] rightDataSource;
/// <summary>
/// 左右列表必须设置相同类型的数据源列表,如果为空必须为长度为0的数组
/// </summary>
/// <value>The left data source.</value>
[Description("右侧列表数据源"), Category("自定义"), Browsable(false), EditorBrowsable(EditorBrowsableState.Never)]
public object[] RightDataSource
{
get { return rightDataSource; }
set
{
rightDataSource = value;
dgvRight.DataSource = value;
}
} /// <summary>
/// Initializes a new instance of the <see cref="UCTransfer"/> class.
/// </summary>
public UCTransfer()
{
InitializeComponent();
dgvLeft.IsCloseAutoHeight = true;
dgvRight.IsCloseAutoHeight = true;
LeftColumns = new DataGridViewColumnEntity[];
RightColumns = new DataGridViewColumnEntity[];
LeftDataSource = new object[];
RightDataSource = new object[];
} /// <summary>
/// Handles the BtnClick event of the btnRight control.
/// </summary>
/// <param name="sender">The source of the event.</param>
/// <param name="e">The <see cref="EventArgs"/> instance containing the event data.</param>
/// <exception cref="System.Exception">
/// 左右数据源列表不能为空
/// or
/// 左右数据源列表类型不一致,无法进行操作
/// </exception>
private void btnRight_BtnClick(object sender, EventArgs e)
{
if (LeftDataSource == null || RightDataSource == null)
{
throw new Exception("左右数据源列表不能为空");
}
if (LeftDataSource.GetType() != RightDataSource.GetType())
{
throw new Exception("左右数据源列表类型不一致,无法进行操作");
}
if (dgvLeft.SelectRows == null || dgvLeft.SelectRows.Count <= )
return;
List<object> lst = new List<object>();
dgvLeft.SelectRows.ForEach(p =>
{
lst.Add(p.DataSource);
p.IsChecked = false;
});
var lstRight = RightDataSource.ToList();
lstRight.AddRange(lst);
var lstLeft = LeftDataSource.ToList();
lstLeft.RemoveAll(p => lst.Contains(p));
RightDataSource = lstRight.ToArray();
LeftDataSource = lstLeft.ToArray();
if (Transfered != null)
{
Transfered(this, new TransferEventArgs() { TransferDataSource = lst.ToArray(), ToRightOrLeft = true });
}
} /// <summary>
/// Handles the BtnClick event of the btnLeft control.
/// </summary>
/// <param name="sender">The source of the event.</param>
/// <param name="e">The <see cref="EventArgs"/> instance containing the event data.</param>
/// <exception cref="System.Exception">
/// 左右数据源列表不能为空
/// or
/// 左右数据源列表类型不一致,无法进行操作
/// </exception>
private void btnLeft_BtnClick(object sender, EventArgs e)
{
if (LeftDataSource == null || RightDataSource == null)
{
throw new Exception("左右数据源列表不能为空");
}
if (LeftDataSource.GetType() != RightDataSource.GetType())
{
throw new Exception("左右数据源列表类型不一致,无法进行操作");
}
if (dgvRight.SelectRows == null || dgvRight.SelectRows.Count <= )
return;
List<object> lst = new List<object>();
dgvRight.SelectRows.ForEach(p =>
{
lst.Add(p.DataSource);
p.IsChecked = false;
});
var lstLeft = LeftDataSource.ToList();
lstLeft.AddRange(lst);
var lstRight = RightDataSource.ToList();
lstRight.RemoveAll(p => lst.Contains(p));
RightDataSource = lstRight.ToArray();
LeftDataSource = lstLeft.ToArray();
if (Transfered != null)
{
Transfered(this, new TransferEventArgs() { TransferDataSource = lst.ToArray(), ToRightOrLeft = false });
}
}
}
}
最后的话
如果你喜欢的话,请到 https://gitee.com/kwwwvagaa/net_winform_custom_control 点个星星吧
(八十二)c#Winform自定义控件-穿梭框的更多相关文章
- (三十)c#Winform自定义控件-文本框(三)
前提 入行已经7,8年了,一直想做一套漂亮点的自定义控件,于是就有了本系列文章. 开源地址:https://gitee.com/kwwwvagaa/net_winform_custom_control ...
- (八十)c#Winform自定义控件-分割线标签-HZHControls
官网 http://www.hzhcontrols.com 前提 入行已经7,8年了,一直想做一套漂亮点的自定义控件,于是就有了本系列文章. GitHub:https://github.com/kww ...
- (十六)c#Winform自定义控件-文本框哪里去了?-HZHControls
官网 http://www.hzhcontrols.com 前提 入行已经7,8年了,一直想做一套漂亮点的自定义控件,于是就有了本系列文章. GitHub:https://github.com/kww ...
- “全栈2019”Java第八十二章:嵌套接口能否访问外部类中的成员?
难度 初级 学习时间 10分钟 适合人群 零基础 开发语言 Java 开发环境 JDK v11 IntelliJ IDEA v2018.3 文章原文链接 "全栈2019"Java第 ...
- (十八)c#Winform自定义控件-提示框
前提 入行已经7,8年了,一直想做一套漂亮点的自定义控件,于是就有了本系列文章. 开源地址:https://gitee.com/kwwwvagaa/net_winform_custom_control ...
- (二十)c#Winform自定义控件-有后退的窗体
前提 入行已经7,8年了,一直想做一套漂亮点的自定义控件,于是就有了本系列文章. 开源地址:https://gitee.com/kwwwvagaa/net_winform_custom_control ...
- (三十一)c#Winform自定义控件-文本框(四)
前提 入行已经7,8年了,一直想做一套漂亮点的自定义控件,于是就有了本系列文章. 开源地址:https://gitee.com/kwwwvagaa/net_winform_custom_control ...
- (五十)c#Winform自定义控件-滑块
前提 入行已经7,8年了,一直想做一套漂亮点的自定义控件,于是就有了本系列文章. GitHub:https://github.com/kwwwvagaa/NetWinformControl 码云:ht ...
- (二十八)c#Winform自定义控件-文本框(一)
前提 入行已经7,8年了,一直想做一套漂亮点的自定义控件,于是就有了本系列文章. 开源地址:https://gitee.com/kwwwvagaa/net_winform_custom_control ...
随机推荐
- CCPC 网络赛
array 做法 比赛中的表现..... 已经无法言语形容了. 题意是,查询前缀中大于某个数字的 mex,在线. 一下把问题转化为偏序问题.... 带修主席树?????这下好,直接一箭穿心,武将被移除 ...
- CodeForces 1018B The hat
The hat 题解: 定义d[i]为第i个数和他对面的差值. 然后我们可以发现d[i]和d[i+1]的差值只会有3种情况2, -2, 0. 并且可以知道 d[i] = - d[i+n/2] 所以如果 ...
- lightoj 1032 - Fast Bit Calculations(数位dp)
A bit is a binary digit, taking a logical value of either 1 or 0 (also referred to as "true&quo ...
- CODE[VS] 1294 全排列
1294 全排列 时间限制: 1 s 空间限制: 128000 KB 题目等级 : 黄金 Gold 题解 查看运行结果 题目描述 Description 给出一个n, 请输出n的所有全 ...
- codeforces 811 D. Vladik and Favorite Game(bfs水题)
题目链接:http://codeforces.com/contest/811/problem/D 题意:现在给你一个n*m大小的图,你输出一个方向之后,系统反馈给你一个坐标,表示走完这步之后到的位子, ...
- codeforces 701 E. Connecting Universities(树+ 边的贡献)
题目链接:http://codeforces.com/contest/701/problem/E 题意:有n个城市构成一棵树,一个城市最多有一个学校,这n个城市一共2*k个学校,要对这2*k个学校进行 ...
- hdu 2050 折线分割平面 dp递推 *
折线分割平面 Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 65536/32768 K (Java/Others)Total Subm ...
- 淘淘购物系统 (Python)
#首页def tao_first(): t1 = '欢迎进入淘淘购物'.center(110) print(t1) print('~' * 130) t2 = '注册'.center(20) prin ...
- 通过CMD命令窗口获取django版本号
通过CMD命令窗口获取django版本号 方法一: C:\Users\Administrator>python >>> import django >>> d ...
- iOS组件化实践
参考资料: http://wereadteam.github.io/2016/03/19/iOS-Component/#more https://casatwy.com/iOS-Modulizatio ...