以往都是做的网站接口什么的,比较少接触桌面软件,刚好最近抽空用了winform做一个桌面软件玩玩,使用 SunnyUI 类库 做界面,遇到一些问题,在此做个记录。
1. DateGridView 添加按钮
winform原生控件不美观,用了SunnyUI,就比较好看了,不过SunnyUI需要授权才能解锁更多功能,对于开源版的,有些功能就得自己实现了。
DateGridView 是个 常见的 控件,一般用来做表格,就像网站的一些列表,最后一列 是操作列, 做一些 按钮 等功能,比如 编辑,删除,预览 。使用DateGridView直接来做按钮就比较麻烦,虽然也 有提供单元格可以设置 为 按钮 的 功能,但是 对于样式 就不好修改了,而且一列多个按钮就比较 麻烦了,最终还是得自己实现了(参考了网上一些思路),自个渲染按钮了。
//获取按钮控件(这里做了一些简单的封装,方便统一按钮样式,写死只弄了3种颜色)
private UIButton GetBtnByType(string strBtnName, string strBtnText,
int tag, EventHandler handler = null, int ButtonColor = 0)
{
var btn = new UIButton();
btn.Name = strBtnName;
btn.Text = strBtnText;
btn.Tag = tag;
btn.BackColor = Color.White;
btn.FillColor = Color.White;
btn.FillHoverColor = Color.White;
btn.FillPressColor = Color.White;
btn.RectColor = Color.White;
btn.RectHoverColor = Color.White;
btn.RectPressColor = Color.White;
if (ButtonColor == 1)
{
btn.ForeColor = Color.FromArgb(233, 70, 108);
btn.ForeHoverColor = Color.OrangeRed;
btn.ForePressColor = Color.OrangeRed;
}
else if (ButtonColor == 2)
{
btn.ForeColor = Color.LightSkyBlue;
btn.ForeHoverColor = Color.Blue;
btn.ForePressColor = Color.Blue;
}
else
{
btn.ForeColor = Color.FromArgb(66, 66, 66);
btn.ForeHoverColor = Color.LightSkyBlue;
btn.ForePressColor = Color.LightSkyBlue;
}
if (handler != null)
{
btn.Click += handler;
}
return btn;
}
//这个是 userList,即DateGridView 循环显示数据 时候,在对应行 添加 按钮
//userList 需要把 控件 添加 进来
//i是 第几行,cloum 是 第几列,num 是 把单元格宽度平分(几个按钮就平分几个,根据需要)
//Size 和 Location 也根据需要了
//mButtons 是 保存 添加 到 DateGridView 里 的 按钮
//为了控制这些按钮的 隐藏和现实等,我这里只弄了 2个按钮,第二个传空,代表没有按钮
var btnEdit = GetBtnByType("name_" + i, "查看", i, button_Clikc,2);
this.userList.Controls.Add(btnEdit);
Rectangle rectangle = this.userList.GetCellDisplayRectangle(cloum, i, true);
btnEdit.Size = new Size(rectangle.Width / num - 2, rectangle.Height-2);
btnEdit.Location = new Point(rectangle.Left+1, rectangle.Top+1);
mButtons.Add(new ActionButtons(btnEdit,null));
//保存 每一行 操作列 的 按钮 对象, 这里 只弄了 两个 按钮(其实可以弄成更灵活的,这里就偷懒了)
//这个 也是参考 网上 改来的
internal class ActionButtons
{
public ActionButtons(UIButton addButton, UIButton removeButton)
{
AddButton = addButton;
RemoveButton = removeButton;
if (AddButton!=null)
{
num++;
}
if (RemoveButton != null)
{
num++;
}
}
public int num { get; set; }=0;
public UIButton AddButton { get; set; }
public UIButton RemoveButton { get; set; }
}
只做到 这一步 ,按钮 基本上 就 可以 显示 出来了, 也可以绑定事件。但是 对于 行 的 数量 过多的,会出现 一种情况,就是 滚动面板的 时候 ,按钮 不会 动,被固定了,所以 还得 对 DateGridView 的 滚动 事件 绑定 更新按钮 位置 的 功能。
//隐藏按钮
private void HideAllActionButtons(ActionButtons ab)
{
if (ab.AddButton != null)
{
ab.AddButton.Visible = false;
}
if (ab.RemoveButton != null)
{
ab.RemoveButton.Visible = false;
}
}
//更新按钮位置
private void UpdateActionButtonsPosition(ActionButtons ab, Rectangle rect, int rowIndex)
{
if (ab.AddButton!=null)
{
ab.AddButton.Location = new Point(rect.Left+2, rect.Top+2);
ab.AddButton.Size = new Size(rect.Width / ab.num - 4, rect.Height-4);
ab.AddButton.Visible = true;
}
if (ab.RemoveButton != null)
{
ab.RemoveButton.Location = new Point(ab.AddButton.Width + rect.Left+ 2, rect.Top+2);
ab.RemoveButton.Size = ab.AddButton.Size;
ab.RemoveButton.Visible = true;// rowIndex > 0;
}
}
//重新定位按钮位置
//Sleep 不加的话 有点问题 (不记得啥问题了)
//先 拿到 面板 显示 的 起始行 和 面板 能显示 的 行数量
//得出 起始 和 结束 行数(这些 就是 需要显示的,其他的按钮 要隐藏)
//因为是在非主线程中操作,所以需要委托主线程来执行操作控件
private void RepositionActionButtons(List<ActionButtons> mButtons,UIDataGridView dgvList,int colum)
{
Task.Run(() =>
{
Thread.Sleep(50);
int firstRow = dgvList.FirstDisplayedScrollingRowIndex;
int lastRow = firstRow + dgvList.DisplayedRowCount(false);
for (int i = 0; i < mButtons.Count; i++)
{
ActionButtons ab = mButtons[i];
if (i >= firstRow && i <= lastRow)
{
Rectangle rect = dgvList.GetCellDisplayRectangle(colum, i, false);
userList.Invoke((Action)(() =>
{
UpdateActionButtonsPosition(ab, rect, i);
}));
}else
{
userList.Invoke((Action)(() =>
{
HideAllActionButtons(ab);
}));
}
}
});
}
//绑定 滚动事件
//cloum 是 第几列
private void dataGridView1_Scroll(object sender, ScrollEventArgs e)
{
var dgv= sender as UIDataGridView;
var i = dgv.Tag.ToInt(); //可以根据 i 来决定 操作 哪个 表格 和 哪些按钮,可复用的写法
var cloum=4;
RepositionActionButtons(mButtons,userList,cloum);
}
//每次刷新数据 需要重新绑定按钮,所以要清理掉
//但是 有BUG的样子,Controls.Clear() 一次请不干净,所以得循环了
for (var i = 0; i < 10; i++)
{
userList.Controls.Clear();
}
这样基本上就完成了 DateGridView 添加 按钮了,样式就需要自己慢慢调整了。
2.由于需求,需要实现列的拖拽功能(就是列手动换位置),发现 winform 的gdv本身有自带了
即 AllowUserToOrderColumns 设置为 true 即可
监听对应事件是这个: ColumnDisplayIndexChanged
做个记录

5244

被折叠的 条评论
为什么被折叠?



