I'm trying to change the border color of a text box (txtUser) on button click event (something like a form validation, if the input is empty then call the method that colors the border red). I did some googling and found this:
void myControl1_Paint(object sender, PaintEventArgs e)
{
ControlPaint.DrawBorder(e.Graphics, this.txtUser.ClientRectangle, Color.Black, ButtonBorderStyle.Solid);
}
But I'm having trouble understaing where or how should I call this method, or methods with (object sender, PaintEventArgs e) as params. Any explanation is appreciated.
You need to inherit from TextBox and then override the OnPaint method. Something like this should work:
public class ValidateEdit : TextBox
{
bool _InError;
public ValidateEdit()
{
SetStyle(ControlStyles.UserPaint, true);
}
public bool InError {
get {
return _InError;
}
set
{
_InError = value;
Refresh();
}
}
protected override void OnPaint(PaintEventArgs e)
{
base.OnPaint(e);
if (InError)
ControlPaint.DrawBorder(e.Graphics, this.DisplayRectangle, Color.Red, ButtonBorderStyle.Solid);
}
}
Related
I'm trying to call PaintEventArgs when i press a button, my problem is i don't know how to call one without modify button event
private void button_Click(object sender, EventArgs e /*<= PaintEventArgs*/)
{
func(e);
base.OnPaint(e);
}
You can call Invalidate()
It will cause the control to be redrawn
private void button_Click(object sender, EventArgs e /*<= PaintEventArgs*/)
{
//func(e); It will be called in the OnPaint method
Invalidate();
}
To use PaintEventArgs you need to override OnPaint method
protected override void OnPaint(PaintEventArgs e)
{
base.OnPaint(e);
func(e);
}
To implement the OnPaint you need to create your own class that inherits the Button
public class BetterButton : Button{
public BetterButton()
{}
protected override void OnPaint(PaintEventArgs e) {
base.OnPaint(e);
func(e);
}
}
You ALWAYS do the drawing on the Paint event of the control you want to draw on. That might mean in the overridden OnPaint method or else in the Paint event handler. In order to cause thew Paint event to be raised, you call the Invalidate method of the appropriate control. You can call it with no arguments but, ideally, you would calculate the smallest area that has or might have changed and pass that as a Rectangle or the like.
EDIT:
Here is an example that will draw the last recorded time in the top-left of the form and update that time on each click of a Button:
private DateTime time;
private void button1_Click(object sender, EventArgs e)
{
time = DateTime.Now;
Invalidate();
}
private void Form1_Paint(object sender, PaintEventArgs e)
{
e.Graphics.DrawString(time.ToString(), Font, Brushes.Black, 10, 10);
}
As you can see, all you need to do on the Click event is update the data and invalidate the form. All the drawing, including the PaintEventArgs, is taken care of in the Paint event handler.
I need to change back-color of a ToolStripDropDownButton when its drop-down is opened. How can I do it?
I tried to inherit a class from the ToolStripProfessionalRenderer and then override the OnRenderDropDownButtonBackground, but it only affects when the drop-down is closed.
I believe you can use the following approaches:
1-st approach:
toolStripDropDownButton1.Paint += toolStripDropDownButton1_Paint;
//...
void toolStripDropDownButton1_Paint(object sender, PaintEventArgs e) {
if(toolStripDropDownButton1.Pressed) {
// TODO Paint your pressed button
e.Graphics.FillRectangle(Brushes.Green, e.ClipRectangle);
}
}
2-nd approach:
toolStrip.Renderer = new PressedRenderer();
//...
class PressedRenderer : ToolStripProfessionalRenderer {
protected override void OnRenderDropDownButtonBackground(ToolStripItemRenderEventArgs e) {
if(e.Item.Pressed)
e.Graphics.Clear(Color.Green);
else base.OnRenderDropDownButtonBackground(e);
}
}
Is the OnDropDownOpened event what you want?
private void toolStripDropDownButton_DropDownOpened(object sender, EventArgs e)
{
toolStripDropDownButton.BackColor = Color.Red;
}
How do I raise a ondraw event
Scenario: I am using a custom combobox with a onDrawItem in my form.
The drawitem is such
protected override void OnDrawItem(DrawItemEventArgs e)
{...
}
Question: How do I make the custom combobox ComboLineStyle redraw
itself on selectedindex changed of another cmbBoxLineColor. Ultimately I need a way to redraw all rows of the combobox on every selectedindex changed
.
private void cmbBoxLineColor_SelectedIndexChanged(object sender, EventArgs e)
{
Here I want the custom combobox-ComboLineStyle control to redraw itself
}
EDIT
I need the dropdown to draw itself again when the color in another linecolorcombo changes.Color
lineColorSel = cmbBoxLineColor.SelectedValue;
ComboBoxItemLineStyle itemSolid = new ComboBoxItemLineStyle ("Solid Line", lineColorSel);
The color property in my linestylecomboboxitem will have the selectedvalue of the linecolor combo. So the linestyle combo should refresh/invalidate itself and redraw itself with this lineColorSel.
Thank u
You can call Invalidate() on anything that inherits System.Windows.Forms.Control to force it to redraw
Heres and example of how I would do a custom draw for a selected item
protected override void OnDrawItem(DrawItemEventArgs e)
{
if (e.State == DrawItemState.Selected)
{
...
}
else
{
...
}
//or you could do it like this
//if(e.Index == this.SelectedIndex)
//{
//}
...
}
protected override void OnSelectedIndexChanged(EventArgs e)
{
base.OnSelectedIndexChanged(e);
base.Invalidate();
}
In my WPF application,I need to highlight ListViewItem whenever something is about to drop on it. I override OnDragEnter, OnDragOver, OnDragLeave etc of ListViewItem to apply my styles(say change background). It is working fine. but after dropping somthing on a listview item, when i click the listview items the selection and mouseover effects are not working properly.How can i solve this?
public class CustomListViewItem : ListViewItem
{
protected override void OnDragOver(System.Windows.DragEventArgs e)
{
this.Background = Brushes.Green;
base.OnDragOver(e);
}
protected override void OnDragEnter(System.Windows.DragEventArgs e)
{
this.Background = Brushes.Green;
base.OnDragEnter(e);
}
protected override void OnDragLeave(System.Windows.DragEventArgs e)
{
if (!this.IsSelected)
{
this.Background = Brushes.Transparent;
this.BorderBrush = Brushes.Transparent;
}
base.OnDragLeave(e);
}
}
After doing DragDrop your local value has precedence over selection and mouseover effects by style (see Dependency Property Setting Precedence List
).
Try DependencyObject.ClearValue Method:
protected override void OnDragLeave(System.Windows.DragEventArgs e)
{
if (!this.IsSelected)
{
this.ClearValue(BackgroundProperty);
this.ClearValue(BorderBrushProperty);
}
base.OnDragLeave(e);
}
I've added a custom border to the labels in one of my application forms as follows:
private void ColorMe(PaintEventArgs e)
{
Color myColor = Color.FromArgb(104, 195, 198);
Pen myPen = new Pen(myColor, 1);
e.Graphics.DrawRectangle(myPen,
e.ClipRectangle.Left,
e.ClipRectangle.Top,
e.ClipRectangle.Width - 1,
e.ClipRectangle.Height - 1);
base.OnPaint(e);
}
private void lblDisbs_Paint(object sender, PaintEventArgs e)
{
ColorMe(e);
}
Which works nicely. All I have to do it put ColorMe(e) in the Paint Event of each label.
However I want to use this method on all forms throughout the whole application. I tried putting my ColorMe() method in a class to call it from multiple forms that way, but it does not work, saying that 'base has no OnPaint event'.
How should I make this method available throughout the whole application?
Create class LabelWithBorder derive it from Label, override the OnPaint method.
public class LabelWithBorder : Label {
protected override void OnPaint(PaintEventArgs e) {
ColorMe(e);
}
}
Replace all WinForms labels in your app with your label.
You probably shouldn't use the ClipRectangle for drawing in this case, since it would produce malformed rectangles on your control.
If not using Karel Frajtak's solution, which is cleaner, you can try making a static class and then you can call it from any form:
internal static class LabelBorder {
public static void ColorMe(Rectangle r, PaintEventArgs e) {
r.Inflate(-1, -1);
using (Pen p = new Pen(Color.FromArgb(104, 195, 198), 1))
e.Graphics.DrawRectangle(p, r);
}
}
Example:
public Form1() {
InitializeComponent();
label1.Paint += label_Painter;
label2.Paint += label_Painter;
}
void label_Painter(object sender, PaintEventArgs e) {
LabelBorder.ColorMe(((Label)sender).ClientRectangle, e);
}