16

I've been looking for the way to change the textbox highlight color when a user select text. Windows uses blue as default color. For example, on Microsoft Outlook, when you write a mail and select (highlight) text, the back color is gray.

Selected text in Outlook

TextBox selected text by user

Everybody said that I need to override onPaint method but i don't know how exactly to do that. The RichTextbox selectedbackground color is not the solution because it changes the color for the text, not when the user selects it.

Camilo Terevinto
  • 31,141
  • 6
  • 88
  • 120
Tanner Ornelas
  • 602
  • 1
  • 8
  • 17
  • you need to understand the the following for example `int length = richTextBox.TextLength richTextBox.SelectionStart = length; richTextBox.SelectionLength = yourstring.Length; richTextBox.SelectionColor = Color.Blue;` something like that – MethodMan Jan 07 '16 at 22:17
  • 1
    That makes a background color on the text, but when user select it, it still in blue. I'm looking to change the rectangle color that is drawn when a user select a text with his mouse or with Shift key. – Tanner Ornelas Jan 07 '16 at 22:32
  • do a google search I have seen several examples online about highlighting selection text – MethodMan Jan 07 '16 at 22:33
  • 5
    @MethodMan I googled and nothing to find. Can you give some link? – FoggyFinder Mar 03 '17 at 19:53
  • I found some related articles [some examples](https://csharp.hotexamples.com/examples/-/TextBoxState/-/php-textboxstate-class-examples.html). And [OnPaint](https://stackoverflow.com/questions/32330186/textbox-drawn-in-wm-paint-flickers-on-mouse-enter-leave) Maybe it helps. – vito Aug 02 '18 at 11:36
  • It depends on the complexity of the rtb. If you want a simple single line without draging and droping or moving selections and other fancy staff with just numbers or text it is not so difficult. But if you want the whole deal that is a looot of work. – γηράσκω δ' αεί πολλά διδασκόμε Aug 03 '18 at 05:04

2 Answers2

2

As an option, you can rely on an ElementHost Windows Forms control to host a WPF TextBox control. Then for the WPF TextBox control, set SelectionBrush and SelectionOpacity.

Example

In the following example I've created a Windows Forms UserControl containing an ElementHost to host a WPF TextBox control. Then for the WPF TextBox control, set SelectionBrush and SelectionOpacity.

using System;
using System.ComponentModel;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Forms.Integration;
using System.Windows.Media;
public class MyWPFTextBox : System.Windows.Forms.UserControl
{
    private ElementHost elementHost = new ElementHost();
    private TextBox textBox = new TextBox();
    public MyWPFTextBox()
    {
        textBox.SelectionBrush = new SolidColorBrush(Colors.Gray);
        textBox.SelectionOpacity = 0.5;
        textBox.TextAlignment = TextAlignment.Left;
        textBox.VerticalContentAlignment = VerticalAlignment.Center;
        elementHost.Dock = System.Windows.Forms.DockStyle.Fill;
        elementHost.Name = "elementHost";
        elementHost.Child = textBox;
        textBox.TextChanged += (s, e) => OnTextChanged(EventArgs.Empty);
        Controls.Add(elementHost);
    }
    [DesignerSerializationVisibility(DesignerSerializationVisibility.Visible)]
    public override string Text
    {
        get { return textBox.Text; }
        set { textBox.Text = value; }
    }
}

Referenced Assemblies

Here are required referenced assemblies: PresentationCore, PresentationFramework, WindowsBase, WindowsFormsIntegration.

Reza Aghaei
  • 120,393
  • 18
  • 203
  • 398
  • +1 That's exactly the only solution I thought of. But I also may be wrong. Note for anyone who would use this solution, it only works with framework >= 4.0. Still looking for other answers that may provide better native Winforms solutions. Also, the `SelectionBrush` in WPF isn't too advanced (i.e no fore/back colors specifying. Only Opacity. But still a good solution). Though thanks for your answer! – Beyondo Aug 02 '18 at 22:04
  • @XStylish You're welcome. As far as I know there is no native support for changing selection highlight color of native text box independent from windows theme. – Reza Aghaei Aug 05 '18 at 20:23
  • Be aware that `System.Windows.Forms.TextBox` has no property `SelectionBrush`. That is only in `System.Windows.Controls.TextBox` – Harald Coppoolse Aug 06 '18 at 13:44
  • @HaraldCoppoolse the `textBox` in the answer is a `System.Windows.Controls.TextBox`. – Reza Aghaei Aug 06 '18 at 13:56
  • This seems a nice solution. More framework native and affordable, maybe this will work with Mono. – Tanner Ornelas Aug 08 '18 at 05:43
  • @TannerOrnelas You can also extend the class by adding more properties and events. – Reza Aghaei Aug 08 '18 at 05:44
1

Hi here is the code to change the selection colour just keep in mind that you will have to store the current colour and then once you've changed the colour and your application closes you would need to restore it because this changes the colour of the whole computer not just for the current process.

    [DllImport("user32.dll")]
    static extern bool SetSysColors(int cElements, int[] lpaElements, uint[] lpaRgbValues);


    void ChangeSelectColour(Color color)
    {
        const int COLOR_HIGHLIGHT = 13;
        const int COLOR_HIGHLIGHTTEXT = 14;
        // You will have to set the HighlightText colour if you want to change that as well.


        //array of elements to change
        int[] elements = { COLOR_HIGHLIGHT };


        List<uint> colours = new List<uint>();
        colours.Add((uint)ColorTranslator.ToWin32(color));

        //set the desktop color using p/invoke
        SetSysColors(elements.Length, elements, colours.ToArray());
    }
  • 3
    This seems an approach but going to the OS is a little risky. – Tanner Ornelas Jan 18 '18 at 21:23
  • 3
    It is not risky. But it changes the settings for ALL running applications including Windows Explorer. This is surely not what the user expects. It is a pity that Microsoft did not implement a function which does the same as SetSysColors, but only for the current application. – Elmue Aug 11 '20 at 02:41