Which button pressed in flowlayoutpanel? - c#

For my current project I am adding an variable amount of usercontrols : ucTask to my flowlayoutpanel : flpTasks
foreach (task t in tasks)
{
ucTask uct = new ucTask();
uct.id = t.task_id;
uct.date= t.date.ToString();
uct.btnNaam = t.task_id.ToString();
uct.OnButtonclick += new EventHandler(uct_OnButtonclick);
flpTasks.Controls.Add(uct);
}
Now I will have a couple of those usercontrols in the flowlayoutpanel, and I want to fire an event when I press that button. With the EventHandler I can fire an event, but I need to fire a different event for a different button.
void uco_OnButtonclick(object sender, EventArgs e)
{
lblStatus.Text = "TEST";
}
I don't know how to know which button (or usercontrol) I pressed. And I'm out of ideas, any suggestions?
Thanks,
Thomas

Sender of event is actually one of buttons. When you cast sender to Button type, you can access any of Buttons properties and determine which button was pressed:
void uco_OnButtonclick(object sender, EventArgs e)
{
Button button = sender as Button;
if (button == null)
return;
lblStatus.Text = button.Name;
}
UPDATE: after reading your question once again, I get that ucTask is actually UserControl, which rises event when button inside it was clicked.
So, first is naming. Good style for class names in c# is PascalCase. E.g. for task user control good name will be TaskControl. Next goes event naming. It's common to name events as EventName(-ing, -ed). If you want to raise event, then good style is protected method OnEventName(-int, -ed). And another remark - when you writing user controls, you are free to use business terms to name your events. E.g. TaskCreated, TaskChanged. And you also can pass any parameters to your event by creating custom EventArgs.
So, for your user control:
public class TaskChangedEventArgs : EventArgs
{
public TaskChangedEventArgs(int taskId)
{
TaskId = taskId;
}
public int TaskId { get; private set; }
}
public class TaskControl : UserControl
{
public event EventHandler<TaskChangedEventArgs> TaskChanged;
// raise it inside button click event handler
protected void OnTaskChanged(int taskId)
{
if (TaskChanged != null)
TaskChanged(this, new TaskChangedEventArgs(taskId));
}
}
When you use your user control, just subscribe to its TaskChanged event:
uct.TaskChanged += new EventHandler<TaskChangedEventArgs>(uct_TaskChanged);
And all parameters, that you passed via event argument will be available in that event handler:
void uco_TaskChanged(object sender, TaskChangedEventArgs e)
{
lblStatus.Text = e.TaskId.ToString();
}

Well, the sender should be the user control right? Then you can cast and determine the item through ucTask.id.
void uco_OnButtonclick(object sender, EventArgs e)
{
ucTask uc = sender as ucTask;
lblStatus.Text = uc.id.ToString();
}
This presumes that the OnButtonclick event of the user control sends a reference to the user control and not a reference to the pressed button as the sender of the event.

Related

how to retrieve text of buttons clicked in windows form with one single method

I have a windows form application with multiple buttons. I need to retrieve the text property of any button clicked in order to create a query to the database. the only way I know is to create a button click event and cast the sender as button then do a switch case for each button Id which seems very hectic since I probably will have more than 100 buttons in the entire application. So my question is there a generic key press method I can create which can retrieve the text property of any button pressed/clicked on the form? Please excuse me if the question is not very clear. Any help will be appreciate
Use a single click event handler for all similar kind of buttons. This way there will be click event subscribed for every button but only one method which will be executed for all buttons. You can determine which button was pressed as follows.
Using sender object as follows;
private void button_Click(object sender, EventArgs e)
{
var buttonText = ((Button)sender).Text;
//Query using buttonText
}
Update:
Above answer will still require you to subscribe click event for each button. If you don't want that then have a look at following approach;
You could use (ClickTransparentButton or) disable (Enabled=false) all these buttons and add click event on parent Form. Once you get click event you can get button which was clicked as follows;
private void Form1_Click(object sender, EventArgs e)
{
var p = PointToClient(Cursor.Position);
var control = GetChildAtPoint(p);
if(control is Button)
{
var buttonText = ((Button)control).Text;
//Query using buttonText
}
}
But this has few disadvantages such as, you will not be able to operate these buttons using keyboard.
and more...
Create some function as buttons click handler:
private void buttonClickHandler(object sender, EventArgs e)
{
string buttonName = (sender as Button).Text;
}
2A. Connect Click event of every button to this handler.
2B. To automate connection of button click handler use something like that:
private void connectButtonsHandlers()
{
foreach(var c in this.Controls)
{
if(c is Button)
{
(c as Button).Click += buttonClickHandler;
}
}
}
Add this code to form constructor to perform connection at program start.

Passing a button to an event handler

I want to pass a button to an event handler outside the scope of the button object.
For example:
void OnClick2(object sender, EventArgs e)
{
button123.text="changed";
}
So I want my click to change the text of a button passed to it. Is there a way to do this other than having the button in scope- can I pass the button object to the event handler somehow?
I am not 100% sure of your question but here is an attempt to answer it.
void ButtonClicked(object sender, EventArgs e)
{
Button button = sender as Button;
if (button != null)
{
button.Text = "changed";
}
}
This allow you to handle any button click and it will change that buttons text.

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);

button should refer to itself in C#

Assuming there are buttons with all the letters from the alphabet set as Text.
I want to call a function in these buttons and use this letter as argument.
Can I use the same piece of code for each button in some way?
something like
functionname(this.Text);
Problem is, that "this" referrs to the Form and not to the specific button.
In most event mechanisms you can obtain the source of the event; in classic win forms vents this is typically called "sender". You can cast the sender to what you know it is, or some common base-type. For example:
void SomeEventHandler(object sender, SomeEventArgs e) {
string text = ((Control)sender).Text;
// ...
}
Hence with this a single event-handler can handle all the buttons.
This may vary subtly between infrastructure / tools (WCF, XNA etc) but fundamentally should remain similar.
Try an event handler like this:
protected button1_click(sender as object, e as EventArgs) {
var button1 = (Button) sender;
if (button1.Text == "A") {
//for example
}
}
You will then need to add the event handler, either in "on load" using AddHandler... or if it's an Asp.net page you can use the onClick="button1_click" attribute.
For a more specific answer, I would need some more details.
You could use the same event handler for every button on the form:
private void Form_Load(object sender, System.EventArgs e)
{
foreach (var btn in this.Controls.OfType<Button>())
{
btn.Click += AllButtonClick;
}
}
private void AllButtonClick(Object sender, EventArgs e)
{
Button btn = (Button)sender;
String buttonText = btn.Text;
}

Custom Component On Click Event

I've built a custom component that basically has a picture box and label in it. In the parent form, I want to be able to detect when its been clicked on. The standard .click event doesn't seem to be working, but I've never used events before so am unsure if I'm using them correctly. Heres the code I'm using (in the parent) to try and make it recognise the click:
Item aItem = new Item();
aItem.Icon = ItemImage;
aItem.Title = Title;
aItem.Click += new EventHandler(ItemClicked);
aItem.Filename = File;
and heres the method its calling:
public void ItemClicked(Object sender, EventArgs e)
{
MessageBox.Show("Item Clicked!");
}
This code never fires. Do I need to put anything into the component or am I just doing this wrong?
Cheers
Right I finally worked it out. Tejs response just confused me more so here's what I did.
In my UserControl I had the following event:
public event EventHandler Clicked;
Then I had an event for when the image was clicked (still in the UserControl) and I just called the Clicked event:
private void imgItem_Click(object sender, EventArgs e)
{
Clicked(this, e);
}
Then in my parent form, when I created the object, I had the following:
Item aItem = new Item();
aItem.Clicked += new EventHandler(ItemClicked);
void ItemClicked(object sender, EventArgs e)
{
MessageBox.Show("Clicked!");
}
You would do this by exposing an event':
Your custom component:
// A custom delegate like MyItemClickedHandler, or you could make a Func<> or Action<>
public event MyItemClickedHandler ItemClickedEvent;
public void ItemClicked(object sender, EventArgs e)
{
if(ItemClickedEvent != null)
ItemClickedEvent(); // Your delegate could pass parameters if needed
}
Then your parent form simply observes the event:
myCustomControl.ItemClickedEvent += new MyItemClickedHandler(SomeMethod);
Then, whenever the event is raised on your custom control, the parent is notified because it subscribed the event.

Categories

Resources