2016-09-14 5 views

답변

2

는 항목 사이 DataRepeater 컨트롤에 표시되는 분리하는가에 그리기입니다 비 클라이언트 영역 DataRepeaterItem 통제.

당신은 그 DataRepeaterItem를 찾아 그 WM_NCPAINT 메시지를 처리하고 항목 BackColor과 같은 색 또는 (0, Height-1)에서 (Width-1, Height-1) 할 다른 색상으로 선을 그릴 수 있습니다.

구현

이를 위해, 우리는 우리가 다른 윈도우의 핸들을 할당하면 우리가 다른 윈도우의 메시지를 처리 ​​할 수 ​​NativeWindow에서 클래스 유도 만들 :

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으로 처리하고 우리가 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); 
} 

그리고 여기 결과입니다

enter image description here

참고 :

  • 해결 방법을 적용 할 때 이벤트를에 첨부하는 것을 잊지 마세요. 양식이벤트. dataRepeater1_DrawItem ~ DrawItem 이벤트를 첨부 할 필요가 없습니다. 코드를 사용하여 Form1_Load에 첨부되었습니다.
  • 로직을 파생 된 DataRepeater 컨트롤에 캡슐화 할 수 있습니다.
+0

이 답변의 변형은 DataRepeater의 동적으로 채색되고 제거 할 수없는 테두리를 덮어 쓰는 경우에도 효과적이라는 것을 발견했습니다. – rileywhite