one click calls both Click and LinkClicked event handlers - c#

LinkLabel label = new LinkLabel();
// imagine there is a code to initialize the label
label.Click += (sender, args) => callback1();
label.LinkClicked += (sender, args) => callback2();
If I click the label anywhere but not its link then callback1() is called which is correct.
If I click the label's link then both callback1() and callback2() are called.
How do I make it call callback2() only?

Two solutions I can think of. First one is a very silly one but looks pretty effective. You don't like Click when the mouse hovers over a link. Which has a side-effect, the mouse cursor changes. So you could filter by checking the cursor shape:
private void linkLabel1_Click(object sender, EventArgs e) {
if (Cursor.Current == Cursors.Default) {
Debug.WriteLine("Click!");
// etc...
}
}
A bit more principled and handy if you have a lot of link labels is to not raise the Click event at all if the mouse is over a link. Add a new class to your project and paste this code:
using System;
using System.Windows.Forms;
class LinkLabelEx : LinkLabel {
protected override void OnClick(EventArgs e) {
var loc = this.PointToClient(Cursor.Position);
if (this.PointInLink(loc.X, loc.Y) == null) base.OnClick(e);
}
}

I don't see a way to do that.
As you can see in the reference source, LinkLabel is derived from Label. The Click event is raised by the Label base class. You can see in the code that the base methods like OnMouseDown and OnMouseUp are always called before the LinkLabel handles those events.
So the Label base implementation will always raise a Click event before the LinkClicked implementation raises the LinkLabel event. There is no property or flag to prevent that.
You hopefully can achieve what you want in a different way.

Related

WPF MouseLeftButtonDown makes FlowDocument unable to select text

I add a function that adds text to FlowDocument when the mouse clicks.
There is no Click event in FlowDocument, so I listen to FlowDocument.MouseLeftButtonDown and MouseLeftButtonUp and check whether the mouse moves between down and up. When I click the mouse left button, the text successfully adds. However, I can't select any text in the FlowDocument.
I tried PreviewMouseLeftButtonDown and PreviewMouseLeftButtonUp. The behavior is the same. Isn't there a PostMouseLeftButtonDown?
My Code:
Point mouseDownPoint;
private void doc_MouseLeftButtonDown(object sender, MouseButtonEventArgs e)
{
mouseDownPoint = Mouse.GetPosition(doc);
e.Handled = true;
}
private void doc_MouseLeftButtonUp(object sender, MouseButtonEventArgs e)
{
var mouseUpPoint = Mouse.GetPosition(doc);
if ((mouseUpPoint - mouseDownPoint).Length < 8) /* add text */;
}
The control handles the event internally.
If you register the event handler programmatically like this, your doc_MouseLeftButtonUp event handler should get invoked (note that last handledEventsToo parameter):
doc.AddHandler(ContentElement.MouseLeftButtonUpEvent,
(MouseButtonEventHandler)doc_MouseLeftButtonUp, true);
Note that you may also have to take care of the MouseLeftButtonUp that is raised by the control itself.
I found the solution. Listen to FlowDocument.MouseLeftButtonDown and do not use e.Handled=true and listen to FlowDocumentScrollViewer.PreviewMouseLeftButtonUp will get text selection and add text behavior at the same time.

Button click event not responding c#

The problem we are having is accessing the click event for a button which is created in the click event of another button i.e. clicking the first button generates a new panel and controls, and we now want the button on this newly created panel to perform an action.
The controls have been declared at the top of the class as follows:
Panel createElementPage = null;
TextBox elementDescription = null;
TextBox elementName = null;
Button continueButton = null;
AuditSystem audit;
Here is an excerpt of the method that generates the new panel, the part that defines the continueButton is written as follows:
public void CE_Click(object sender, EventArgs e)
{
createElementPage.Controls.Add(elementDescription);
continueButton = new Button();
continueButton.Text = "Continue";
continueButton.Location = new Point(700, 500);
continueButton.Size = new Size(100, 50);
createElementPage.Controls.Add(continueButton);
}
We want to access the continueButton's click event handler but the method we have written does not seem to be working. This is what we have so far:
private void continueButton_Click(object sender, EventArgs e)
{
Console.WriteLine(" something");
}
Clicking the button yields no results, and we have tried a few solutions such as implementing a seperate eventHandler method. Does anybody have a fix for this?
You have to actually subscribe to the event:
continueButton.Click += continueButton_Click;
Events need to be told what they should handle. Without that, they won't "listen" to anything.
Friendly note: be careful when adding handlers "on demand" like this (i.e. outside of the designer). It doesn't really apply here (you have a new button each time), but it's fairly easy to accidentally subscribe to a control's event multiple times, and your handler will fire multiple times as a result. It's just nice to be aware of :)

user control and raising events from controls placed in user control

So I would like to know what is wrong with the following code, especially from a theoretical point of view.
I have a user control in which I've added a text box.
When I click in the text box I would like the Mouse clicked event raised in the user control.
To my mind, the solution should be:
Create an event handler for the mouse click event in the text box.
in this event handler, raise the mouse click event for the user control.
so this is what i have:
private void txtLog_MouseClick(object sender, MouseEventArgs e)
{
this.OnMouseClick(e);
}
i have tried it and it doesn't work, why is this?
P.S. I would really like to know why this is wrong! A correct solution is great, but I'm really trying to understand where I'm going wrong here. Thank :-)
Well, you could just click on your textbox in design mode and in the property window in events tab add the click event. or if you want to do it in runtime you can do it like this:
textbox.Click += Txt_Click;
private static void Txt_Click(object sender, EventArgs e)
{
// do your thing
}
or even shorter:
textbox.Click += (s,e) =>
{
//do your thing
};
you should do these three steps
declare an MouseClick delegation method for textbox
assign method to textbox
add this delegation to the this (form) OnMouseClick event [on user control constructor]
Step1:
private void textBox1_MouseClick(object sender, MouseEventArgs e)
{
}
Step2:
this.textBox1.MouseClick += new System.Windows.Forms.MouseEventHandler(this.textBox1_MouseClick);
Step3:
public myUserControl()
{
InitializeComponent();
this.MouseClick += new MouseEventHandler(textBox1_MouseClick);
}

Windows Forms - get Text value from object of type button

I have a Windows form named Form1 and panel within this form named panel1. I use the panel only to place buttons there so that I can group them and work with them separately from the other buttons in my Form1. For the purpose of my program I need to handle every button click made from the buttons inside panel1. For this purpose I use the same code snippet:
public Form1()
{
InitializeComponent();
// Set a click event handler for the button in the panel
foreach (var button in panel1.Controls.OfType<Button>())
{
button.Click += HandleClick;
}
}
What I need to do is to have a way to identify which button exactly has been clicked. For this purpose I played a little bit with my handler method:
private void HandleClick(object o, EventArgs e)
{
MessageBox.Show("HI" + o.ToString());
}
which gave me some hope because I get this:
It's the second part - Text: button4 which is actually enough information to continue with my work. But I can't find a way to get this piece of information without some complicated string manipulations. So is there a way to get this or other unique information about the button been clicked given the way I have written my code?
private void HandleClick(object sender, EventArgs e)
{
var btn = sender as Button;
if (btn != null)
{
MessageBox.Show(btn.Text);
}
}
One option is to cast the object to a Button, but rather than doing the casting you can change how the event handler is assigned so that you don't need to cast in the first place:
foreach (var button in panel1.Controls.OfType<Button>())
{
button.Click += (_,args)=> HandleClick(button, args);
}
Then just change the signature of HandleClick to:
private void HandleClick(Button button, EventArgs e);
You need to cast sender to the Button class so you can access its properties:
Button b = (Button)sender;
MessageBox.Show(b.Text);

WinForm - Don't allow radio button to be tabbed into

Since TabStop does not work on RadioButtons (see linked question), how can I prevent a (WinForm) RadioButton from being tabbed into, but also allow the user to click on the RadioButton, without the tab focus jumping somewhere else.
I've read this and so I thought the following would work:
rbFMV.Enter += (s, e) => focusFirstWorkflowButton();
rbFMV.MouseUp += (s, e) => rbFMV.Focus();
But it doesn't. When I click on the RB, the focus jumps away, and does not come back on Mouse Up.
Any dirty workarounds out there?
Try something like this:
Set TabStop property of the radiobuttons to "false" in the form's constructor. Then attach the following events handlers to the CheckedChanged events of the radiobuttons.
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
radioButton1.TabStop = false;
radioButton2.TabStop = false;
}
private void radioButton1_CheckedChanged(object sender, EventArgs e)
{
radioButton1.TabStop = false;
radioButton2.TabStop = false;
}
private void radioButton2_CheckedChanged(object sender, EventArgs e)
{
radioButton1.TabStop = false;
radioButton2.TabStop = false;
}
}
You can attach these event handlers using lambda aswell, as you have shown in your question.
But the important point here is that whenever a radiobutton is checked/unchecked, it's tabstop property is also modified simultaneously. Hence you need to set it to false everytime that event occurs.
The underlying Win32 RadioButton does not automatically change the TabStop property. However, if you use .NET Reflector you can see that the .NET control runs code to update the TabStop property whenever OnEnter method is called because focus has entered the control or whenever the AutoCheck or Checked properties are modified.
Luckily there is a simple solution to your problem. Just derive a new class that overrides the OnTabStopChanged method and automatically set it back to false again. Here is the impl...
public class NonTabStopRadioButton : RadioButton
{
protected override void OnTabStopChanged(EventArgs e)
{
base.OnTabStopChanged(e);
if (TabStop)
TabStop = false;
}
}
Then always use the NonTabStopRadioButton in your application instead of the standard one.
only one control can have input focus at the time i think, so when they click the radio button it will get focus..
But what if you do something like this?
rbFMV.GotFocus += (s, e) => someothercontrol.Focus();
also, have you looked at the TabStop property?
-edit-
i see you have, sorry, missed that :/

Categories

Resources