删除 Winforms 中的 DataRepeater Control 底线
Remove DataRepeater Control bottom line in Winforms
如何删除DataRepeater
控件中数据控件项的底部边框线:
您在 DataRepeater
控件中项目之间看到的分隔符,是在 DataRepeaterItem
控件的非客户区上绘制的。
您可以找到那些 DataRepeaterItem
并处理那些 WM_NCPAINT
消息,并用与项目 BackColor
相同的颜色或您想要的 [=17= 中的任何其他颜色画一条线] 到 (Width-1, Height-1)
.
实施
为此,我们创建了一个派生自 NativeWindow
的 class,它使我们能够处理另一个 window 的消息,如果我们将其他 window 的句柄分配给它:
using Microsoft.VisualBasic.PowerPacks;
using System;
using System.Drawing;
using System.Runtime.InteropServices;
using System.Windows.Forms;
public class DataRepeaterItemHelper : NativeWindow
{
private DataRepeaterItem item;
private const int WM_NCPAINT = 0x85;
[DllImport("user32.dll")]
static extern IntPtr GetWindowDC(IntPtr hWnd);
[DllImport("user32.dll")]
static extern int ReleaseDC(IntPtr hWnd, IntPtr hDC);
public DataRepeaterItemHelper(DataRepeaterItem repeaterItem)
{
item = repeaterItem;
this.AssignHandle(item.Handle);
}
protected override void WndProc(ref Message m)
{
base.WndProc(ref m);
if (m.Msg == WM_NCPAINT)
{
var hdc = GetWindowDC(m.HWnd);
using (var g = Graphics.FromHdcInternal(hdc))
using (var p = new Pen(item.BackColor, 1))
g.DrawLine(p, 0, item.Height - 1, item.Width - 1, item.Height - 1);
ReleaseDC(m.HWnd, hdc);
}
}
}
然后我们处理 DataRepeater
的 DrawItem
事件并检查我们是否没有为 e.DataRepeaterItem
创建一个 DataRepeaterItemHelper
我们创建一个。它有助于绘制与项目背景颜色相同的颜色的分隔符。同样,在将数据加载到 DataRepeater
之后,我们应该为第一个没有触发 DrawItem
事件的项目创建 DataRepeaterItemHelper
。为了跟踪我们为他们创建的 DataRepeaterItemHelper
项目,我们将处理过的项目保存在 List<DataRepeaterItem>
:
中
new List<DataRepeaterItem> items = new List<DataRepeaterItem>();
void HandleItem(DataRepeaterItem item)
{
if (items.Contains(item))
return;
var handler = new DataRepeaterItemHelper(item);
items.Add(item);
}
private void Form1_Load(object sender, EventArgs e)
{
//Load data and put data in dataRepeater1.DataSource
var db = new TestDBEntities();
this.dataRepeater1.DataSource = db.Category.ToList();
this.dataRepeater1.Controls.OfType<DataRepeaterItem>().ToList()
.ForEach(item => HandleItem(item));
this.dataRepeater1.DrawItem += dataRepeater1_DrawItem;
}
void dataRepeater1_DrawItem(object sender, DataRepeaterItemEventArgs e)
{
HandleItem(e.DataRepeaterItem);
}
结果如下:
注:
- 应用解决方案时,不要忘记将
Form1_Load
事件附加到表单的 Load
事件。您不需要将 dataRepeater1_DrawItem
附加到 DrawItem
事件。它已使用代码附加在 Form1_Load
中。
- 您可以将逻辑封装在派生的
DataRepeater
控件中。
如何删除DataRepeater
控件中数据控件项的底部边框线:
您在 DataRepeater
控件中项目之间看到的分隔符,是在 DataRepeaterItem
控件的非客户区上绘制的。
您可以找到那些 DataRepeaterItem
并处理那些 WM_NCPAINT
消息,并用与项目 BackColor
相同的颜色或您想要的 [=17= 中的任何其他颜色画一条线] 到 (Width-1, Height-1)
.
实施
为此,我们创建了一个派生自 NativeWindow
的 class,它使我们能够处理另一个 window 的消息,如果我们将其他 window 的句柄分配给它:
using Microsoft.VisualBasic.PowerPacks;
using System;
using System.Drawing;
using System.Runtime.InteropServices;
using System.Windows.Forms;
public class DataRepeaterItemHelper : NativeWindow
{
private DataRepeaterItem item;
private const int WM_NCPAINT = 0x85;
[DllImport("user32.dll")]
static extern IntPtr GetWindowDC(IntPtr hWnd);
[DllImport("user32.dll")]
static extern int ReleaseDC(IntPtr hWnd, IntPtr hDC);
public DataRepeaterItemHelper(DataRepeaterItem repeaterItem)
{
item = repeaterItem;
this.AssignHandle(item.Handle);
}
protected override void WndProc(ref Message m)
{
base.WndProc(ref m);
if (m.Msg == WM_NCPAINT)
{
var hdc = GetWindowDC(m.HWnd);
using (var g = Graphics.FromHdcInternal(hdc))
using (var p = new Pen(item.BackColor, 1))
g.DrawLine(p, 0, item.Height - 1, item.Width - 1, item.Height - 1);
ReleaseDC(m.HWnd, hdc);
}
}
}
然后我们处理 DataRepeater
的 DrawItem
事件并检查我们是否没有为 e.DataRepeaterItem
创建一个 DataRepeaterItemHelper
我们创建一个。它有助于绘制与项目背景颜色相同的颜色的分隔符。同样,在将数据加载到 DataRepeater
之后,我们应该为第一个没有触发 DrawItem
事件的项目创建 DataRepeaterItemHelper
。为了跟踪我们为他们创建的 DataRepeaterItemHelper
项目,我们将处理过的项目保存在 List<DataRepeaterItem>
:
new List<DataRepeaterItem> items = new List<DataRepeaterItem>();
void HandleItem(DataRepeaterItem item)
{
if (items.Contains(item))
return;
var handler = new DataRepeaterItemHelper(item);
items.Add(item);
}
private void Form1_Load(object sender, EventArgs e)
{
//Load data and put data in dataRepeater1.DataSource
var db = new TestDBEntities();
this.dataRepeater1.DataSource = db.Category.ToList();
this.dataRepeater1.Controls.OfType<DataRepeaterItem>().ToList()
.ForEach(item => HandleItem(item));
this.dataRepeater1.DrawItem += dataRepeater1_DrawItem;
}
void dataRepeater1_DrawItem(object sender, DataRepeaterItemEventArgs e)
{
HandleItem(e.DataRepeaterItem);
}
结果如下:
注:
- 应用解决方案时,不要忘记将
Form1_Load
事件附加到表单的Load
事件。您不需要将dataRepeater1_DrawItem
附加到DrawItem
事件。它已使用代码附加在Form1_Load
中。 - 您可以将逻辑封装在派生的
DataRepeater
控件中。