I have a display that customizes text and as the user customizes it, I want the text to display. One of the customizations available is an "x-out" which should draw a large "X" over all 5 characters of the text. So when the checkbox "X-Out" is checked, it should update the text from this:
To this:
The box itself is a RichTextBox contained within a Panel. I have tried using the Paint event in the panel, but it draws it underneath the RichTextBox (that's the little red lines on the corners). I have also tried using a custom RichTextBox control like at this website. This code does work, but only if I do not set text and color in the RichTextBox. If I set text and color and then check the checkbox, the WndProc method is not called. How do I trigger the WndProc method with Message.msg 15? Here is the code:
Form
public partial class ButtonDataForm : Form
{
CustomRichTextBox button1;
public ButtonDataForm()
{
InitializeComponent()
}
void OnFormLoad(object sender, EventArgs e)
{
cstmRichTextBox = new CustomRichTextBox(richTextBox1);
}
void OnXOutChecked()
{
cstmRichTextBox.IsChecked = xoutCheckbox.Checked;
cstmRichTextBox.ParentTex.Refresh(); // This does not trigger the WndProc message on cstmRichTextBox
}
}
CustomRichTextBox
public class CustomRichTextBox : NativeWindow
{
public RichTextBox ParentTextBox { get; private set; }
Graphics textBoxGraphics;
public bool IsChecked { get; set; }
public CustomRichTextBox(RichTextBox tb)
{
ParentTextBox = tb;
textBoxGraphics = Graphics.FromHwnd(tb.Handle);
AssignHandle(ParentTextBox.Handle);
}
protected override void WndProc(ref Message m}
{
switch(m.Msg)
{
case 15:
parentTextBox.Invalidate();
base.WndProc(ref m);
DrawXOut();
break;
default:
base.WndProc(ref m);
break;
}
}
void DrawXOut()
{
if (IsChecked)
{
Pen xpen = new Pen(ParentTextBox.ForeColor, 3);
Point topLeft = ParentTextBox.Location;
int x1 = topLeft.X + ParentTextBox.Width;
int y1 = topLeft.Y + ParentTextBox.Height;
Point topRight = new Point(x1, topLeft.Y);
Point bottomLeft = new Point(topLeft.X, y1);
Point bottomRight = new Point(x1, y1);
textBoxGraphics.DrawLine(xpen, topLeft, bottomRight);
textBoxGraphics.DrawLine(xpen, bottomLeft, topRight);
}
}
}
EDIT:
I tried placing a transparent panel on the bottom panel and drawing inside it when the Paint event fired. The event fires, but nothing showed up in the panel. Am I calculating the location incorrectly?
void OnXOutChecked()
{
panel1.Refresh();
}
void OnPanel1Paint(object sender, PaintEventArgs e)
{
Pen xpen = new Pen(Color.Red, 3);
Point topLeft = panel1.Location;
int x1 = topLeft.X + panel1.Width;
int y1 = topLeft.Y + panel1.Height;
Point topRight = new Point(x1, topLeft.Y);
Point bottomLeft = new Point(topLeft.X, y1);
Point bottomRight = new Point(x1, y1);
e.Graphics.DrawLine(xpen, topLeft, bottomRight);
e.Graphics.DrawLine(xpen, bottomLeft, topRight);
}




This is a very unreliable approach, drawing on top of the control and expecting it to work in all possible scenarios (and there can be many!).
You can just place a transparent picture box on top of the text box with a transparent bitmap that has two crossed red lines.