代码之家  ›  专栏  ›  技术社区  ›  NickAldwin

在RichTextBox中重置RTF?

  •  12
  • NickAldwin  · 技术社区  · 17 年前

    我正在尝试“重置”RichTextBox(WinForms,而不是WPF)中的格式。我以前使用过

    richTextBox.Text = richTextBox.Text;
    

    然而,这似乎突然让我失望了。现在不管我做什么 richTextBox.Text 到,它保留了一些rtf格式。

    我试过了

    richTextBox.Rtf = richTextBox.Text;
    

    编辑: 我已经让它工作了:

    string tempTxt = richTextBox.Text;
    richTextBox.Clear();
    richTextBox.Text = tempTxt;
    

    编辑2: 为了清楚起见,我希望删除所有格式,同时保留文本。看起来第一次编辑中的代码将会发布,除非其他人有更高效/更好的编码方式。

    编辑3:

    richTextBox.Text = richTextBox.Text.ToString();
    

    似乎不起作用,因为它仍然没有清除所有格式。我不喜欢上面第一次编辑中的方法的原因是它在清除文本框时使文本框“闪烁”,然后重新输入文本。似乎应该有一个richTextBox.ResetFormatting()方法,或者以某种方式访问相同的功能,因为Clear()方法除了简单地清除所有文本外,还可以进行某种形式的格式重置。

    总结如下:

    10 回复  |  直到 16 年前
        1
  •  27
  •   csharptest.net    16 年前

    遗憾的是,我已经尽了最大的努力将其精简为只需要的代码。它仍然很大,但会起作用。Net中的RichTextBox api非常有限,要想做任何事情,几乎必须进入Win32库。我已经围绕这个东西构建了一个完整的库,这样我就可以切换粗体,并确定粗体是否在整个选择中设置。

    用法:

    RichTextBox te = ...;
    te.ClearAllFormatting(new Font("Microsoft Sans Serif", 8.25f));
    

    吨代码:

    static class RichTextExtensions
    {
        public static void ClearAllFormatting(this RichTextBox te, Font font)
        {
            CHARFORMAT2 fmt = new CHARFORMAT2();
    
            fmt.cbSize = Marshal.SizeOf(fmt);
            fmt.dwMask = CFM_ALL2;
            fmt.dwEffects = CFE_AUTOCOLOR | CFE_AUTOBACKCOLOR;
            fmt.szFaceName = font.FontFamily.Name;
    
            double size = font.Size;
            size /= 72;//logical dpi (pixels per inch)
            size *= 1440.0;//twips per inch
    
            fmt.yHeight = (int)size;//165
            fmt.yOffset = 0;
            fmt.crTextColor = 0;
            fmt.bCharSet = 1;// DEFAULT_CHARSET;
            fmt.bPitchAndFamily = 0;// DEFAULT_PITCH;
            fmt.wWeight = 400;// FW_NORMAL;
            fmt.sSpacing = 0;
            fmt.crBackColor = 0;
            //fmt.lcid = ???
            fmt.dwMask &= ~CFM_LCID;//don't know how to get this...
            fmt.dwReserved = 0;
            fmt.sStyle = 0;
            fmt.wKerning = 0;
            fmt.bUnderlineType = 0;
            fmt.bAnimation = 0;
            fmt.bRevAuthor = 0;
            fmt.bReserved1 = 0;
    
            SendMessage(te.Handle, EM_SETCHARFORMAT, SCF_ALL, ref fmt);
        }
    
        private const UInt32 WM_USER = 0x0400;
        private const UInt32 EM_GETCHARFORMAT = (WM_USER + 58);
        private const UInt32 EM_SETCHARFORMAT = (WM_USER + 68);
        private const UInt32 SCF_ALL = 0x0004;
        private const UInt32 SCF_SELECTION = 0x0001;
    
        [DllImport("user32.dll", CharSet = CharSet.Auto, SetLastError = false)]
        static extern IntPtr SendMessage(IntPtr hWnd, UInt32 Msg, UInt32 wParam, ref CHARFORMAT2 lParam);
    
        [StructLayout(LayoutKind.Sequential, Pack = 4, CharSet = CharSet.Auto)]
        struct CHARFORMAT2
        {
            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.ByValTStr, SizeConst = 32)]
            public string szFaceName;
            public short wWeight;
            public short sSpacing;
            public int crBackColor;
            public int lcid;
            public int dwReserved;
            public short sStyle;
            public short wKerning;
            public byte bUnderlineType;
            public byte bAnimation;
            public byte bRevAuthor;
            public byte bReserved1;
        }
    
        #region CFE_
        // CHARFORMAT effects 
        const UInt32 CFE_BOLD = 0x0001;
        const UInt32 CFE_ITALIC = 0x0002;
        const UInt32 CFE_UNDERLINE = 0x0004;
        const UInt32 CFE_STRIKEOUT = 0x0008;
        const UInt32 CFE_PROTECTED = 0x0010;
        const UInt32 CFE_LINK = 0x0020;
        const UInt32 CFE_AUTOCOLOR = 0x40000000;            // NOTE: this corresponds to 
        // CFM_COLOR, which controls it 
        // Masks and effects defined for CHARFORMAT2 -- an (*) indicates
        // that the data is stored by RichEdit 2.0/3.0, but not displayed
        const UInt32 CFE_SMALLCAPS = CFM_SMALLCAPS;
        const UInt32 CFE_ALLCAPS = CFM_ALLCAPS;
        const UInt32 CFE_HIDDEN = CFM_HIDDEN;
        const UInt32 CFE_OUTLINE = CFM_OUTLINE;
        const UInt32 CFE_SHADOW = CFM_SHADOW;
        const UInt32 CFE_EMBOSS = CFM_EMBOSS;
        const UInt32 CFE_IMPRINT = CFM_IMPRINT;
        const UInt32 CFE_DISABLED = CFM_DISABLED;
        const UInt32 CFE_REVISED = CFM_REVISED;
    
        // CFE_AUTOCOLOR and CFE_AUTOBACKCOLOR correspond to CFM_COLOR and
        // CFM_BACKCOLOR, respectively, which control them
        const UInt32 CFE_AUTOBACKCOLOR = CFM_BACKCOLOR;
        #endregion
        #region CFM_
        // CHARFORMAT masks 
        const UInt32 CFM_BOLD = 0x00000001;
        const UInt32 CFM_ITALIC = 0x00000002;
        const UInt32 CFM_UNDERLINE = 0x00000004;
        const UInt32 CFM_STRIKEOUT = 0x00000008;
        const UInt32 CFM_PROTECTED = 0x00000010;
        const UInt32 CFM_LINK = 0x00000020;         // Exchange hyperlink extension 
        const UInt32 CFM_SIZE = 0x80000000;
        const UInt32 CFM_COLOR = 0x40000000;
        const UInt32 CFM_FACE = 0x20000000;
        const UInt32 CFM_OFFSET = 0x10000000;
        const UInt32 CFM_CHARSET = 0x08000000;
    
        const UInt32 CFM_SMALLCAPS = 0x0040;            // (*)  
        const UInt32 CFM_ALLCAPS = 0x0080;          // Displayed by 3.0 
        const UInt32 CFM_HIDDEN = 0x0100;           // Hidden by 3.0 
        const UInt32 CFM_OUTLINE = 0x0200;          // (*)  
        const UInt32 CFM_SHADOW = 0x0400;           // (*)  
        const UInt32 CFM_EMBOSS = 0x0800;           // (*)  
        const UInt32 CFM_IMPRINT = 0x1000;          // (*)  
        const UInt32 CFM_DISABLED = 0x2000;
        const UInt32 CFM_REVISED = 0x4000;
    
        const UInt32 CFM_BACKCOLOR = 0x04000000;
        const UInt32 CFM_LCID = 0x02000000;
        const UInt32 CFM_UNDERLINETYPE = 0x00800000;        // Many displayed by 3.0 
        const UInt32 CFM_WEIGHT = 0x00400000;
        const UInt32 CFM_SPACING = 0x00200000;      // Displayed by 3.0 
        const UInt32 CFM_KERNING = 0x00100000;      // (*)  
        const UInt32 CFM_STYLE = 0x00080000;        // (*)  
        const UInt32 CFM_ANIMATION = 0x00040000;        // (*)  
        const UInt32 CFM_REVAUTHOR = 0x00008000;
    
        const UInt32 CFE_SUBSCRIPT = 0x00010000;        // Superscript and subscript are 
        const UInt32 CFE_SUPERSCRIPT = 0x00020000;      //  mutually exclusive           
    
        const UInt32 CFM_SUBSCRIPT = (CFE_SUBSCRIPT | CFE_SUPERSCRIPT);
        const UInt32 CFM_SUPERSCRIPT = CFM_SUBSCRIPT;
    
        // CHARFORMAT "ALL" masks
        const UInt32 CFM_EFFECTS = (CFM_BOLD | CFM_ITALIC | CFM_UNDERLINE | CFM_COLOR |
                             CFM_STRIKEOUT | CFE_PROTECTED | CFM_LINK);
        const UInt32 CFM_ALL = (CFM_EFFECTS | CFM_SIZE | CFM_FACE | CFM_OFFSET | CFM_CHARSET);
    
        const UInt32 CFM_EFFECTS2 = (CFM_EFFECTS | CFM_DISABLED | CFM_SMALLCAPS | CFM_ALLCAPS
                            | CFM_HIDDEN | CFM_OUTLINE | CFM_SHADOW | CFM_EMBOSS
                            | CFM_IMPRINT | CFM_DISABLED | CFM_REVISED
                            | CFM_SUBSCRIPT | CFM_SUPERSCRIPT | CFM_BACKCOLOR);
    
        const UInt32 CFM_ALL2 = (CFM_ALL | CFM_EFFECTS2 | CFM_BACKCOLOR | CFM_LCID
                            | CFM_UNDERLINETYPE | CFM_WEIGHT | CFM_REVAUTHOR
                            | CFM_SPACING | CFM_KERNING | CFM_STYLE | CFM_ANIMATION);
        #endregion
    }
    

    我通过一个小型实用程序类使用了其中的大部分内容,该类对所有样式和字体更改都进行了包装。这样,您可以更改字体大小,而不更改字体名称等。

    class RichTextStyle
    {   
        private readonly Control _textEdit;
        private readonly CHARFORMAT2 _charFormat;
    
        public RichTextStyle(RichTextBox te)
        {
            _textEdit = te;
            _charFormat = new CHARFORMAT2();
            _charFormat.cbSize = Marshal.SizeOf(_charFormat);
            SendMessage(te.Handle, EM_GETCHARFORMAT, SCF_SELECTION, ref _charFormat);
        }
    
        private void SetEffect(UInt32 mask, UInt32 effect, bool valid)
        {
            CHARFORMAT2 fmt = new CHARFORMAT2();
            fmt.cbSize = Marshal.SizeOf(fmt);
            fmt.dwMask = mask;
            fmt.dwEffects = valid ? effect : 0;
            SendMessage(_textEdit.Handle, EM_SETCHARFORMAT, SCF_SELECTION, ref fmt);
        }
    
        private bool GetEffect(UInt32 mask, UInt32 effect)
        {
            return (0 != (_charFormat.dwMask & mask)) && (0 != (_charFormat.dwEffects & effect));
        }
    
        public bool Bold { get { return GetEffect(CFM_BOLD, CFE_BOLD); } set { SetEffect(CFM_BOLD, CFE_BOLD, value); } }
        public bool Italic { get { return GetEffect(CFM_ITALIC, CFE_ITALIC); } set { SetEffect(CFM_ITALIC, CFE_ITALIC, value); } }
    
        // ... etc ... etc ... you get the idea.
    
        2
  •  6
  •   Mike B    17 年前

    那么...怎么样

    richTextBox.Text = richTextBox.Text.ToString();
    
        3
  •  3
  •   Cheeso    16 年前

    我用过

    var t = richTextBox1.Text;
    richTextBox1.Text = t; 
    

    编辑::

    一定要插入一条评论,说明你为什么要这么做。在不知情的人看来,这看起来很可笑。

        4
  •  2
  •   jay_t55    17 年前

    仅使用:

    richTextBox1.Clear();
    

        5
  •  1
  •   NickAldwin    16 年前

    我发现的另一种方法(我已经改用了,因为它不会闪烁)是在应用任何格式之前获取初始rtf字符串:

    string initialRtf = richTextBox.Rtf;
    

    然后,当我想重置格式时,我只需执行以下操作:

    richTextBox.Rtf = initialRtf;
    

    然而,这并不完美,因为它要求文本保持不变。好吧,至少比问题中详述的方法好一点。

        6
  •  1
  •   Dan W    11 年前

    一段时间以来,我一直在我自己的程序中使用这段代码。它直接设置RichTextBox的RTF,因此应该比通常的方式设置样式快得多。它接收字符串(主文本),还可以选择接收颜色数组、字体大小数组(int)和字体权重数组(bool),每个数组表示字符串中每个字符的每个颜色、大小或字体权重。

    或者,您可以简单地保留标题给出的默认大小、重量和斜体数字。

    public string text2RTF(string text, Color[] color = null, bool[] bold = null, int[] size = null,
                            string font = "Microsoft Sans Serif", double defaultFontSize = 16,
                            bool defaultFontBold = false, bool defaultFontItalic = false, char align = 'l')
    {
        StringBuilder rtf = new StringBuilder();
        rtf.Append(@"{\rtf1\ansi\ansicpg1252\deff0\deflang2057{\fonttbl{\f0\fnil\fcharset0 ");
        rtf.Append(font);
        rtf.Append(@";}}{\colortbl ;");
    
        if (color != null)
        {
            rtf.Append("\\red" + (color[0].R).ToString() + "\\green" + (color[0].G).ToString() + "\\blue" + (color[0].B).ToString() + ";");
            for (int i = 1; i < text.Length; i++)
            {
                if ((color[i].R != color[i - 1].R || color[i].G != color[i - 1].G || color[i].B != color[i - 1].B))
                {
                    rtf.Append("\\red" + (color[i].R).ToString() + "\\green" + (color[i].G).ToString() + "\\blue" + (color[i].B).ToString() + ";");
                }
            }
        }
    
    
        rtf.Append("}\n\\viewkind4\\uc1\\pard");
        if (defaultFontBold == true) rtf.Append("\\b");
        if (defaultFontItalic == true) rtf.Append("\\i");
    
        if (align == 'r')   rtf.Append("\\qr");
    
        rtf.Append("\\f0\\fs" + (Math.Round(defaultFontSize)).ToString()+" ");
        int startOfActualText = rtf.Length;
    
        int count = 1;
        for (int i = 0; i < text.Length; i++)
        {
            if (color!=null && (i == 0 || color[i].R != color[i - 1].R || color[i].G != color[i - 1].G || color[i].B != color[i - 1].B))
            {
                rtf.Append("\\cf"); rtf.Append(count.ToString() + " "); count++;
            }
            if (bold!=null && (i == 0 || bold[i] != bold[i - 1]))
            {
                if (bold[i] == true) rtf.Append("\\b1 ");
                else rtf.Append("\\b0 ");
            }
            if (size!=null && (i == 0 || size[i] != size[i - 1]))
            {
                rtf.Append("\\fs"+size[i].ToString()+" " );                 
            }
    
            if (text[i] == '\\' || text[i] == '}' || text[i] == '{') rtf.Append('\\');
    
            // GetRtfUnicodeOfChar:
            string st="";
            if (text[i] <= 0x7f) st = text[i].ToString();
            else st = "\\u" + Convert.ToUInt32(text[i]) + "?";
    
    
            rtf.Append(st);
        }
    
        rtf.Append("\n}");
        rtf.Replace("\n", "\\par\n", startOfActualText, rtf.Length - startOfActualText);
    
    
        return rtf.ToString();
    
    }
    
        7
  •  1
  •   Julo    11 年前

    在我的例子中,我需要清除格式并留下一个空的 RichTextBox ,所以我做了这个函数:

    private void ClearRichTextBox()
    {
      this.richTextBox1.ForeColor = Color.Empty;
      this.richTextBox1.BackColor = Color.Empty;
      this.richTextBox1.SelectAll();
      this.richTextBox1.SelectionColor = Color.Empty;
      this.richTextBox1.SelectionBackColor = Color.Empty;
      this.richTextBox1.SelectionFont = this.richTextBox1.Font;
      this.richTextBox1.Clear();
    }
    

    那么简单的解决方案是:

    string backUp = this.richTextBox1.Text;
    ClearRichTextBox();
    this.richTextBox1.Text = backUp;
    

    this.richTextBox1.Clear(); (这可能也会起作用,但我不能保证,因为我只在简单的格式上测试了它。因此,可以添加任何其他行以删除不同的格式。)

    当不应清除文本时,请记住在数据变形后存储以前的位置/选择和刷新状态。

        8
  •  0
  •   user2774159    13 年前

    “我不喜欢上面第一次编辑中的方法的原因是它在清除文本框时使文本框“闪烁”,然后重新输入文本。”

    string tempTxt = richTextBox.Text;
    rtbIncludes.SuspendLayout();
    richTextBox.Clear();
    richTextBox.Text = tempTxt;
    rtbIncludes.ResumeLayout();
    

    如果花费的时间太长,控件将显示为黑色矩形,直到调用ResumeLayout()。

        9
  •  -1
  •   John Sibly    13 年前
    RichTextBox rtbTemp = new RichTextBox();
    rtbTemp.Text = rtb.Text;
    rtb.Rtf = rtbTemp.Rtf;
    

    希望它能起作用

        10
  •  -1
  •   wael32gh    10 年前

    很好。。

    var TempString = richTextBox1.Text;
    richTextBox1.Rtf = string.Empty;
    richTextBox1.Text = TempString ;
    
    推荐文章