2010-09-09 45 views
2

我正在爲Windows Mobile應用程序創建從ListView繼承的所有者繪製的控件。我使用Graphics.DrawString來寫出一個雙行文本字符串(使用.NET CF 3.5)。問題是一些項目有特別長的文字,不適合這兩行。谷歌搜索找到了使用MeasureString和手動截斷我的字符串的方法,但這隻適用於單行字符串。有沒有什麼辦法可以在這裏得到這些省略號,或者我是否必須接受剪裁的文本或者重新設計才能使用一行代碼? (既不是一個致命弱點,但是橢圓肯定會很高興。)精簡框架:用橢圓繪製多行字符串

回答

2

是的,你可以得到省略號來顯示,但你必須做一些P /調用(什麼新內容?):

public static void DrawText(Graphics gfx, string text, Font font, Color color, int x, int y, int width, int height) 
{ 
IntPtr hdcTemp = IntPtr.Zero; 
IntPtr oldFont = IntPtr.Zero; 
IntPtr currentFont = IntPtr.Zero; 

try 
{ 
    hdcTemp = gfx.GetHdc(); 
    if (hdcTemp != IntPtr.Zero) 
    { 
    currentFont = font.ToHfont(); 
    oldFont = NativeMethods.SelectObject(hdcTemp, currentFont); 

    NativeMethods.RECT rect = new NativeMethods.RECT(); 
    rect.left = x; 
    rect.top = y; 
    rect.right = x + width; 
    rect.bottom = y + height; 

    int colorRef = color.R | (color.G << 8) | (color.B << 16); 
    NativeMethods.SetTextColor(hdcTemp, colorRef); 

    NativeMethods.DrawText(hdcTemp, text, text.Length, ref rect, NativeMethods.DT_END_ELLIPSIS | NativeMethods.DT_NOPREFIX); 
    } 
} 
finally 
{ 
    if (oldFont != IntPtr.Zero) 
    { 
    NativeMethods.SelectObject(hdcTemp, oldFont); 
    } 

    if (hdcTemp != IntPtr.Zero) 
    { 
    gfx.ReleaseHdc(hdcTemp); 
    } 

    if (currentFont != IntPtr.Zero) 
    { 
    NativeMethods.DeleteObject(currentFont); 
    } 
} 
} 

NativeMethods是一個擁有我所有本機調用的類。其中包括:

internal const int DT_END_ELLIPSIS = 32768; 
internal const int DT_NOPREFIX = 2048; 


[DllImport("coredll.dll", SetLastError = true)] 
internal static extern int DrawText(IntPtr hDC, string Text, int nLen, ref RECT pRect, uint uFormat); 

[DllImport("coredll.dll", SetLastError = true)] 
internal static extern int SetTextColor(IntPtr hdc, int crColor); 

[DllImport("coredll.dll", SetLastError = true)] 
internal static extern IntPtr SelectObject(IntPtr hDC, IntPtr hObject); 

[DllImport("coredll.dll", SetLastError = true)] 
[return: MarshalAs(UnmanagedType.Bool)] 
internal static extern bool DeleteObject(IntPtr hObject); 

[StructLayout(LayoutKind.Sequential)] 
internal struct RECT 
{ 
public int left; 
public int top; 
public int right; 
public int bottom; 

} 
+0

我擔心會涉及P/Invoke。但很好的答案! – 2010-09-15 13:39:24