2010-06-11 4 views
1

나는 사용자 정의한 패널이 있습니다. 텍스트를 표시하는 데 사용합니다. 하지만 때로는 텍스트가 너무 길어서 다음 줄로 넘어갑니다. 모든 텍스트를 표시하도록 패널의 크기를 자동으로 조정할 수있는 방법이 있습니까?패널에서 텍스트의 높이 찾기

저는 C#과 Visual Studio 2008 및 컴팩트 프레임 워크를 사용하고 있습니다.
(참고 :.. HintBox 패널에서 상속 내 자신의 클래스입니다 그래서 필요에 수정할 수 있습니다)

public void DataItemClicked(ShipmentData shipmentData) 
{ 
    // Setup the HintBox 
    if (_dataItemHintBox == null) 
     _dataItemHintBox = HintBox.GetHintBox(ShipmentForm.AsAnObjectThatCanOwn(), 
              _dataShipSelectedPoint, 
              new Size(135, 50), shipmentData.LongDesc, 
              Color.LightSteelBlue); 


    _dataItemHintBox.Location = new Point(_dataShipSelectedPoint.X - 100, 
              _dataShipSelectedPoint.Y - 50); 
    _dataItemHintBox.MessageText = shipmentData.LongDesc; 
    // It would be nice to set the size right here 
    _dataItemHintBox.Size = _dataItemHintBox.MethodToResizeTheHeightToShowTheWholeString() 
    _dataItemHintBox.Show(); 

} 
여기

내가의 크기를 조정 걸려 코드입니다

그의 코드 예제가 필자가 필요로하는 것과 가장 비슷하기 때문에 (그 코드가 작동하는 것처럼 보입니다) Will Marcouiller에게 답을 알려 드리겠습니다. 그러나 이것은 내가 사용할 것으로 생각됩니다.

public static class CFMeasureString 
{ 
    private struct Rect 
    { 
     public readonly int Left, Top, Right, Bottom; 
     public Rect(Rectangle r) 
     { 
      this.Left = r.Left; 
      this.Top = r.Top; 
      this.Bottom = r.Bottom; 
      this.Right = r.Right; 
     } 
    } 

    [DllImport("coredll.dll")] 
    static extern int DrawText(IntPtr hdc, string lpStr, int nCount, 
           ref Rect lpRect, int wFormat); 
    private const int DT_CALCRECT = 0x00000400; 
    private const int DT_WORDBREAK = 0x00000010; 
    private const int DT_EDITCONTROL = 0x00002000; 

    static public Size MeasureString(this Graphics gr, string text, Rectangle rect, 
            bool textboxControl) 
    { 
     Rect bounds = new Rect(rect); 
     IntPtr hdc = gr.GetHdc(); 
     int flags = DT_CALCRECT | DT_WORDBREAK; 
     if (textboxControl) flags |= DT_EDITCONTROL; 
     DrawText(hdc, text, text.Length, ref bounds, flags); 
     gr.ReleaseHdc(hdc); 
     return new Size(bounds.Right - bounds.Left, bounds.Bottom - bounds.Top + 
         (textboxControl ? 6 : 0)); 
    } 
} 

텍스트를 그리기 위해 os 수준 호출을 사용합니다. P-Invoking을 사용하면 필요한 기능을 얻을 수 있습니다 (다중 줄 바꿈). 이 메서드는 여백을 포함하지 않습니다. 텍스트가 차지하는 실제 공간.

이 코드를 작성하지 않았습니다. 나는 http://www.mobilepractices.com/2007/12/multi-line-graphicsmeasurestring.html에서 그것을 얻었다. 그 블로그 포스트는 나의 정확한 문제와이 결함을 가지고 있었다. (비록 내가 그것을 확장 메소드로 만들기 위해 약간의 비틀기를 만들었지 만)

+0

+1 Compact Framework 질문은 전체 프레임 워크 자체와 다른 해결책을 가져올 수 있습니다. –

답변

4

Graphics.MeasureString() 메소드를 사용할 수 있습니다.

패널에 텍스트를 지정하는 코드 샘플을 사용하면 필요할 경우 MeasureString() 메서드를 사용하여 코드 샘플을 제공 할 수 있습니다.

Graphics.MeasureString() 메서드가 Compact Framework의 일부인지 여부를 알 수있는 방법이 없습니다. 링크 된 페이지에는이 메서드가 없다는 것입니다. 내가 당신을 위해 샘플을 쓰기 위해 찾는 동안 나는 다른 텍스트 크기 관련 질문에 대답

편집 # 1

Here's a link. =)

편집 # 질문 2

Here's another link related. (다음 편집 샘플 코드 = P.)

편집 # 3

public void DataItemClicked(ShipmentData shipmentData) { 
    // Setup the HintBox 
    if (_dataItemHintBox == null) 
     _dataItemHintBox = HintBox.GetHintBox(ShipmentForm.AsAnObjectThatCanOwn(), 
              _dataShipSelectedPoint, 
              new Size(135, 50), shipmentData.LongDesc, 
              Color.LightSteelBlue); 

    // Beginning to measure the size of the string shipmentData.LongDesc here. 

    // Assuming that the initial font size should be 30pt. 
    Single fontSize = 30.0F; 
    Font f = new Font("fontFamily", fontSize, FontStyle.Regular); 

    // The Panel.CreateGraphics method provides the instance of Graphics object 
    // that shall be used to compare the string size against. 
    using (Graphics g = _dataItemHintBox.CreateGraphics()) { 
     while (g.MeasureString(shipmentData.LongDesc, f).Width > _dataItemHintBox.Size.Width - 5) { 
      --fontSize; 
      f = new Font("fontFamily", fontSize, FontStyle.Regular); 
     } 
    } 

    // Font property inherited from Panel control. 
    _dataItemHintBox.Font = f; 

    // End of font resizing to fit the HintBox panel. 

    _dataItemHintBox.Location = new Point(_dataShipSelectedPoint.X - 100, 
              _dataShipSelectedPoint.Y - 50); 
    _dataItemHintBox.MessageText = shipmentData.LongDesc; 
    // It would be nice to set the size right here 
    _dataItemHintBox.Size = _dataItemHintBox.MethodToResizeTheHeightToShowTheWholeString() 
    _dataItemHintBox.Show(); 
} 

면책 조항 :이 코드는 테스트 내 머리 위로 떨어져있다되지 않은. 일부 변경 사항은 테스트를 위해 필수적 일 수 있습니다. 이것은 당신이 성취하고자하는 것을 달성하기위한 지침을 제공합니다. 이 작업을 수행하는 더 좋은 방법이있을 수 있지만이 작업이 효과가 있다는 것을 알고 있습니다. 자, 알고리즘은 다른 답변에서 볼 수 있듯이 작동합니다.대신 라인의

: 왜이 ​​

var fontSize = _dataItemHintBox.Font.Size; 

입니다 :

SizeF fontSize = 30.0F; 

당신은뿐만 아니라 다음을 수행 할 수?

Font.Size 속성은 읽기 전용 때문입니다. 따라서 Font.Size이 변경 될 때마다 System.Drawing.Font 클래스의 새 인스턴스를 만들어야합니다. 당신의 비교

라인을 갖는 대신 : 당신은 또한 할 수

while (g.MeasureString(shipmentData.LongDesc, f)...) 

을 :

while (g.MeasureString(shipmentData.LongDesc, _dataItemHintBox.Font)...) 

이 두 번째 Font 클래스 인스턴스에 대한 필요성을 무효화 것, 즉 을 f를 .

수신 한 피드백에 내 현실감을 반영하도록 샘플을 바꿀 수 있으므로 피드백을 보내 주시기 바랍니다. =)

이 도움이 되었기를 바랍니다. =)

+0

Graphics.MeasureString()은 압축 프레임 워크의 일부입니다. 제 임무는 간단합니다. 나는 내 패널을 가지고 있고 텍스트를 설정했다. 나는 내 질문에 코드를 추가 할 것이다. Paint 메서드에서 크기를 조정하고 싶지 않으므로 Graphics 인스턴스를 어떻게 든 만들 필요가 있습니다. – Vaccano

+2

'using'문 안에 control.CreateGraphics()를 사용하십시오. – bbudge

+0

당신의 지속적인 관심을 가져 주셔서 감사합니다,하지만 Compact Framework에서 메서드에 너비를 제공 할 수 없기 때문에 적어도 MeasureString을 사용하면 가능하다는 것을 모릅니다. 내 자신의 단어 배치 알고리즘을 만들어야 할 것입니다. 복잡하고 버그가 발생하기 쉽습니다. – Vaccano

2

TextRenderer.MeasureText 과부하 중 어느 것이 든 당신에게 적합합니다. 이 함수를 사용하면 문자열의 실제 렌더링 크기를 결정하고 이에 따라 패널 크기를 조정할 수 있습니다.

당신은 당신이 당신의 e.Graphics 개체의 MeasureString 기능을 사용할 수는 Paint 이벤트 내부 측정하기 위해 노력하고 있지만, Paint 내부 크기를 조정하는 것은 현명하지 않습니다 경우. TextRenderer을 사용하면 CreateGraphics()Graphics 개체를 만들고 완료 할 때 처리하지 않아도됩니다. TextRenderer 이후

컴팩트 프레임 워크에서 지원되지 않습니다

편집, 당신은 Graphics 객체에 MeasureString() 기능을 사용해야합니다 (제가 질문을 처음봤을 때 태그를 놓쳤다). 다음과 같은 것 :

public Size GetStringSize(string text) 
{ 
    using(Graphics g = yourPanel.CreateGraphics()) 
    { 
     return g.MeasureString(text, yourPanel.Font); 
    } 
} 
+0

아아, TextRenderer는 압축 프레임 워크의 일부가 아닙니다. 그러나 그것은 정상적인 .net 문제에서이 문제가 발생하는 것을 알면 좋습니다. – Vaccano

+0

예제 코드를 보내 주셔서 감사합니다. 그러나 게시 한 두 번째 MeasureString은 Compact Framework의 일부가 아닙니다. 이 링크는 처음 사용했던 것만 지원된다는 것을 보여줍니다 (http://msdn.microsoft.com/en-us/library/system.drawing.graphics.measurestring%28VS.90%29.aspx) (모바일에서 표시됨 장치 아이콘) – Vaccano

+0

@Vaccano : 업데이트했습니다. –