2014-03-13 7 views
0

나는 완전히 소유자가 그린 체크 박스가있는 TreeView 컨트롤이 있습니다 (DrawMode = TreeViewDrawMode.OwnerDrawAll).Ownerdrawn TreeView (WinForms)

내가하려는 것은 체크 박스 소유자를 그려서 회색 상태가되도록 할 수 있습니다. 나는 이것을 VisualStyleRenderer으로 사용하고 있습니다.

글리프와 체크 박스의 "히트 테스트 영역"이 알 수 없거나 변경 될 수 없기 때문에 확장/축소 글리프와 체크 박스를 항목 경계에 올바르게 배치해야 할 때 문제가 발생합니다.

해당 영역의 경계를 가져 오거나 기본 값을 사용자 정의 값으로 바꾸는 방법이 있습니까?

답변

1

같은 문제가 발생했습니다. 도면을 적절한 양만큼 상쇄해야합니다. 이는 예측 가능합니다.

내 그림은 내가 달력 컨트롤과 함께 사용되는 사용자 정의 트리의 여기가 당신이 필요로하는 것보다 여기에 아마도 더 많은,하지만 :

private void TreeViewControl_DrawNode(Object sender, DrawTreeNodeEventArgs e) 
{ 
    //What might seem like strange positioning/offset is to ensure that our custom drawing falls in 
    // line with where the base drawing would appear. Otherwise, click handlers (hit tests) fail 
    // to register properly if our custom-drawn checkbox doesn't fall within the expected coordinates. 

    Int32 boxSize = 16; 
    Int32 offset = e.Node.Parent == null ? 3 : 21; 
    Rectangle bounds = new Rectangle(new Point(e.Bounds.X + offset, e.Bounds.Y + 1), new Size(boxSize, boxSize)); 
    ControlPaint.DrawCheckBox(e.Graphics, bounds, e.Node.Checked ? ButtonState.Checked : ButtonState.Normal); 
    if (e.Node.Parent != null) 
    { 
     Color c = Color.Black; 
     String typeName = e.Node.Name.Remove(0, 4); 
     Object o = Enum.Parse(typeof(CalendarDataProvider.CalendarDataItemType), typeName); 
     if (o != null && (o is CalendarDataProvider.CalendarDataItemType)) 
      c = CalendarDataProvider.GetItemTypeColor((CalendarDataProvider.CalendarDataItemType)o); 
     bounds = new Rectangle(new Point(bounds.X + boxSize + 2, e.Bounds.Y + 1), new Size(13, 13)); 
     using (SolidBrush b = new SolidBrush(c)) 
      e.Graphics.FillRectangle(b, bounds); 
     e.Graphics.DrawRectangle(Pens.Black, bounds); 
     e.Graphics.DrawLine(Pens.Black, new Point(bounds.X + 1, bounds.Bottom + 1), new Point(bounds.Right + 1, bounds.Bottom + 1)); 
     e.Graphics.DrawLine(Pens.Black, new Point(bounds.Right + 1, bounds.Y + 1), new Point(bounds.Right + 1, bounds.Bottom + 1)); 
    } 
    Font font = new Font("Microsoft Sans Serif", 9f, e.Node.Parent == null ? FontStyle.Bold : FontStyle.Regular); 
    bounds = new Rectangle(new Point(bounds.X + boxSize + 2, e.Bounds.Y), new Size(e.Bounds.Width - offset - 2, boxSize)); 
    e.Graphics.DrawString(e.Node.Text, font, Brushes.Black, bounds); 
} 
+0

안녕하세요, 답장을 보내 주셔서 감사합니다! 사실, 지금은 당신의 코드 에서처럼하고 있습니다. 나는'boxSize'와'offset' 값을 런타임에 (즉, 일부 Win32 API를 사용하여) 읽을 수 있는지 궁금합니다. 왜냐하면 미래에이 값들이 변경 될 수 있고 UI가 어떤 식 으로든 손상 될 수 있기 때문입니다 ... – kris88

+0

I 내가 안전하다고 느끼기 때문에 그 길을 떠났다. 기본 컨트롤이 기본 Win32이기 때문에 기본 컨트롤이 그렇게 변경되지는 않습니다. 당신은 아마 그것에 도착할 수 있지만, 나는 그 번거 로움의 가치가 의심. – DonBoitnott