Reputation: 93
i have a problem about custom Paint method in class that inherit from ToolStripTextBox. I need to draw an icon before ToolStripTextBox in ContextMenuStrip.
FIRST ATTEMPT:
ContextMenuStrip CXstrip = new ContextMenuStrip();
CXstrip.ImageList = [My defined list];
var groupMenu = new ToolStripTextBox();
groupMenu.DisplayStyle = ToolStripItemDisplayStyle.ImageAndText;
groupMenu.ImageIndex = 1;
Failed :( Only textBox will Appear.
SECOND ATTEMPT:
public class ToolStripSpringTextBox : ToolStripTextBox {
protected override void OnPaint(PaintEventArgs e) {
e.Graphics.DrawLine(Pens.Red, 0, 0, 50, 10);
}
}
Paint is called, but he draw always standard textbox without my line (same of First Attempt)
My question is why i cannot draw manually? Why first (Logic) way to do this doesn't work like ToolStripMenuItem for example?
Upvotes: 2
Views: 626
Reputation: 4660
As a direct answer to your question, the ToolStripTextBox
doesn't have in its inheritance tree the ToolStripMenuItem
so you can't deal with it in the exact same way.
To assign images to items like ToolStripTextBox
, ToolStripComboBox
, and ToolStripDropDownItem
:
Override the hidden Image
property and reverse the attributes to make it visible and accessible again. You will find it in the Properties window to assign an image. Or through the code.
Override the OnParentChanged
method to subscribe to the parent's Paint event. The type of the parent of both ContextMenuStrip
and a MenuStrip
drop down is ToolStripDropDownMenu
.
Define the rectangle of the image and draw it.
using System.ComponentModel;
using System.Windows.Forms;
using System.Windows.Forms.Design;
using System.Drawing;
[DesignerCategory("ToolStrip"),
ToolStripItemDesignerAvailability(ToolStripItemDesignerAvailability.All)]
public class ToolStripSpringTextBox : ToolStripTextBox
{
public ToolStripSpringTextBox() : base() { }
/// <summary>
/// The image that will be displayed on the item.
/// </summary>
[Browsable(true),
EditorBrowsable(EditorBrowsableState.Always),
DesignerSerializationVisibility(DesignerSerializationVisibility.Visible),
Category("Appearance"),
Description("The image associated with the object.")]
public override Image Image { get => base.Image; set => base.Image = value; }
protected override void OnParentChanged(ToolStrip oldParent, ToolStrip newParent)
{
base.OnParentChanged(oldParent, newParent);
if (newParent != null && newParent is ToolStripDropDownMenu)
{
newParent.Paint -= new PaintEventHandler(OnParentPaint);
newParent.Paint += new PaintEventHandler(OnParentPaint);
}
if (oldParent != null)
oldParent.Paint -= new PaintEventHandler(OnParentPaint);
}
private void OnParentPaint(object sender, PaintEventArgs e)
{
if (Image is null ||
(sender is ContextMenuStrip cmnu &&
!cmnu.ShowImageMargin && !cmnu.ShowCheckMargin))
return;
var sz = Image.Size;
var r = new Rectangle((Bounds.X - sz.Width - 7) / 2,
(Bounds.Height - sz.Height) / 2 + Bounds.Y, sz.Width, sz.Height);
if (RightToLeft == RightToLeft.Yes)
r.X = Bounds.Right + r.Width - ContentRectangle.X;
e.Graphics.DrawImage(Image, r);
}
}
Upvotes: 2