C# (object sender, RoutedEventArgs e) Properties - c#

Visual Studio keeps saying (object sender, RoutedEventArgs e) properties are not used and to remove them. But if I do, it errors out the MainPage.g.cs reference. What should I do?
//MainPage.Xaml.cs
private void TextBoxSingleArray_GotFocus(object sender, RoutedEventArgs e)
{
var textBoxSingleArray_GotFocus = e.OriginalSource as TextBox;
textBoxSingleArray_GotFocus.SelectAll();
}
//MainPage.g.cs
//If I remove object sender, this will display error
((global::Windows.UI.Xaml.Controls.TextBox)this.TextBoxSingleArray).GotFocus += this.TextBoxSingleArray_GotFocus;

There are two ways to solve this.
1) Remove the name of the parameters using "discards" .
REf. https://learn.microsoft.com/en-us/dotnet/csharp/discards .
The error you see is due to you are not using those parameters inside the method.
2) Disable the warning:
Ref https://learn.microsoft.com/en-us/dotnet/csharp/language-reference/preprocessor-directives/preprocessor-pragma-warning
Ref http://www.blackwasp.co.uk/SuppressWarnings.aspx
You just cannot simply remove the parameters since TextBoxSingleArray_GotFocus is a referenced event that requires to receive those two parameters. Even if you don't use them.
Hope it helps.
Juan Simon

I've seen messages like that (not in that particular case, though) from ReSharper (do you have that installed?), but Visual Studio itself may also do something similar.
Often, messages like that can help you keep your code cleaner... or sometimes catch bugs because it highlights when something you thought was being used is actually being missed. But in some cases, such as when creating a library with a public API but that isn't fully used within the same solution and leaves some "public" members unused, a suggestion such as "can be made private" isn't really true--it just has no way of knowing that.
This sounds like a similar case. You have arguments which are required for an event handler, but until it is used as an event handler somewhere within your code it wouldn't know that and might warn you that they aren't being used. Or, properties on the RoutedEventArgs aren't being referenced within the handler (or elsewhere in the code that it can see), so it gives you that warning and suggestion. But really, they are required--just perhaps not within your solution--and you can't really remove properties from a defined event args type that comes from WinForms, anyway.
But, you generally want to take note of messages like and consider whether the suggestion applies or if you have missed using something you should--or maybe you're just still in the middle of coding it and it might go away once you're done. If it's really a warning (shows up in the Errors box after a build) you may want to suppress it around the unavoidable cases where you know you don't want to access the other properties to "fix" it, but as #HereticMonkey commented, it's probably just a suggestion and not an actual warning. The main reason to suppress it is so that other, real, warnings aren't missed and can be attended to (or similarly suppressed if not important). Either way, as long as it's not preventing it from building successfully, you don't have to follow the suggestion--because it's not always right.

I believe you can get VS to be quite about this by naming your parameters _ and __.
Alternatively, you could add a SuppressMessage annotation to your method.

Related

What would cause WinForms richTextBox.DataBindings.Add() to throw a Null Reference Exception?

I have scratched my head on this for a while and just can't figure it out. I even spun up a brand new test project and cannot reproduce the error that I'm getting in my primary project.
The code in question is this:
private void FormMain_Load(object sender, EventArgs e)
{
Binding myBinding = new Binding("Text", _gizmo, nameof(_gizmo.MyProp));
richRmDesc.DataBindings.Add(myBinding); //NullReference exception occurs on this line
}
I checked in Debugger.
myBinding is NOT null.
_gizmo is a brand new Gizmo object. It's NOT null.
_gizmo.MyProp is a string. It's got text in it.
Even richRmDesc.DataBindings is NOT null. I can inspect all the fields
and properties of the DataBindings member without issue.
The error has me completely stumped.
I've tried to simplify my form and startup code as much as possible, short of completely demolishing everything I've built on it (which I'm going to try next, but it's going to be slow and painful).
Does anybody know of a possible reason on why I'd get a Null reference exception on the DataBindings line when none of the items are even null?
So I thought it would be a big deal to demolish my form components. It was in fact extremely easy with minimal refactoring (pays to write well-abstracted code).
I reduced the culprit to this line in the form class generated by the Designer:
this.richRmDesc.TextChanged += new System.EventHandler(this.RichDesc_TextChanged);
So when I looked at the RichDesc_TextChanged event method, I discovered that it was invoking another method that was referencing a null collection because it had not yet been initialized. This was in some run-of-the-mill logic in the form itself.
For whatever reason, the debugger was completely unable to show me that the exception was actually happening in the TextChanged event. It wasn't even giving me an indication that the event was firing, though it makes sense that it would fire immediately upon binding.
I fixed the initiailization bug pertaining to the TextChanged event logic and now everything is fine.
I'm guessing that the debugger could not detect this event bug because it was happening on another thread??? Not sure really. Comments are welcome.

"Click" - Delegate to an instance method cannot have null 'this'

I know there are alot of questions allready to this topic. But I can't really seem to understand this whole delegate stuff. I'm kinda at a point where I just want it to work and move on. Everytime when I look at delegates I think to myself, there has to be a way to make this much easier to understand and do, but I can't seem to find it.
I have a FlowLayoutPanel that will be filled with a bunch of Panels. each of those panels needs to have a OnClick (or Click?) method to be attached to it.
So I went ahead and wrote (inside of the creator of my personal panel class):
IntDrawForm form = FindForm() as IntDrawForm;
Click += form.PointPanelClick;
And I ended up with the error message Delegate to an instance method cannot have null 'this' when tried to create one my panels.
Yes, that will happen if FindForm() returns either null, or something that isn't an instance of IntDrawForm. There's nothing particularly specific to delegates here - you'd get a similar result if you tried this as your second line:
form.CallSomeMethod();
(In that case it would be a NullReferenceException.)
Given that the second line basically fails when form is null, you shouldn't use as here - use a cast instead. That way, the first line will fail if you don't have an IntDrawForm, and you'll get a more informative exception.
IntDrawForm form = (IntDrawForm) FindForm();
Now we can't tell why FindForm() has returned either null or a non-IntDrawForm, but that's a different matter.

What is the right way to invoke a button's click event?

Here: http://msdn.microsoft.com/en-us/library/hkkb40tf(v=VS.90).aspx, it says that, to call a button's click event from another button, you can/should do it this way:
button1.PerformClick();
However, in my situation (VS 2003. NET 1.1), this doesn't compile (admittedly, the link above specifies VS 2008, but it does not have a link to the pertinent info for prior versions, as msdn often does).
This compiles:
private void btnPrint_Click(object sender, System.EventArgs args)
{
if (this.recordChanged)
{
//btnSave.Click();
btnSave_Click(sender, args);
}
. . .
...but I don't know if it's THE way to do it.
Put the business logic that you want to execute in a separate method (e.g. DoSave()), and then your event handlers can both just call that internal method rather than calling each other directly.
"Faking" events by calling the event handler methods directly is ugly and can lead to bugs (any programmer modifying the event handler in future may be unaware that it could be called under different conditions than expected/documented, which could cause the print option to behave strangely or even crash when it tries to do a save operation)
Also there is a good chance that you may want to cause a save operation from somewhere else in future - so it's always a very good idea to keep the business logic separate from the use interface that activates it.
I would do btnSave.Click(sender, args);. Here's the page on MSDN: http://msdn.microsoft.com/en-us/library/aa645739(v=VS.71).aspx

Why pass dummy object to Event Handler in C#?

the following is a function that invokes the event and thus notifies all clients.
public static void OnEventXYZ(XYZEventArgs e)
{
if(EventXYZ!=null)
EventXYZ(new object(),e);
}
This is from a sample code.
What i want to know is "What is the significance of new object()?
is this a syntax followed or only for this situation?
Normally you pass this as the sender parameter of an event handler.
However, in this case, the event is static so you cannot use this. The person who wrote that sample chose to pass new object() instead. I think most people would pass null instead but that's really a matter of personnal preference.
That parameter is for the sender of the event. Normally, you would use this, but that will not work in the static context.
EventXYZ seems to have been written to expect a sender (typical with event handlers). In the case of the static "On"blahBlah event raiser, the sender isn't really dealt with clearly. As another responder posted, it seems to be an attempt to satisfy the sender property of the event args that are passed along to the handler.
A more correct implementation would likely either omit the sender from the EventArgs or allow the static "OnBlahBlah" method an argument that allows the caller to specify the sender.
The use of "new object()" in this case seems like confusing fluff, IMHO. But, then again, we don't technically know the signature of the constructor being used in this case... perhaps the first argument is meant to be "Some random object that will be used as the thing we can blame later when your hard drive gets formatted".. maybe a new, empty, meaningless object is perfect for this.
Another thing to look for is that you may consider rewriting the code to be this:
public static void OnEventXYZ(XYZEventArgs e)
{
var evt = EventXYZ;
if(evt != null)
evt(new object(),e);
}
.. In a nutshell, that is a typical "sender as first argument" pattern that you see in 99% of event args / event handlers. Better examples will probably make more sense.
You can also use ILSpy or Reflector to look at the thousands of event raisers/handlers in the .NET runtime to get better examples of how the common patterns are coded.
EDIT: BTW, it's unusual to see static OnEvent raisers... it's a little odd. Not technically correct, but it sure messes up the typical "'this' as sender" pattern.
Cheers!

In a C# event handler, why must the "sender" parameter be an object?

According to Microsoft event naming guidelines, the sender parameter in a C# event handler "is always of type object, even if it is possible to use a more specific type".
This leads to lots of event handling code like:
RepeaterItem item = sender as RepeaterItem;
if (item != null) { /* Do some stuff */ }
Why does the convention advise against declaring an event handler with a more specific type?
MyType
{
public event MyEventHander MyEvent;
}
...
delegate void MyEventHander(MyType sender, MyEventArgs e);
Am I missing a gotcha?
For posterity: I agree with the general sentiment in the answers that the convention is to use object (and to pass data via the EventArgs) even when it is possible to use a more specific type, and in real-world programming it is important to follow the convention.
Edit: bait for search: RSPEC-3906 rule "Event Handlers should have the correct signature"
Well, it's a pattern rather than a rule. It does mean that one component can forward on an event from another, keeping the original sender even if it's not the normal type raising the event.
I agree it's a bit strange - but it's probably worth sticking to the convention just for familiarity's sake. (Familiarity for other developers, that is.) I've never been particularly keen on EventArgs myself (given that on its own it conveys no information) but that's another topic. (At least we've got EventHandler<TEventArgs> now - although it would help if there were also an EventArgs<TContent> for the common situation where you just need a single value to be propagated.)
EDIT: It does make the delegate more general purpose, of course - a single delegate type can be reused across multiple events. I'm not sure I buy that as a particularly good reason - particularly in the light of generics - but I guess it's something...
I think there's a good reason for this convention.
Let's take (and expand on) #erikkallen's example:
void SomethingChanged(object sender, EventArgs e) {
EnableControls();
}
...
MyRadioButton.Click += SomethingChanged;
MyCheckbox.Click += SomethingChanged;
MyDropDown.SelectionChanged += SomethingChanged;
...
This is possible (and has been since .Net 1, before generics) because covariance is supported.
Your question makes total sense if you're going top-down - i.e. you need the event in your code, so you add it to your control.
However the convention is to make it easier when writing the components in the first place. You know that for any event the basic pattern (object sender, EventArgs e) will work.
When you add the event you don't know how it will be used, and you don't want to arbitrarily constrain the developers using your component.
Your example of a generic, strongly typed event makes good sense in your code, but won't fit with other components written by other developers. For instance if they want to use your component with those above:
//this won't work
GallowayClass.Changed += SomethingChanged;
In this example the additional type-constraint is just creating pain for the remote developer. They now have to create a new delegate just for your component. If they're using a load of your components they might need a delegate for each one.
I reckon the convention is worth following for anything external or that you expect to be used outside of a close nit team.
I like the idea of the generic event args - I already use something similar.
I use the following delegate when I would prefer a strongly-typed sender.
/// <summary>
/// Delegate used to handle events with a strongly-typed sender.
/// </summary>
/// <typeparam name="TSender">The type of the sender.</typeparam>
/// <typeparam name="TArgs">The type of the event arguments.</typeparam>
/// <param name="sender">The control where the event originated.</param>
/// <param name="e">Any event arguments.</param>
public delegate void EventHandler<TSender, TArgs>(TSender sender, TArgs e) where TArgs : EventArgs;
This can be used in the following manner:
public event EventHandler<TypeOfSender, TypeOfEventArguments> CustomEvent;
Generics and history would play a big part, especially with the number of controls (etc) that expose similar events. Without generics, you would end up with a lot of events exposing Control, which is largely useless:
you still have to cast to do anything useful (except maybe a reference check, which you can do just as well with object)
you can't re-use the events on non-controls
If we consider generics, then again all is well, but you then start getting into issues with inheritance; if class B : A, then should events on A be EventHandler<A, ...>, and events on B be EventHandler<B, ...>? Again, very confusing, hard for tooling, and a bit messy in terms of language.
Until there is a better option that covers all of these, object works; events are almost always on class instances, so there is no boxing etc - just a cast. And casting isn't very slow.
I guess that's because you should be able to do something like
void SomethingChanged(object sender, EventArgs e) {
EnableControls();
}
...
MyRadioButton.Click += SomethingChanged;
MyCheckbox.Click += SomethingChanged;
...
Why do you do the safe cast in your code? If you know that you only use the function as an event handler for the repeater, you know that the argument is always of the correct type and you can use a throwing cast instead, e.g. (Repeater)sender instead of (sender as Repeater).
No good reason at all, now there's covarience and contravarience I think it's fine to use a strongly typed Sender. See discussion in this question
Conventions exist only to impose consistency.
You CAN strongly type your event handlers if you wish, but ask yourself if doing so would provide any technical advantage?
You should consider that event handlers don't always need to cast the sender... most of the event handling code I've seen in actual practice don't make use of the sender parameter. It is there IF it is needed, but quite often it isn't.
I often see cases where different events on different objects will share a single common event handler, which works because that event handler isn't concerned with who the sender was.
If those delegates were strongly typed, even with clever use of generics, it would be VERY difficult to share an event handler like that. In fact, by strongly typing it you are imposing the assumption that the handlers should care what the sender is, when that isn't the practical reality.
I guess what you should be asking is why WOULD you strongly type the event handling delegates? By doing so would you be adding any significant functional advantages? Are you making the usage more "consistent"? Or are you just imposing assumptions and constraints just for the sake of strong-typing?
You say:
This leads to lots of event handling
code like:-
RepeaterItem item = sender as RepeaterItem
if (RepeaterItem != null) { /* Do some stuff */ }
Is it really lots of code?
I'd advise never to use the sender parameter to an event handler. As you've noticed, it's not statically typed. It's not necessarily the direct sender of the event, because sometimes an event is forwarded. So the same event handler may not even get the same sender object type every time it is fired. It's an unnecessary form of implicit coupling.
When you enlist with an event, at that point you must know what object the event is on, and that is what you're most likely to be interested in:
someControl.Exploded += (s, e) => someControl.RepairWindows();
And anything else specific to the event ought to be in the EventArgs-derived second parameter.
Basically the sender parameter is a bit of historical noise, best avoided.
I asked a similar question here.
It's because you can never be sure who fired the event. There is no way to restrict which types are allowed to fire a certain event.
The pattern of using EventHandler(object sender, EventArgs e) is meant to provide for all events the means of identifying the event source (sender), and providing a container for all the event's specific payload.
The advantage of this pattern is also that it allows to generate a number of different events using the same type of delegate.
As for the arguments of this default delegate...
The advantage of having a single bag for all the state you want to pass along with the event is fairly obvious, especially if there are many elements in that state.
Using object instead of a strong type allows to pass the event along, possibly to assemblies that do not have a reference to your type (in which case you may argue that they won't be able to use the sender anyway, but that's another story - they can still get the event).
In my own experience, I agree with Stephen Redd, very often the sender is not used. The only cases I've needed to identify the sender is in the case of UI handlers, with many controls sharing the same event handler (to avoid duplicating code).
I depart from his position, however, in that I see no problem defining strongly typed delegates, and generating events with strongly typed signatures, in the case where I know that the handler will never care who the sender is (indeed, often it should not have any scope into that type), and I do not want the inconvenience of stuffing state into a bag (EventArg subclass or generic) and unpacking it. If I only have 1 or 2 elements in my state, I'm OK generating that signature.
It's a matter of convenience for me: strong typing means the compiler keeps me on my toes, and it reduces the kind of branching like
Foo foo = sender as Foo;
if (foo !=null) { ... }
which does make the code look better :)
This being said, it is just my opinion. I've deviated often from the recommended pattern for events, and I have not suffered any for it. It is important to always be clear about why it is OK to deviate from it.
Good question!
.
Well, that's a good question. I think because any other type could use your delegate to declare an event, so you can't be sure that the type of the sender is really "MyType".
I tend to use a specific delegate type for each event (or a small group of similar events). The useless sender and eventargs simply clutter the api and distract from the actually relevant bits of information. Being able to "forward" events across classes isn't something I've yet to find useful - and if you're forwarding events like that, to an event handler that represents a different type of event, then being forced to wrap the event yourself and provide the appropriate parameters is little effort. Also, the forwarder tends to have a better idea of how to "convert" the event parameters than the final receiver.
In short, unless there's some pressing interop reason, dump the useless, confusing parameters.

Categories