在做了一些研究后,我相信我问的问题与Remove richtextbox SelectionBackColor相同。我遇到了同样的问题,但我认为该问题的答案不充分,因为问题没有得到明确解释。请参阅以下内容:
在RichTextBox
中,我如何从某些(但不是全部)文本(BackColor
)中删除自定义SelectionBackColor
,以便它假设控件<{>>的BackColor
,即使BackColor
将来发生变化?
我有一种方法可突出显示某些文字,并使用BackColor
更改其SelectionBackColor
。我有另一种方法可以更改整个控件的BackColor
。这些事件可以独立发生。
如果我想&#34;删除&#34;一些SelectionBackColor
,我可以尝试将SelectionBackColor
设置为Color.Transparent
,但最终会为白色。如果我的RichTextBox
当前 BackColor
为白色,那暂时没问题。如果我将SelectionBackColor
设置为当前BackColor
,则暂时没有问题,直到BackColor从其他方法更改为止。
RichTextBox.BackColor
更改后,之前突出显示的所有地点都使用白色或之前的BackColor
,而不是假设新颜色与之前未突出显示的文字一样。
我已尝试删除和替换文本,但据我所知,这会否定保留该文本的任何其他自定义格式的能力。将SelectionBackColor
设置为null不起作用。
使用下面的代码可以很容易地看到我在说什么:
protected override void OnLostFocus(EventArgs e)
{
base.OnLostFocus(e);
this.BackColor = Color.Gray;
if (SelectionLength > 0)
{
SelectionBackColor = Color.Yellow;
}
}
protected override void OnGotFocus(EventArgs e)
{
base.OnGotFocus(e);
this.ResetBackColor();
if (SelectionLength > 0)
{
// The goal of this line is to "remove" the yellow.
// By assigning it any value, it seems to have lost
// the ability to use the control's BackColor normally.
SelectionBackColor = this.BackColor;// or Color.Transparent
}
}
使用上面的代码在自定义RichTextBox
对象中键入一些文本,突出显示其中的一小部分,然后使框失去焦点。您将看到黄色突出显示的文本。然后,让盒子获得焦点。正如预期的那样,黄色背景将消失。但是,如果您将插入符号移动到文本的其他位置并使控件再次失去焦点,您将看到先前突出显示的文本不呈现灰色背景颜色。
答案 0 :(得分:2)
这很有趣。看来(在我测试的Windows 7 / .Net 3.5上,也许在其他地方)System.Windows.Forms.RichTextBox.SelectionBackColor
可能有一个错误清除选择背景颜色的错误。 source code确实:
public Color SelectionBackColor {
set
{
//Note: don't compare the value to the old value here: it's possible that
//you have a different range selected.
selectionBackColorToSetOnHandleCreated = value;
if (IsHandleCreated)
{
NativeMethods.CHARFORMAT2A cf2 = new NativeMethods.CHARFORMAT2A();
if (value == Color.Empty)
{
cf2.dwEffects = RichTextBoxConstants.CFE_AUTOBACKCOLOR;
}
else
{
cf2.dwMask = RichTextBoxConstants.CFM_BACKCOLOR;
cf2.crBackColor = ColorTranslator.ToWin32(value);
}
UnsafeNativeMethods.SendMessage(new HandleRef(this, Handle), RichTextBoxConstants.EM_SETCHARFORMAT, RichTextBoxConstants.SCF_SELECTION, cf2);
}
}
}
正如您所注意到的,当设置为richTextBox.BackColor
时,实际上并未清除背景颜色。当设置为RichTextBox.DefaultBackColor
时,它也不会清除颜色,here只是将选择颜色设置为默认的灰色控制颜色。看起来源代码尝试在设置为Color.Empty
时清除选择背面颜色 - 但至少在我的机器上,它什么都不做。
但是如果我在发送消息之前创建了一个也为空颜色设置cf2.dwMask = RichTextBoxConstants.CFM_BACKCOLOR;
的扩展方法,那么SetSelectionBackColor(Color.Empty)
现在可以正常工作了!
public static void SetSelectionBackColor(this RichTextBox richTextBox, Color value)
{
if (richTextBox.IsHandleCreated && value == Color.Empty)
{
var cf2 = new CHARFORMAT2();
cf2.dwEffects = RichTextBoxConstants.CFE_AUTOBACKCOLOR;
cf2.dwMask = RichTextBoxConstants.CFM_BACKCOLOR;
cf2.crBackColor = ColorTranslator.ToWin32(value);
UnsafeNativeMethods.SendMessage(new HandleRef(richTextBox, richTextBox.Handle), RichTextBoxConstants.EM_SETCHARFORMAT, RichTextBoxConstants.SCF_SELECTION, cf2);
}
else
{
richTextBox.SelectionBackColor = value;
}
}
完整方法,常量和类改编自here和here以及here和here以及{{3}}:
public static class RichTextBoxConstants
{
// http://referencesource.microsoft.com/#System.Windows.Forms/winforms/Managed/System/WinForms/RichTextBoxConstants.cs,31b52ac41e96a888
/* EM_SETCHARFORMAT wparam masks */
internal const int SCF_SELECTION = 0x0001;
internal const int EM_SETCHARFORMAT = (NativeMethods.WM_USER + 68);
internal const int CFM_BACKCOLOR = 0x04000000;
/* NOTE: CFE_AUTOCOLOR and CFE_AUTOBACKCOLOR correspond to CFM_COLOR and
CFM_BACKCOLOR, respectively, which control them */
internal const int CFE_AUTOBACKCOLOR = CFM_BACKCOLOR;
}
[StructLayout(LayoutKind.Sequential, Pack = 4)]
public class CHARFORMAT2
{
// http://referencesource.microsoft.com/#System.Windows.Forms/winforms/Managed/System/WinForms/NativeMethods.cs,acde044a28b57a48
// http://pinvoke.net/default.aspx/Structures/CHARFORMAT2.html
public int cbSize = Marshal.SizeOf(typeof(CHARFORMAT2));
public int dwMask;
public int 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;
}
public static class NativeMethods
{
// http://referencesource.microsoft.com/#System.Windows.Forms/winforms/Managed/System/WinForms/NativeMethods.cs,e75041b5218ff60b
public const int WM_USER = 0x0400;
public static void SetSelectionBackColor(this RichTextBox richTextBox, Color value)
{
if (richTextBox.IsHandleCreated && value == Color.Empty)
{
var cf2 = new CHARFORMAT2();
cf2.dwEffects = RichTextBoxConstants.CFE_AUTOBACKCOLOR;
cf2.dwMask = RichTextBoxConstants.CFM_BACKCOLOR;
cf2.crBackColor = ColorTranslator.ToWin32(value);
UnsafeNativeMethods.SendMessage(new HandleRef(richTextBox, richTextBox.Handle), RichTextBoxConstants.EM_SETCHARFORMAT, RichTextBoxConstants.SCF_SELECTION, cf2);
}
else
{
richTextBox.SelectionBackColor = value;
}
}
}
public static class UnsafeNativeMethods
{
// http://referencesource.microsoft.com/#System.Windows.Forms/winforms/Managed/System/WinForms/UnsafeNativeMethods.cs,0d546f58103867e3
// For RichTextBox
//
[DllImport("user32.dll", CharSet = CharSet.Auto)]
public static extern IntPtr SendMessage(HandleRef hWnd, int msg, int wParam, [In, Out, MarshalAs(UnmanagedType.LPStruct)] CHARFORMAT2 lParam);
}
答案 1 :(得分:0)
我做了:
SelectionBackColor = default(Color);
它工作正常。