C# Trying to subscribe to an event in Unity - c#

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.

Related

Calling methods with parameters inside other methods

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.

Get the Vertex(Node) Object user clicked on in MSAGL

So, what is the way to retrieve the object that was under the mouse pointer when user clicked? I assume the gViewer must have some event to do that. In the tutorial i found this idea:
gViewer.SelectionChanged +=
new EventHandler(gViewer_SelectionChanged);
with gViewer_SelectionChanged being an event handler defined like this:
void gViewer_SelectionChanged(object sender, EventArgs e)
Although i added using statments for all 3 MSAGL dll's, i can't find the
Selection changedevent. Is there a special event for that, or am i looking the wrong way? Can it be that i need to handle some mouse event and get object based on it?
Sadly, there are only few MSAGL samples, no documentation and limited comments, so the more questions abount it here - the better.
do you mean get the infomation of each object?
viewer.Click += GraphNode_Click;
...
private void GraphNode_Click(object sender, EventArgs e)
{
GViewer viewer = sender as GViewer;
if (viewer.SelectedObject is Node)
{
Node node = viewer.SelectedObject as Node;
//...do works here
}
}
The code can not work:
viewer.Click += GraphNode_Click;
It should be like:
viewer.Click += EventHandler(Group_Click);

How to call treeView.SelectedItemChanged programmatically

In my program I would like to call to a SelectedItemChanged event using c# code-behind, I am just unsure about what to pass as parameters. This is for a TreeViewItem.
//Gets selected item in TreeView
private void TreeOne_SelectedItemChanged(object sender, RoutedPropertyChangedEventArgs<object> e)
{
MainWindowViewModel.SelectedItem = e.NewValue as TreeViewItem;
}
//I'm calling the SelectedItemChanged event from a RightButtonDown event
private void TreeOne_MouseRightButtonDown(object sender, MouseButtonEventArgs e)
{
TreeOne_SelectedItemChanged(/* What would go here? **/);
}
Also, when I try to build this I receive this compiler error that pretty much led to this question...
No overload for method TreeOne_SelectedItemChanged takes '0' arguments
I'm hoping that this is an easy question, but if I have not provided enough information, or haven't been clear enough please let me know.
Adding to #Bart Friederichs' answer and assuming that you have a reference to your TreeView, you could add the following method:
private void SetSelectedItem()
{
MainWindowViewModel.SelectedItem = TreeOne.SelectedItem;
}
Then you can simply call this from wherever you like:
private void TreeOne_SelectedItemChanged(object sender, RoutedPropertyChangedEventArgs<object> e)
{
SetSelectedItem();
}
private void TreeOne_MouseRightButtonDown(object sender, MouseButtonEventArgs e)
{
SetSelectedItem();
}
The usual design pattern would be to call some kind of processing method, and not to "manually" fire events:
private TreeOne_SelectedItemChaned(object sender,
RoutedPropertyChangedEventArgs<object> e) {
processChange();
}
Then, from withing your code, you just call processChange(), no need to call TreeOne_SelectedItemChanged.
try to call
TreeOne_SelectedItemChanged(null, null);

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.

Is there a way to not create an explicit EventHandler delegate in Visual Studio?

Visual Studio likes to be helpful when typing:
Event +=
by generating code like:
Event += new EventHandler(EventClassName_Event);
void EventClassName_Event(object sender, EventArgs e)
{
throw new System.NotImplementedException();
}
Ideally I would like to remove the explicit delegate and add an explicit private. Like so:
Event += EventClassName_Event;
private void EventClassName_Event(object sender, EventArgs e)
{
throw new System.NotImplementedException();
}
I've looked to see if there is a snippet, but found nothing. Any suggestions? I do have ReSharper installed if there is a way that it can do this.
With Resharper if I type:
myObject.SomeEvent +=
then hit Ctrl-Shift-Space, I get the option to create a method or a delegate (or to use an existing method).
I think this is what you want.

Categories