Calling methods with parameters inside other methods - c#

I have this two methods that in the first look are fine.
But the problem is that e parameter of RadWizard2_NextButtonClick method is returning the value of e parameter of radTxb_TextChanged method.
I tried to change the name of e parameter in one of the methods but than returns me null all the time when in fact it should not.
Any idea why this is happening or where i am doing wrong??
protected void radTxb_TextChanged(object sender, EventArgs e)
{
//dothings
if (!opMsg.IsError)
{
RadWizard2_NextButtonClick(sender, e as WizardEventArgs); // arguments WITHOUT types
}
}

You have to create WizardEventArgs instance, e.g.:
protected void radTxb_TextChanged(object sender, EventArgs e) {
if (!opMsg.IsError) {
// It seems you have to provide some parameters:
// currentIndex and nextIndex which
RadWizard2_NextButtonClick(sender,
new WizardEventArgs(currentIndex, nextIndex));
}
}
If you inspect e instance, you'll find it of EventArgs type; and sice EventArgs has not been inherited from WizardEventArgs (quite the opposite is true: it is WizardEventArgs which is derived from EventArgs)
e as WizardEventArgs
returns null (e being EventArgs instabce can't be treated as WizardEventArgs instance)

I know i'm late to the party, however you might be able to just get away with null
protected void radTxb_TextChanged(object sender, EventArgs e)
{
//dothings
if (!opMsg.IsError)
{
RadWizard2_NextButtonClick(sender, null); // arguments WITHOUT types
}
}

Let me suggest a different approach.
You are trying to call a UI event handler directly. This is almost always a bad idea. Event handlers are designed to handle events, not to be used as library methods.
If you need the code from RadWizard2_NextButtonClick in your radTxb_TextChanged method, just extract it into a new method:
Before:
protected void RadWizard2_NextButtonClick(object sender, WizardEventArgs e)
{
... // some code here
}
After:
protected void RadWizard2_NextButtonClick(object sender, WizardEventArgs e)
{
DoStuff();
}
private void DoStuff()
{
... // some code here
}
You can now call DoStuff in your radTxb_TextChanged method.

When you need to do something, write a method that does exactly what you need. Give it a name that describes what it does, and give it only the arguments that it needs. Then you can call that method from event handlers or anywhere else. You can also put the method in a separate class so you can reuse it if needed across pages and keep the code-behind from getting too big.
It's peculiar that the built-in event handlers often contain vague arguments that aren't even used and aren't cast as the correct type, such as:
protected void radTxb_TextChanged(object sender, EventArgs e)
Obviously the sender isn't going to be any object. It's going to be a specific type of control. And the event args are also going to be of a particular type. The way they are cast implies that they don't matter, and in many cases they won't even be used. We know what happened just because the method fired, and we respond to that and ignore the arguments.
But we don't need to follow that convention. We can just write our methods according to their own requirements. If you want to do something with a RadWizard after an event has fired, you can just write the method you want:
public void DoSomethingWithTheRadWizard(RadWizard radWizard)
In the event handlers, extract whatever values you need from the arguments and then call your more specific method. It will be much easier to read and understand when all of the arguments are used and each is declared as the correct type.

Related

How can I trigger TypeValidationCompleted event from a method in c#?

Usually other event methods take object sender and EventsArgs e as an argument. For that matter it is easy to call most event methods from different event methods.
But for
TypeValidationCompleted(object sender, TypeValidationEventArgs e)
{
if (!e.IsValidInput)
{
}
}
the second argument is different. I want this method specially for (e.IsValidInput).
Is there a way to call TypeValidationCompleted(object sender, TypeValidationEventArgs e)
from a custom method or event method?

C# Trying to subscribe to an event in Unity

I'm using the Kinect v2 with Unity3D.
A class BodyFramReader has an event Framearrived that I wish to subscribe to.
Heres my code so far..
void Start()
{
man.kman._BodyReader.FrameArrived += this.FrameIn;
}
void FrameIn(BodyFrameReader sender, BodyFrameArrivedEventArgs a)
{
// Do something useful here.
}
I get the following error in visual studio.
It seems my delegate method is not right. If that is the problem how do I find the right parameters? If not, what am I doing wrong?
Your sender parameter doesn't match the parameter in EventHandler<TEventArgs> - it should be of type object:
void FrameIn(object sender, BodyFrameArrivedEventArgs e)
If you need the sender as a BodyFrameReader, you can cast to it within the method.

Call a function that has parameter type inside another function c#

i got this function on my form:
private void UpdateQuantityDataGridView(object sender, DataGridViewCellEventArgs e)
{
(...codes)
}
and i want to call that function inside another function, let's say when i click a "OK" button, this below function will run and execute above function that has parameter type.
private void button5_Click(object sender, EventArgs e) // This is the "OK" button click handler.
{
SubmitButton(sender, e);
}
private void SubmitButton(object sender, EventArgs e) // This is function of "OK" button
{
(...codes)
UpdateQuantityDataGridView("What should i put in here? I tried (sender, e), but it is useless")
}
I know that this function run when we put something like this:
dataGridView1.CellValueChanged += new DataGridViewSystemEventHandler(...);
But, i don't want that because that function will only run if the cell value in DataGridView has been changed, i want to access that function when i click "OK" button. But, what should i put inside a parameters value?
Extract the logic currently in the UpdateQuantityDataGridView() method and put it into a new public method named whatever you want, then you can call this logic from anywhere in your class or any other code that references your class, like this:
public void DoUpdateQuantityLogic()
{
// Put logic here
}
Note: If you do not actually use sender or e, then you can leave the method above without parameters, but if you do use e, for example, then you need to have a parameter for the DoUpdateQuantityLogic() method to account for what the property of the e object you are using is.
Now you can call DoUpdateQuantityLogic() from you other methods, like this:
private void button5_Click(object sender, EventArgs e) // This is the "OK" button click handler.
{
DoUpdateQuantityLogic();
}
private void SubmitButton(object sender, EventArgs e) // This is function of "OK" button
{
DoUpdateQuantityLogic();
}
This allows you to re-use your logic and also isolates the functionality into a method that makes unit testing easier, if you choose to unit test this logic.
If you are determined to use your existing event-based method infrastructure, then you can pass null for both the sender and the e arguments of the event handler, like this:
UpdateQuantityDataGridView(null, null);
If your method UpdateQuantityDataGridView() actually using the parameters sender and e? If not just pass null for both.
UpdateQuantityDataGridView(null, null);
If you are using them:
var e = new DataGridViewCellEventArgs();
// assign any properties
UpdateQuantityDataGridView(dataGridView1, e);
You can use sender, but you can't use e because UpdateQuantityDataGridView needs e to be of type DataGridViewCellEventArgs.
Depending on what your UpdateQuantityDataGridView handler wants to do with the e parameter, you could just pass null when you call it from your SubmitButton.
Otherwise, you'll have to new a DataGridViewCellEventArgs and populate it with the appropriate values your own handler requires/expects.

Best Practice with Common Event Handling

In a WinForms solution, you have multiple controls of the same type. You need to add an event handler to each of the control and at the current time the event handler will be doing the same thing. You do not expect there to be difference between them down the road any reason.
eg:
ScheduledPatientsGrid.ProcessGridKey += ScheduledPatientsGrid_ProcessGridKey;
RecentPatientsGrid.ProcessGridKey += RecentPatientsGrid_ProcessGridKey;
RecentPatientsGrid.ProcessGridKey += RecentPatientsGrid_ProcessGridKey;
...
private void ScheduledPatientsGrid_ProcessGridKey(object sender, KeyEventArgs e)
{
...
}
private void RecentPatientsGrid_ProcessGridKey(object sender, KeyEventArgs e)
{
...
}
private void PatientsGrid_ProcessGridKey(object sender, KeyEventArgs e)
{
...
}
Now is it better to sharing an single Event Handler between the different events as shown below or use different ones like in the code sample shown above?
ScheduledPatientsGrid.ProcessGridKey += ProcessGridKey;
RecentPatientsGrid.ProcessGridKey += ProcessGridKey;
RecentPatientsGrid.ProcessGridKey += ProcessGridKey;
private void ProcessGridKey(object sender, KeyEventArgs e)
{
...
}
In the following page, Microsoft seems to suggest that sharing is better, however I notice that they have not updated it since .NET 2.0 (ie: Visual Studio 2008)
http://msdn.microsoft.com/en-us/library/4ac48519%28v=vs.90%29.aspx
Is there a Guide that makes a best practices recommendation in this case?
I would absolutely use the same method. What possible benefit is there to having multiple methods which do exactly the same, none of which is named to say what it does?
Personally I abhor the source_EventName convention that Visual Studio spawns. I prefer to give my event handler methods meaningful names which say what they do. Then when you look down the event handler list in the designer, you can see that when a button is clicked, X will happen rather than "the button's click event handler will be called" which is useless.
Alternatively, use lambda expressions to subscribe to the events and call meaningful methods with meaningful parameters. (The sender and args are often useless for event handlers.)
In this case, I usually have them wrap a common method, but I keep their event handlers named per usage. This allows me to easily unit test the method and (usually) reduce the needed parameters, and any errors in the stack trace will be very readable as to which grid the process failed for:
ScheduledPatientsGrid.ProcessGridKey += ScheduledPatientsGrid_ProcessGridKey;
RecentPatientsGrid.ProcessGridKey += RecentPatientsGrid_ProcessGridKey;
RecentPatientsGrid.ProcessGridKey += RecentPatientsGrid_ProcessGridKey;
...
private void ScheduledPatientsGrid_ProcessGridKey(object sender, KeyEventArgs e)
{
ProcessGridKey(e.Key);
}
private void RecentPatientsGrid_ProcessGridKey(object sender, KeyEventArgs e)
{
ProcessGridKey(e.Key);
}
private void PatientsGrid_ProcessGridKey(object sender, KeyEventArgs e)
{
ProcessGridKey(e.Key);
}
private void ProcessGridKey(Key e)
{
...
}
Your mileage may vary depending on what the shared method does, or the parameters passed in. (For example, in my above sample, I duplicate the pulling of the Key from the KeyEventArgs.
I prefer sharing, if the logic gets out of hand you can always just use the single event as a router to the correct method like...
private void ProcessGridKey(object sender, KeyEventArgs e)
{
if (sender is x)
xmethod();
if (sender is y)
ymethod(); //etc
}
I'm aware this syntax doesn't quite make sense as the sender will always be the same object in OP example, but you get the idea.

How do I change the properties of a ContextMenuItem from inside an event handler

I'm slowly getting the hang of C# and this question is probably a result of bad design but here goes.
I have dynamic menus being generated thusly:
public Form1()
{
InitializeComponent();
AddContextMenu();
}
public void AddContextMenu()
{
ContextMenuStrip mnuContextMenu = new ContextMenuStrip();
mnuContextMenu.ItemClicked+=
new ToolStripItemClickedEventHandler(mnuContextMenu_ItemClicked);
this.ContextMenuStrip = mnuContextMenu;
ToolStripMenuItem mnuItemEnable = new ToolStripMenuItem("Enable");
mnuContextMenu.Items.Add(mnuItemEnable);
}
and the event handler:
private void mnuContextMenu_ItemClicked (Object sender,
ToolStripItemClickedEventArgs e)
{
//do stuff here
}
How do I change mnuContextMenu.Text (or any other property) from inside the event handler?
VS says :
mnuContextMenu does not exist in the
current context
There's a reason that all event handler methods have the exact same signature in the .NET world. You've probably noticed that the sender and e arguments are always there, no matter which event you're handling. They provide all the information you need.
In this particular case, you're looking for the sender parameter, which is a reference to the specific control that raised the event.
Of course, it's typed as an Object, so you'll have to cast it to a more derived type in order to use it like you want to. That's straight-forward enough—since you know that an ItemClicked event is only going to be raised by a ContextMenuStrip object, just cast it directly:
private void mnuContextMenu_ItemClicked (Object sender, ToolStripItemClickedEventArgs e)
{
((ContextMenuStrip)sender).Text = "Your text";
}
Or, if you want to play it safe (and you probably do), follow the standard idiom:
private void mnuContextMenu_ItemClicked (Object sender, ToolStripItemClickedEventArgs e)
{
// Try to cast the object to a ContextMenuStrip
ContextMenuStrip cmnu = sender as ContextMenuStrip;
// Verify that the cast was successful
// (if it failed, the cmnu variable will be null and this test will fail,
// preventing your code from being executed and your app from crashing)
if (cmnu != null)
{
cmnu.Text = "Your text";
}
}
There's absolutely no reason to litter your code with maintaining class-level references to these objects when there's a perfectly good, built-in way of obtaining references to exactly the ones that you want, when you want them.
mnuContextMenu only existed in the scope of AddContextMenu.
You have a couple of options:
this.ContextMenuStrip.Text = "Hello World";
or:
((ContextMenuStrip) sender).Text = "Hello World";
The first works because you stored the local mnuContextMenu in the class propery ContextMenuStrip. The second way casts the sender paramater (object raising the event) to a ContextMenuStrip.
Clearly it fails because you declare the context menu object inside the AddContextMenu method as local method variable instead of having it as private member of the containing class. the solution MegaHerz has suggested would probably work, or you keep a reference to your object as private member of the class.

Categories