Just what the h can we do with "sender" - new guy question

  • Thread starter Thread starter T.Davis
  • Start date Start date
T

T.Davis

Okay, when you subscribe to an event, and that event fires, it is
passed (sender, eventargs), yea?

So what is sender? Can you do anything with it other than toString()?

If it's a reference to the object that fired the event, how can I
access that object's properties?


I'm new, and am trying to get my sea legs. I've got an application
that fills a treeview with tables from a mysql database.

I've added a context menu. I want one of the items to be "load this
table." In order for that to work, I need to get the text of the
treeview node. How do I do this?

treeview

+ blah table <-- context menu from this part, select "Load this
table" Need to get "blah"
- id
- name
- isugly

+ blah_again table
- id
- name
- description


Thanks in advance.

ps.

i find the word "newbie" icky.
 
Well, assuming you know the type of sender, you just have to cast to it.
So if it was a menu item, you cast it to MenuItem, if it was a button, you
cast it to Button, etc, etc.
 
I use it in cases where I have the possibility of receiving an event
that I send. I ignore events sent from myself. In that case all you
have to do is a pointer compare (== by default on classes) without
casting the object.
 
All apologies, but how do you cast event sender object in c#?

string s = (string)sender;

like so?
 
Yes, if the sender object represents a string.

I think, however, tht you would be hard pushed to find a sender object (in
the context of event handlers0 that does.

When you subscribe a handler to an event, you are in control so you know
what the object types are going to be.

For example, in a handler for a button click event, the sender will
invariably be of type Button. Therefore you cast it to a button:

Button _button = (Button)sender;

If, for some obscure reason, you subscribed the same handler to events from
different types then you would need to cater for, (in your code), the
different types involved.
 
Nicholas Paldino said:
Well, assuming you know the type of sender, you just have to cast to it.
So if it was a menu item, you cast it to MenuItem, if it was a button, you
cast it to Button, etc, etc.

And even if you don't know the exact type of the event sender object but
have some reasonable assumption what it *could* be, you should have a look
at the very usefull 'is' and 'as' keywords.


You can check the sender type with a simple:
if (sender is MyClassXYZ) { ... }

And afterwards use it with the named cast:
((MyClassXYZ)sender).doThisOrThat()


Or assign a variable with as, having a similar result:

MyClassXYZ EventSender = sender as MyClassXYZ;
if (EventSender != null) {
EventSender.doThisOrThat();
}


These are very handy constructs in situations where you want to have a
single event handler e.g. for events of different object instances derived
from a common mother class.

Greetings,
Hans
 
All apologies, but how do you cast event sender object in c#?

string s = (string)sender;

like so?



- Show quoted text -

String is a bad example as strings don't raise events. Take a look at
the following example. It's very simple. One form, two buttons using
the same click handler to increment their label. Watch for line wrap.

using System;
using System.Drawing;
using System.Collections;
using System.ComponentModel;
using System.Windows.Forms;

namespace WindowsApplication30
{
public class Form1 : System.Windows.Forms.Form
{
private System.Windows.Forms.Button button1;
private System.Windows.Forms.Button button2;

private System.ComponentModel.Container components = null;

public Form1()
{
InitializeComponent();
}
protected override void Dispose( bool disposing )
{
if( disposing )
{
if (components != null)
{
components.Dispose();
}
}
base.Dispose( disposing );
}

#region Windows Form Designer generated code
private void InitializeComponent()
{
this.button1 = new System.Windows.Forms.Button();
this.button2 = new System.Windows.Forms.Button();
this.SuspendLayout();

this.button1.Location = new System.Drawing.Point(16, 16);
this.button1.Name = "button1";
this.button1.Size = new System.Drawing.Size(112, 40);
this.button1.TabIndex = 0;
this.button1.Text = "1";
this.button1.Click += new System.EventHandler(this.button_Click);
this.button2.Click += new System.EventHandler(this.button_Click);

this.button2.Location = new System.Drawing.Point(16, 64);
this.button2.Name = "button2";
this.button2.Size = new System.Drawing.Size(112, 40);
this.button2.TabIndex = 1;
this.button2.Text = "1";

this.AutoScaleBaseSize = new System.Drawing.Size(5, 13);
this.ClientSize = new System.Drawing.Size(292, 266);
this.Controls.Add(this.button2);
this.Controls.Add(this.button1);
this.Name = "Form1";
this.Text = "Form1";
this.ResumeLayout(false);
}
#endregion

[STAThread]
static void Main()
{
Application.Run(new Form1());
}
private void button_Click(object sender, System.EventArgs e)
{
if(sender is Button)
{
Button b = (Button)sender;
int c = int.Parse(b.Text);
c++;
b.Text = c.ToString();
}
}
}
}
 
Hi,
In the context you describe the sender is not much use to you.

The problem is that the sender is the context menu.
The data that you want to deal with is in the treeview.

There may be a more elegant way but what I do here is capture
where you are in the treeview with the mousedown event into a global
point say mPosition.
The context menu decides what action to take
And in that code you reference the treeview by using
currentnode=myTreeView.mygetnodeat(mPosition)
hth
Bob
 
Back
Top