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.
Related
Given the following event handler code:
private void image1_MouseDown(object sender, MouseButtonEventArgs e)
{
///////////
}
How can I call it from another method:
private void timerTick(object sender, EventArgs e)
{
image1_MouseDown(object, e); // error
}
Event handlers are regular methods like any others.
The reason you can't call it like you're trying to do, is because the MouseDown event takes a MouseButtonEventArgs instance, while the Tick event of timers take the base class EventArgs.
You'll need to create a new instance of MouseButtonEventArgs, but then you'll need to initialize it with a device, and other event data.
A better option would be to refactor the body of the MouseDown event handler to a method taking individual parameters, which you can then call without having to create a MouseButtonEventArgs instance.
private void image1_MouseDown(object sender, MouseButtonEventArgs e)
{
this.ProcessImageMouseDown(e.ChangedButton, e.ButtonState, e.GetPosition(sender as FrameworkElement));
}
private void timerTick(object sender, EventArgs e)
{
this.ProcessImageMouseDown(MouseButton.Left, MouseButtonState.Pressed, new Point(10d, 20d));
}
private void ProcessImageMouseDown(MouseButton button, MouseButtonState state, System.Windows.Point position)
{
// Do actual processing here.
}
I have some basic override code in the same class to catch mouse events. I can get OnMouseWheel to fire, but other click events do to not fire with the same code.
protected override void OnMouseDown(System.Windows.Forms.MouseEventArgs e)
{
Debug.WriteLine("mouse down"); //does not work
}
protected override void OnMouseWheel(System.Windows.Forms.MouseEventArgs e)
{
Debug.WriteLine("mouse wheel"); //works
}
Does OnMouseWheel need focus to fire? That has been what I have been trying to troubleshoot so far.
protected override void OnMouseClick ( MouseEventArgs e )
{
Debug.WriteLine("Mouse click"); //works
}
private void panel1_MouseClick ( object sender, MouseEventArgs e )
{
OnMouseClick(e);
}
In your actual design window make sure you attached the event to the Control. If you need to do it programatically, then
this.panel1.MouseClick += new System.Windows.Forms.MouseEventHandler(this.panel1_MouseClick);
Note:
Yes I know the control names aren't the exact same and you aren't using MetroControls, but it's the same idea.
You need to call the base method implementation of OnMouse events so the base class can react to the events:
protected override void OnMouseDown(MouseEventArgs e)
{
Debug.WriteLine("OnMouseDown");
base.OnMouseDown(e);
}
protected override void OnMouseUp(MouseEventArgs e)
{
Debug.WriteLine("OnMouseUp");
base.OnMouseUp(e);
}
protected override void OnMouseWheel(MouseEventArgs e)
{
Debug.WriteLine("OnMouseWheel");
base.OnMouseWheel(e);
}
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);
}
}
I've created a custom user control for a windows form that will operate similar to a button (and please don't suggest that I just use a button, because I will be storing data in this user control), but I can't figure out how to get the OnClick() event to fire. I've sifted through a handful of tutorials and looked at a few similar questions on the site, but I can't seem to get the event to fire off - so I'm either doing something wrong or everyone posted incorrect code (I hope it isn't the latter)
In my custom control.cs,
namespace MobCreator {
public partial class MOBSample : UserControl {
public MOBSample() {
InitializeComponent();
}
protected override void OnMouseUp(MouseEventArgs e) {
this.BorderStyle = BorderStyle.FixedSingle;
base.OnMouseUp(e);
}
protected override void OnMouseDown(MouseEventArgs e) {
this.BorderStyle = BorderStyle.Fixed3D;
base.OnMouseDown(e);
}
public event EventHandler ButtonClick;
private void OnButtonClick(object sender, EventArgs e) {
// invoke UserControl event here
if (this.ButtonClick != null) this.OnButtonClick(sender, e);
}
}
}
And in my form.cs,
private void MobCreatorForm_Load(object sender, EventArgs e) {
UserControl1.ButtonClick += new EventHandler(this.CustomEvent_Handler);
}
private void CustomEvent_Handler(object sender, EventArgs e) {
Console.WriteLine("Click");
}
However, when I run the program my console never outputs "Click".
Check this link on MSDN: it is a simple Event tutorial, you should be able to adapt it to your scenario.
At a first look, what you are probably missing is a Delegate for your event.
Try this
private void MobCreatorForm_Load(object sender, EventArgs e)
{
CustomEvent_Handler(null,null);
}
private void CustomEvent_Handler(object sender, EventArgs e)
{
Console.WriteLine("Click");
}
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);
}