Overridden Event in Custom Control executes after Form Event - c#

I created a custom button in c#/WinForms that, among other things, gives the button a 3-D feel by altering the border thickness of the button in overridden MouseDown and MouseUp events using the following code in the overridden OnPaint event:
public int BorderThickness { get; set; } = 3;
public int ClickBorderThickness { get; set; } = 2;
private MouseIsDown = false;
protected override void OnPaint(PaintEventArgs pevent)
{
int BorderWidth = (MouseIsDown) ? ClickBorderThickness : BorderThickness;
ControlPaint.DrawBorder(pevent.Graphics, ClientRectangle,
SystemColors.ControlLightLight, BorderWidth, ButtonBorderStyle.Outset,
SystemColors.ControlLightLight, BorderWidth, ButtonBorderStyle.Outset,
SystemColors.ControlLightLight, BorderWidth, ButtonBorderStyle.Outset,
SystemColors.ControlLightLight, BorderWidth, ButtonBorderStyle.Outset);
//...Other Code...
}
protected override void OnMouseDown(MouseEventArgs e)
{
base.OnMouseDown(e);
MouseIsDown = true;
Invalidate();
}
protected override void OnMouseUp(MouseEventArgs e)
{
base.OnMouseUp(e);
MouseIsDown = false;
Invalidate();
}
I also created an overridden OnClick event:
protected override void OnMouseClick(MouseEventArgs e)
{
MouseIsDown = false;
Invalidate();
base.OnMouseClick(e);
}
What I thought would happen is that the button would be redrawn and go back to its "unclicked" look prior to executing the code in the Click event for the button on my form. That isn't what happened, and the overridden event was executed after ALL the code in the form Click event was completed.
How would I modify my custom button to execute the overridden Click event before the form Click event?

Thanks to the comment by Jimi, I made the following change, which did the trick:
protected override void OnMouseUp(MouseEventArgs e)
{
MouseIsDown = false;
Invalidate();
base.OnMouseUp(e);
}
(I moved the base.OnMouseUp(e) to the end in the OnMouseUp event).

Related

Why doesn't work custom control's paint event in Form.cs?

I have a custom button. OnPaint method is working in control's class file but the Button.Paint method doesn't work in Form.cs. Why does this happen and how can it be fixed?
My code for button:
//code...
public AltoButton()
{
SetStyle(ControlStyles.AllPaintingInWmPaint|ControlStyles.OptimizedDoubleBuffer|ControlStyles.ResizeRedraw|ControlStyles.SupportsTransparentBackColor|ControlStyles.UserPaint, true);
BackColor = Color.Transparent;
ForeColor = Color.Black;
Font = new System.Drawing.Font("Comic Sans MS", 10, FontStyle.Bold);
state = MouseState.Leave;
transparency = false;
}
#endregion
#region Events
protected override void OnPaint(PaintEventArgs e)
{
//code to draw shape and painting
}
//code...
code in Form.cs:
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
altoButton1.Paint += altoButton1_Paint;
}
void altoButton1_Paint(object sender, PaintEventArgs e)
{
e.Graphics.DrawLine(Pens.Red, 3, 3, 10, 10);
}
private void timer1_Tick(object sender, EventArgs e)
{
altoButton1.Invalidate();
}
}
I have found a solution myself. The reason is the I deleted the base.OnPaint(e) at the OnPaint(e) code block.
The solution is just to add base.OnPaint(e)
protected override void OnPaint(PaintEventArgs e)
{
//code to draw shape and painting
base.OnPaint(e);
}
The problem could be with the drawing elements on the screen - you should practise doing this to get known more(this is unique in different projects).Excatly you can add element to screen , to the tab etc...Hope it would help you.(Helped me:P)

How to override userControl property

IDE: C# .net, WINFORMS, .net 4.0
Hi have created a userControl, and I want to make a property that if user control enabled is false than change the back Image to imgDisabled.jpg else imgEnabled.jpg
Please tell me how to override the Enabled Property of usercontrol and add this function to it.
private void onPropertyChanged()
{
if (this.Enabled)
this.BackgroundImage = Properties.Resources.imgEnabled;
else
this.BackgroundImage = Properties.Resources.imgDisabled;
}
Override virtual OnEnabledChanged method of base Control class:
protected override void OnEnabledChanged(EventArgs e)
{
base.OnEnabledChanged(e);
if (this.Enabled)
this.BackgroundImage = Properties.Resources.imgEnabled;
else
this.BackgroundImage = Properties.Resources.imgDisabled;
}
Kindly use an event litner like this
class CustomProperty : Property
{
public event EventHandler SelectionChanged;
private int _selectionStart;
private int _selectionLength;
protected override void OnMouseDown(MouseEventArgs e)
{
_selectionStart = SelectionStart;
_selectionLength = SelectionLength;
base.OnMouseDown(e);
}
protected override void OnMouseUp(MouseEventArgs e)
{
if (null != SelectionChanged && (_selectionStart != SelectionStart || _selectionLength != SelectionLength))
SelectionChanged(this, EventArgs.Empty);
base.OnMouseUp(e);
}
}

UserControl click event is slow

I have my UserControl, and I have attached it's click event so I can set it's border style.
public partial class TestControl : UserControl
{
public TestControl()
{
InitializeComponent();
this.Click += Item_Click;
IsSelected = false;
}
public bool IsSelected { get; set; }
void Item_Click(object sender, EventArgs e)
{
if (!IsSelected)
{
IsSelected = true;
this.BorderStyle = System.Windows.Forms.BorderStyle.FixedSingle;
}
else
{
IsSelected = false;
this.BorderStyle = System.Windows.Forms.BorderStyle.None;
}
}
}
When I click over the UserControl I get it's border style assigned or removed... this works fine. But if I try to click faster It doesn't respond as I click on the UserControl.
If I click once and then wait and click again it works perfect but I want to increase the click response time, like if it was a button.
Any clue on how do I have this behavior?
If you are clicking very fast, you are getting a Double-Click event. Try using the MouseDown event instead.
But since this is the UserControl's base event, you can just override the method instead of attaching an event handler:
protected override void OnMouseDown(MouseEventArgs e) {
base.OnMouseDown(e);
if (e.Button == MouseButtons.Left) {
// your code here...
}
}

C# event Click TextBox

I have a usercontrol inheriting TextBox. But somehow the click event does not work. Other events work. How to make that work click?
this.Click += new EventHandler(AfyTransparentTextBox_Click);
private void AfyTransparentTextBox_Click(object sender, EventArgs e)
{
MessageBox.Show("KY-KY");
}
I don't know if this will be appropriate in your scenario but it works:
public class AfyTransparentTextBox : TextBox
{
protected override void OnClick(EventArgs e)
{
System.Windows.MessageBox.Show("KY-KY");
base.OnClick(e);
}
}

Can I get a MouseLeave event while Mouse.Capture() is active?

I have a button. On Button.MouseRightButtonDown, I'm calling Mouse.Capture(button), because I want to detect if someone releases right-click outside of the Button.
I also have a Button.MouseLeave event registered. If someone right-click-drags the mouse off the button, I want this event to trigger.
Unfortunately, it seems like Mouse.Capture somehow blocks MouseLeave from occuring.
Does anyone know a workaround, or maybe can point out where I'm going wrong?
(By the way, if anyone's curious what I'm doing this for, see my other question.)
When mouse is captured, you can use MouseMove and hit-testing to determine whether the mouse within your element or another.
protected override void OnMouseMove(MouseEventArgs e)
{
base.OnMouseMove(e);
if (this.IsMouseCaptured)
{
HitTestResult ht = VisualTreeHelper.HitTest(this, e.GetPosition(this));
if (ht != null)
{
DependencyObject current = ht.VisualHit;
while (current != this && current != null)
{
current = VisualTreeHelper.GetParent(current);
}
if (current == this)
{
Debug.WriteLine("Inside");
return;
}
}
Debug.WriteLine("Outside");
}
}
The following code can be used to avoid tree walk:
protected override void OnMouseMove(MouseEventArgs e)
{
base.OnMouseMove(e);
if (this.IsMouseCaptured)
{
bool isInside = false;
VisualTreeHelper.HitTest(
this,
d =>
{
if (d == this)
{
isInside = true;
}
return HitTestFilterBehavior.Stop;
},
ht => HitTestResultBehavior.Stop,
new PointHitTestParameters(e.GetPosition(this)));
if (isInside)
{
Debug.WriteLine("Inside");
}
else
{
Debug.WriteLine("Outside");
}
}
}
Following on from my answer to your related question, if you use CaptureMouse() from UIElement in place of Mouse.Capture(...) then you will see the correct behaviour.
public class MyButton : Button
{
protected override void OnMouseRightButtonDown(MouseButtonEventArgs e)
{
base.OnMouseRightButtonDown(e);
CaptureMouse();
}
protected override void OnMouseRightButtonUp(MouseButtonEventArgs e)
{
base.OnMouseRightButtonUp(e);
ReleaseMouseCapture();
}
protected override void OnMouseEnter(MouseEventArgs e)
{
base.OnMouseEnter(e);
Debug.WriteLine("Mouse enter");
}
protected override void OnMouseLeave(MouseEventArgs e)
{
base.OnMouseLeave(e);
Debug.WriteLine("Mouse leave");
}
}

Categories