2010-07-18 6 views
4

이것은 C# 데스크톱 응용 프로그램입니다. 내 ListBoxDrawStyle 속성은 OwnerDrawFixed으로 설정됩니다.ListBox에 대한 DrawItem 무시 - 선택되지 않은 항목은 다시 그려지지 않습니다.

문제 : 다른 글꼴로 텍스트를 그리려면 DrawItem을 무시하고 작동합니다. 그러나 런타임에 양식의 크기를 조절하기 시작하면 선택한 항목이 올바르게 그려 지지만 나머지는 다시 그려지지 않으므로 선택하지 않은 항목에 대해 텍스트가 손상 될 수 있습니다. 또한

private void listDevices_DrawItem(object sender, DrawItemEventArgs e) 
{ 
    e.DrawBackground(); 

    string textDevice = ((ListBox)sender).Items[e.Index].ToString(); 

    e.Graphics.DrawString(textDevice, 
     new Font("Ariel", 15, FontStyle.Bold), new SolidBrush(Color.Black), 
     e.Bounds, StringFormat.GenericDefault); 


    // Figure out where to draw IP 
    StringFormat copy = new StringFormat(
     StringFormatFlags.NoWrap | 
     StringFormatFlags.MeasureTrailingSpaces 
    ); 
    copy.SetMeasurableCharacterRanges(new CharacterRange[] {new CharacterRange(0, textDevice.Length)}); 

    Region[] regions = e.Graphics.MeasureCharacterRanges(
     textDevice, new Font("Ariel", 15, FontStyle.Bold), e.Bounds, copy); 

    int width = (int)(regions[0].GetBounds(e.Graphics).Width); 
    Rectangle rect = e.Bounds; 
    rect.X += width; 
    rect.Width -= width; 

    // draw IP 
    e.Graphics.DrawString(" 255.255.255.255", 
     new Font("Courier New", 10), new SolidBrush(Color.DarkBlue), 
     rect, copy); 

    e.DrawFocusRectangle(); 
} 

listDevices.Items.Add("Device001"); 
listDevices.Items.Add("Device002"); 

, 폼 크기 조정에 깜박이는 제대로 그려진 아이템합니다 (하나를 선택) :

여기 내 코드입니다. 아니 문제 야하지만, 사람이 TNX

답변

5

가 크기 조정 이벤트에 다음 코드를 넣어 이유를 .... 알고있는 경우 :이 모든 것이 다시 그려되도록해야

private void listDevices_Resize(object sender, EventArgs e) { 
    listDevices.Invalidate(); 
} 

.

깜박임을 멈추려면 이중 버퍼링이 필요합니다.

이 작업을 수행하려면 목록 상자에서 파생 된 새로운 클래스를 만들고, 생성자에 다음을 넣어 :

this.SetStyle(ControlStyles.OptimizedDoubleBuffer, true); 

을하거나 코드 파일에이를 붙여 넣습니다

using System.Windows.Forms; 

namespace Whatever { 
    public class DBListBox : ListBox { 
     public DBListBox(): base() { 
      this.DoubleBuffered = true; 
      // OR 
      // this.SetStyle(ControlStyles.OptimizedDoubleBuffer, true); 
     } 
    } 
} 

것은 교체 " 프로젝트가 사용하는 네임 스페이스에 무엇이든 "을 사용하거나 더 유용한 것으로 만듭니다. 컴파일 한 후에는 폼 디자이너에 DBListBox를 추가 할 수 있어야합니다.

+0

기본 (다시 그리기) 문제 주셔서 감사합니다 - 작동합니다. Double Buffering은 깜박 거리는 데 도움이되지 않았습니다. – flamey

4

문제를 재현합니다. 코드에는 몇 가지 실수가 있습니다. 글꼴 이름은 "Arial"입니다. rect.Width를 조정하면 안됩니다. 글꼴, 브러시 및 영역에서 Dispose()를 호출하는 것을 잊지 마십시오. 그러나 그들은 행동을 설명하지 않습니다. 텍스트가 제대로 업데이트되지 못하게하는 클리핑 영역에는 문제가 있습니다. 그게 어디서 발생하는지, 그래픽 객체 상태는 괜찮은지 모르겠다.

Graphics.DrawString()은 매우 문제가있는 메서드이므로 실제로 사용하지 않아야합니다. ListBox를 포함한 모든 Windows Forms 컨트롤에는 TextRenderer.DrawText()가 사용됩니다. 그걸 사용하면 문제가 해결됩니다. 나는 측정이 더 어렵다는 것을 안다. 고정 된 오프셋으로 IP 주소를 표시함으로써이를 해결할 수있다. 너무 좋아 보이는군요, 그들은 그런 식으로 칼럼에 줄을 서 있습니다.

e.DrawBackground()를 사용하기 때문에 깜박입니다. 기존 텍스트를 지우면 텍스트를 바로 그립니다. 이중 버퍼링으로 해결할 수 있다고 생각하지 않습니다. 배경을 그리지 않아도 전체 항목을 그려야합니다. 글꼴 크기가 큰 텍스트의 정확한 크기를 얻을 수 없다면 문제가 될 수 있습니다. 해결 방법은 먼저 비트 맵에 그리는 것입니다.

+0

정말 고맙게 생각합니다. 당신이 지적한 문제들을 고쳐 줄 것입니다. 그러나 나는 지금 당장 깜박 거릴 것이라고 생각합니다. 이것은 개인적인 사용을위한 작은 도구입니다. – flamey