how can I remove the bottom border line of data control item in DataRepeater
control:
The separator which you see in DataRepeater
control between items, is a drawing on non-client area of DataRepeaterItem
control.
You can find those DataRepeaterItem
and handle those WM_NCPAINT
messages and draw a line with the same color as item BackColor
or any other color which you want from (0, Height-1)
to (Width-1, Height-1)
.
Implementation
To do so, we create a class deriving from NativeWindow
which enables us to handle messages of another window, if we assign handle of other window to it:
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);
}
}
}
Then we handle DrawItem
event of DataRepeater
and check if we didn't have created a DataRepeaterItemHelper
for e.DataRepeaterItem
we create one. It helps drawing the separator with the same color as item back color. Also after loading data into DataRepeater
we should create DataRepeaterItemHelper
for the first items which DrawItem
event doesn't fire for them. To keep track of items which we created a DataRepeaterItemHelper
for them, we keep handled items in a 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);
}
And here is the result:
Note:
Form1_Load
event to Load
event of form. You don't need to attach dataRepeater1_DrawItem
to DrawItem
event. It's been attached in Form1_Load
using code.DataRepeater
control.