2013-04-30 69 views
4

如何更改richtextbox的所有內容的字體而不會丟失格式?更改richtextbox的字體而不會丟失格式化

我想使用

rtb.SelectAll(); 
rtb.SelectionFont = new Font(fontName,...); 

但字體構造必須採取除了字體類型無論是字體樣式(粗體,斜體,...)或字體大小。 因此,使用這將改變richtextbox的所有內容的風格/大小。

當然這同樣適用於richtextbox中的任何選擇。

+1

見(http://stackoverflow.com/q/5325918/719186)。最終,禁令可能是最好的解決方案。 – LarsTech 2013-04-30 18:21:49

+0

你可以在pinvoking更清晰? – Jerry 2013-04-30 18:27:20

回答

6

這是我以前用過的RichTextBox。從這兒發現的堆棧溢出代碼和互聯網拼接在一起,在大:

public class RichBox : RichTextBox { 
    private const UInt32 CFM_BOLD = 0x00000001; 
    private const UInt32 CFM_ITALIC = 0x00000002; 
    private const UInt32 CFM_UNDERLINE = 0x00000004; 
    private const UInt32 CFM_STRIKE = 0x00000008; 
    private const UInt32 CFM_FACE = 0x20000000; 
    private const UInt32 CFM_SIZE = 0x80000000; 

    private const int WM_PAINT = 0xF; 
    private const int WM_SETREDRAW = 0xB; 
    private const int WM_USER = 0x400; 

    private const int EM_SETCHARFORMAT = (WM_USER + 68); 
    private const int SCF_SELECTION = 0x0001; 
    private const int EM_GETEVENTMASK = WM_USER + 59; 
    private const int EM_SETEVENTMASK = WM_USER + 69; 
    private const int EM_GETSCROLLPOS = WM_USER + 221; 
    private const int EM_SETSCROLLPOS = WM_USER + 222; 

    [StructLayout(LayoutKind.Sequential)] 
    private struct CHARFORMAT { 
    public int cbSize; 
    public uint dwMask; 
    public uint dwEffects; 
    public int yHeight; 
    public int yOffset; 
    public int crTextColor; 
    public byte bCharSet; 
    public byte bPitchAndFamily; 
    [MarshalAs(UnmanagedType.ByValArray, SizeConst = 32)] 
    public char[] szFaceName; 
    public short wWeight; 
    public short sSpacing; 
    public int crBackColor; 
    public int LCID; 
    public uint dwReserved; 
    public short sStyle; 
    public short wKerning; 
    public byte bUnderlineType; 
    public byte bAnimation; 
    public byte bRevAuthor; 
    } 

    [DllImport("kernel32.dll", CharSet = CharSet.Auto)] 
    private static extern IntPtr LoadLibrary(string lpFileName); 

    [DllImport("user32", CharSet = CharSet.Auto)] 
    private static extern int SendMessage(IntPtr hWnd, int msg, int wParam, ref CHARFORMAT lParam); 

    [DllImport("user32.dll")] 
    private static extern IntPtr SendMessage(IntPtr hWnd, Int32 wMsg, Int32 wParam, ref Point lParam); 

    [DllImport("user32.dll")] 
    private static extern IntPtr SendMessage(IntPtr hWnd, Int32 wMsg, Int32 wParam, IntPtr lParam); 

    private bool frozen = false; 
    private Point lastScroll = Point.Empty; 
    private IntPtr lastEvent = IntPtr.Zero; 
    private int lastIndex = 0; 
    private int lastWidth = 0; 

    protected override CreateParams CreateParams { 
    get { 
     var cp = base.CreateParams; 
     if (LoadLibrary("msftedit.dll") != IntPtr.Zero) { 
     cp.ClassName = "RICHEDIT50W"; 
     } 
     return cp; 
    } 
    } 

    [Browsable(false)] 
    [DefaultValue(typeof(bool), "False")] 
    [DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)] 
    public bool FreezeDrawing { 
    get { return frozen; } 
    set { 
     if (value != frozen) { 
     frozen = value; 
     if (frozen) { 
      this.SuspendLayout(); 
      SendMessage(this.Handle, WM_SETREDRAW, 0, IntPtr.Zero); 
      SendMessage(this.Handle, EM_GETSCROLLPOS, 0, ref lastScroll); 
      lastEvent = SendMessage(this.Handle, EM_GETEVENTMASK, 0, IntPtr.Zero); 
      lastIndex = this.SelectionStart; 
      lastWidth = this.SelectionLength; 
     } else { 
      this.Select(lastIndex, lastWidth); 
      SendMessage(this.Handle, EM_SETEVENTMASK, 0, lastEvent); 
      SendMessage(this.Handle, EM_SETSCROLLPOS, 0, ref lastScroll); 
      SendMessage(this.Handle, WM_SETREDRAW, 1, IntPtr.Zero); 
      this.Invalidate(); 
      this.ResumeLayout(); 
     } 
     } 
    } 
    } 

    [Browsable(false)] 
    [DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)] 
    public Font CurrentFont { 
    get { 
     Font result = this.Font; 
     if (this.SelectionLength == 0) { 
     result = SelectionFont; 
     } else { 
     using (RichBox rb = new RichBox()) { 
      rb.FreezeDrawing = true; 
      rb.SelectAll(); 
      rb.SelectedRtf = this.SelectedRtf; 
      rb.Select(0, 1); 
      result = rb.SelectionFont; 
     } 
     } 
     return result; 
    } 
    } 

    [Browsable(false)] 
    [DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)] 
    public string SelectionFontName { 
    get { return CurrentFont.FontFamily.Name; } 
    set { 
     CHARFORMAT cf = new CHARFORMAT(); 
     cf.cbSize = Marshal.SizeOf(cf); 
     cf.szFaceName = new char[32]; 
     cf.dwMask = CFM_FACE; 
     value.CopyTo(0, cf.szFaceName, 0, Math.Min(31, value.Length)); 
     IntPtr lParam = Marshal.AllocCoTaskMem(Marshal.SizeOf(cf)); 
     Marshal.StructureToPtr(cf, lParam, false); 
     SendMessage(this.Handle, EM_SETCHARFORMAT, SCF_SELECTION, lParam); 
    } 
    } 

    [Browsable(false)] 
    [DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)] 
    public float SelectionFontSize { 
    get { return CurrentFont.Size; } 
    set { 
     CHARFORMAT cf = new CHARFORMAT(); 
     cf.cbSize = Marshal.SizeOf(cf); 
     cf.dwMask = CFM_SIZE; 
     cf.yHeight = Convert.ToInt32(value * 20); 
     IntPtr lParam = Marshal.AllocCoTaskMem(Marshal.SizeOf(cf)); 
     Marshal.StructureToPtr(cf, lParam, false); 
     SendMessage(this.Handle, EM_SETCHARFORMAT, SCF_SELECTION, lParam); 
    } 
    } 

    [Browsable(false)] 
    [DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)] 
    public bool SelectionBold { 
    get { return CurrentFont.Bold; } 
    set { 
     CHARFORMAT cf = new CHARFORMAT(); 
     cf.cbSize = Marshal.SizeOf(cf); 
     cf.dwMask = CFM_BOLD; 
     cf.dwEffects = value ? CFM_BOLD : 0; 
     IntPtr lParam = Marshal.AllocCoTaskMem(Marshal.SizeOf(cf)); 
     Marshal.StructureToPtr(cf, lParam, false); 
     SendMessage(this.Handle, EM_SETCHARFORMAT, SCF_SELECTION, lParam); 
    } 
    } 

    [Browsable(false)] 
    [DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)] 
    public bool SelectionItalic { 
    get { return CurrentFont.Italic; } 
    set { 
     CHARFORMAT cf = new CHARFORMAT(); 
     cf.cbSize = Marshal.SizeOf(cf); 
     cf.dwMask = CFM_ITALIC; 
     cf.dwEffects = value ? CFM_ITALIC : 0; 
     IntPtr lParam = Marshal.AllocCoTaskMem(Marshal.SizeOf(cf)); 
     Marshal.StructureToPtr(cf, lParam, false); 
     SendMessage(this.Handle, EM_SETCHARFORMAT, SCF_SELECTION, lParam); 
    } 
    } 

    [Browsable(false)] 
    [DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)] 
    public bool SelectionStrikeout { 
    get { return CurrentFont.Strikeout; } 
    set { 
     CHARFORMAT cf = new CHARFORMAT(); 
     cf.cbSize = Marshal.SizeOf(cf); 
     cf.dwMask = CFM_STRIKE; 
     cf.dwEffects = value ? CFM_STRIKE : 0; 
     IntPtr lParam = Marshal.AllocCoTaskMem(Marshal.SizeOf(cf)); 
     Marshal.StructureToPtr(cf, lParam, false); 
     SendMessage(this.Handle, EM_SETCHARFORMAT, SCF_SELECTION, lParam); 
    } 
    } 

    [Browsable(false)] 
    [DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)] 
    public bool SelectionUnderline { 
    get { return CurrentFont.Underline; } 
    set { 
     CHARFORMAT cf = new CHARFORMAT(); 
     cf.cbSize = Marshal.SizeOf(cf); 
     cf.dwMask = CFM_UNDERLINE; 
     cf.dwEffects = value ? CFM_UNDERLINE : 0; 
     IntPtr lParam = Marshal.AllocCoTaskMem(Marshal.SizeOf(cf)); 
     Marshal.StructureToPtr(cf, lParam, false); 
     SendMessage(this.Handle, EM_SETCHARFORMAT, SCF_SELECTION, lParam); 
    } 
    } 
} 

它增加了新的特性,如SelectionBold,SelectionItalic等在那裏你可以應用屬性,而不是失去文本的其他格式。

+0

完美!謝謝 – Jerry 2013-04-30 20:20:36

+0

嗨LarsTech,有時當我改變包含粗體的大選擇的字體時,粗體會丟失。當我點擊ctrl + Z一次時,粗體被恢復。你有一個想法,爲什麼會發生這種情況?謝謝 – Jerry 2013-06-11 21:49:12

+1

@Jerry如果您要更改'SelectionFont'屬性,那麼是的,您正在告訴文檔將所有字體屬性替換爲新字體。要更改字體但保留屬性,請改爲使用「SelectionFontName」或「SelectionFontSize」屬性。另外,Ctrl-Z是撤消功能。 – LarsTech 2013-06-17 13:25:24

0

您可以傳入所需的任何參數的新值,並使用rtb屬性來保留其他值。例如,如果你想改變font family但希望保留font size,這是你會怎麼做:

rtb.SelectionFont = new Font(fontName, rtb.Font.Size); 

這將SelectionFont家庭改變fontName但保留的字體大小。對於其他重載,您可以遵循相同的模式。

+1

但是,如果有不同的字體大小,這將無法正常工作。 – Jerry 2013-04-30 18:15:07

+0

你是什麼意思不同的字體大小?解釋你想要達成的目標,然後或許我們可以搞清楚。 – PoweredByOrange 2013-04-30 18:18:27

+0

具有不同字體大小的不同文本。無論如何,即使你的答案導致字體樣式改變。 – Jerry 2013-04-30 18:20:33

2

通過使用現有的richtextbox字體屬性,您可以傳遞新的字體名稱,同時保持其他值不變。爲了改變選中的文本隻字體的名稱,你需要做的:

if (rtb.SelectionFont !=null) 
    rtb.SelectionFont = new Font(fontName, rtb.SelectionFont.Size, rtb.SelectionFont.Style); 

注意,上面的代碼只會工作,如果所有選定的文本具有相同的格式(字體大小,樣式等)。這可以通過首先檢查SelectionFont屬性來檢測,如果選擇包含樣式組合,則它將爲null。

現在要更改richtextbox所有內容的字體名稱,同時保持其他格式不變,您需要遍歷richtextbox的所有字符並逐個應用字體名稱。

for (int i = 0; i < rtb.TextLength; i++) 
{ 
    rtb.Select(i, 1); 
    rtb.SelectionFont = new Font(fontName, rtb.SelectionFont.Size, rtb.SelectionFont.Style); 
} 
0
Private Sub changeFont(ByVal fontz As FontStyle, getStr As RichTextBox) 
    Dim currentFont As System.Drawing.Font = txt.SelectionFont 
    Dim newFontStyle As System.Drawing.FontStyle 
    newFontStyle = fontz 
    getStr.SelectionFont = New Font(currentFont.FontFamily, currentFont.Size, newFontStyle) 
End Sub 

這將改變所選文本的字體屬性。
樣品:[?我如何保持改變任何一個元素時富文本格式(粗體/斜體/等)

changeFont(FontStyle.Italic, [textbox_name]) 
相關問題