18

RichTextBox (WPF ではなく WinForms) の書式設定を「リセット」しようとしています。以前使用していた

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();

まだすべてのフォーマットがクリアされていないため、機能していないようです。上記の最初の編集の方法が気に入らない理由は、テキストボックスをクリアしてからテキストを再入力すると、テキストボックスが「点滅」するからです。Clear() メソッドは、すべてのテキストを単純にクリアするだけでなく、何らかの書式設定のリセットを明確に (しゃれは意図していません) 行うため、単純に richTextBox.ResetFormatting() メソッド、または同じ機能にアクセスする何らかの方法が必要なようです。 .

要約する:

上記の例のようにテキストをクリアせずにRichTextBox内のテキストのフォーマットをリセットする方法はありますか(そうであれば、それは何ですか)(望ましくない点滅が発生するため)?

4

10 に答える 10

28

悲しいことに、私はこれを必要なコードだけにスリム化するために最善を尽くしました。まだ大きいですが、頑張ります。.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.
于 2009-10-14T00:41:57.760 に答える
6

どうですか

richTextBox.Text = richTextBox.Text.ToString();
于 2009-09-25T22:50:47.090 に答える
3

利用した

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

編集::

なぜあなたがしていることをしているのかについてのコメントを必ず挿入してください。知らない人にはばかげているように見えます。

于 2009-10-12T22:22:30.470 に答える
2

ちょうど使用:

richTextBox1.Clear();

... トリックを行う必要があります。私のために働きます。

于 2009-08-16T18:44:46.560 に答える
1

多くの答えがあることがわかりますが、すべてのフォーマットをクリアする拡張機能として、よりシンプルで簡単なアプローチがあると思います。

私の場合、フォーマットをクリアして空のままにする必要があったため、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();または、単純に clear 関数の行を削除します。(これもおそらく機能しますが、単純な書式設定でのみテストしたため、保証はしません。したがって、別の書式設定を削除するために他の行を追加する必要がある可能性があります。)

テキストをクリアしてはならない場合は、以前の位置/選択を保存し、データのフォーマット解除後に状態を更新することを忘れないでください。

于 2015-05-20T09:34:39.310 に答える
1

私が見つけた別の方法 (フラッシュしないので、使用に切り替えた方法) は、フォーマットが適用される前に最初の rtf 文字列を取得することです。

string initialRtf = richTextBox.Rtf;

次に、フォーマットをリセットしたい場合は、次のようにします。

richTextBox.Rtf = initialRtf;

ただし、テキストが同じままである必要があるため、これは実際には完璧ではありません。少なくとも、質問で詳述されている方法よりも少し優れています。

于 2009-10-12T22:14:59.507 に答える
-1

正常に動作します ..

var TempString = richTextBox1.Text;
richTextBox1.Rtf = string.Empty;
richTextBox1.Text = TempString ;
于 2016-09-02T14:43:14.150 に答える
-1
RichTextBox rtbTemp = new RichTextBox();
rtbTemp.Text = rtb.Text;
rtb.Rtf = rtbTemp.Rtf;

それがうまくいくことを願っています

于 2009-10-15T15:11:48.823 に答える