I am trying to understand how the lambda operator in C# is used when the given parameters are formatted in ( ), like so:
_backgroundVideoWorker.DoWork += (s, e) =>
{
outputFile = _videoEditor.JoinVideo(selectedConfiguration, videoFiles);
};
My main goal from asking this question is to understand how the different operators are being used with the lambda, += (s, e) =>.
For reference, this code excerpt is taken from an application that is joining two video files together by using the FFMPEG utility.
_backgroundVideoWorker.DoWork is an event that needs handlers.
+= indicates we are adding an event handler to handle the event.
(s, e) is saying that the expression is creating a function which accepts the s and e parameters required by the event for a function to handle it. These represent an object (s) and the DoWorkEventArgs (e). If you were to write a full function block instead of an inline lambda, they would look like (object s, DoWorkEventArgs e) or more familiarly (object sender, DoWorkEventArgs e);
BackgroudWorker.DoWork is an event with a delegate type of DoWorkEventHandler, which has the signature:
public delegate void DoWorkEventHandler(object sender, DoWorkEventArgs e)
which means that DoWork would be a function that receives two parameters, of type object and DoWorkEventArgs, respectively.
The event handler has to follow the same signature as the event's delegate, therefore, when you speficy (s, e) => { /*..*/ } as the event handler, the compiler will assume that s corresponds to the object sender parameter, while e corresponds to the DoWorkEventargs e parameter. Of course, you don't have to name them s and e
Related
Is there a way that I am able to use 'custom' parameters with a function that is used when the value in an entry widget is changed.
the basic function is:
public void(object sender, EventArgs args){
Entry ent1 = (Entry)sender;
}
what I tried:
public void onChange(object sender, EventArgs args, String name){
Entry ent1 = (Entry)sender;
}
but It would run, because when I was calling the function it was:
entry1 += onChange("testname");
which only passes one paramter to the function, when it needs three.
What I'm asking is how can I use a 'custom' paramter like 'name', and still pass the values for 'sender' and 'args'?
You will have to create a delegate that wraps code that passes that extra parameter.
You should be able to do it with this syntax:
entry1 += (s, e) => onChange(s, e, "testname");
However, this will make you unable to unsubscribe that event. If you need that, you will have to store the delegate:
ChangeEventHandler onchange = (s, e) => onChange(s, e, "testname");
entry1 += onchange;
...
entry1 -= onchange;
The first one code is shorthand notation of second:
itemCountLines.Click = itemCountLines.Click + (sender, args) => countLines();
itemCountLines.Click += (sender, args) => CountLines();
But i did not understand what this expression is doing.Anybody Please Explain it to me
This code adds an handler to the Control.Click event:
public event EventHandler Click
where EventHandler is a delegate of type:
public delegate void EventHandler(
object sender,
EventArgs e
)
Normally, given you have a method with the same signature:
void SomeClickHandler(object sender, EventArgs e)
{
CountLines();
}
you would add this handler to handle Click event:
itemCountLines.Click += SomeClickHandler;
Operator += is possible because Click is an event, so you can add or remove a multiple EventHandlers to it. Simple speaking, after some control is clicked, you may want to make multiple actions (show some other control, log it to the database etc) so you are able to add multiple event handlers. You can even do itemCountLines.Click -= SomeClickHandler somewhere later to say, you do not want to handle Click with SomeClickHandler anymore.
But above code needs to define method SomeClickHandler which sometimes is unnecessary (for example, it is used only one in whole class). Then you can use anonymous delegate (added in C# 2.0):
itemCountLines.Click += delegate(object sender, EventArgs args)
{
CountLines();
};
but you can further shorten this syntax with lambda expression (added in C# 3.0) to:
itemCountLines.Click += (sender, args) => CountLines();
It simply add an event to the list of listeners itemCountLines.Click = itemCountLines.Click + (sender, args) so when an event occurs the instance of sender will be notified to raise the event inline => countLines(); as you are using lambda Expression => which will invoke countLines method
You're just attaching an event on Click, it is the same as saying
itemCountLines.Click += CountLines(sender, args);
Somewhere, there should be a method like this :
private void CountLines()
{
// Some Code There
}
I'm trying to implement drag and drop for a specific object of a Type that I've created in c# for windows phone 8. I'm using Manipulation Events like this :
deck[r[i, j]].card.ManipulationCompleted += new EventHandler<ManipulationCompletedEventArgs>(ImageManipulationCompleted);
private void ImageManipulationCompleted(object sender, ManipulationCompletedEventArgs e)
{
//something
}
How can I change object to the type that I want ?
keyboardP's solution will work just fine. But I personally prefer to store the information I need in the Tag property of the control, which has been designed for this very purpose.
deck[r[i, j]].card.Tag = deck[r[i, j]];
deck[r[i, j]].card.ManipulationCompleted += ImageManipulationCompleted;
private void ImageManipulationCompleted(object sender, ManipulationCompletedEventArgs e)
{
var deck = (Deck)((FrameworkElement)sender).Tag;
}
The good side of keyboardP's approach is that, since you receive directly the desired object as a parameter of your method, it's easier to read. The downside is that you have to declare a custom delegate for every event you need, and you lose the ability to assign event handlers directly from the XAML. My solution is a bit harder to read, but addresses this point.
In the end, which solution is better really depends on your tastes and your needs.
What you could do is just call a method that takes in your type instead of using the standard ImageManipulationCompleted handler. I don't know what the deck[r[i, j]] type is but you can replace MyType below with the correct type.
deck[r[i, j]].card.ManipulationCompleted += delegate(object s, ManipulationCompletedEventArgs e){ CardManipulated(s, e, deck[r[i, j]]); };
private void CardManipulated(object sender, ManipulationCompletedEventArgs e, MyType selectedObject)
{
//you know have access to selectedObject which is of type deck[r[i, j]],
//the ManipluationCompletedEvents properties if needed,
//and the actual card Image object (sender).
}
You cant.
Since you are subscribing to an event with this code new EventHandler<>(..), you cannot change the type of sender because in the description of EventHandler<> there is only object sender:
public delegate EventHandler<T>(object sender, T eventArgs) where T : EventArgs
If you need to create your own delegate, you could make a factory or simply write this:
public delegate EventHandler<T, TArgs>(T sender, TArgs eventArgs) where TTArgs : EventArgs
ManipulationCompletedEventHandler signature is using object in its first parameter
public delegate void ManipulationCompletedEventHandler(object sender,
ManipulationCompletedRoutedEventArgs e);
So, you can't change the signature but you can use delegate to typecast object always to your type like this -
deck[r[i, j]].card.ManipulationCompleted += (s, e) =>
ManipulateMe_ManipulationCompleted((YourType)s, e);
private void ImageManipulationCompleted(YourType sender,
ManipulationCompletedEventArgs e)
{
//something
}
Replace YourType with your desired Type (TextBox or something whichever you want)
What is exactly the += ( s, e ) in the code?
example:
this.currentOperation.Completed += ( s, e ) => this.CurrentOperationChanged();
This is the way to attach an event handler using Lambda expression.
For example:
button.Click += new EventHandler(delegate (Object s, EventArgs e) {
//some code
});
Can be rewritten using lambda as follows:
button.Click += (s,e) => {
//some code
};
One thing to note here. It is not necessary to write 's' and 'e'. You can use any two letters, e.g.
button.Click += (o,r) => {};
The first parameter would represent the object that fired the event and the second would hold data that can be used in the eventhandler.
This codes adds an event listener in form of a Lambda expression. s stands for sender and e are the EventArgs. Lambda for
private void Listener(object s, EventArgs e) {
}
This is an assignment of a delegate instance (the start of a lambda expression) to an event invocation list. The s, e represents the sender and EventArgs parameters of the event delegate type.
See http://msdn.microsoft.com/en-us/library/ms366768.aspx for more info.
It is a shorthand for an event handler.
s --> object sender and
e --> some type of EventArgs.
It can also be rewrriten as:
public void HandlerFunction(object sender, EventArgs e)
{
this.loaded = true;
}
IntelliSense says that the lambda parameter ea is a DownloadStringCompletedEvent Args. Understood, but parameter s is only defined as "object s". Can anyone explain the purpose of this parameter?
WebClient client = new WebClient();
client.DownloadStringCompleted += (s, ea) =>
{ XDocument document = XDocument.Parse(ea.Result);
// ... Do something else...
};
AFAIK that object s is usually known as the "Sender", hence the s for sender - ie. the object that generate the event, aka, the source.
Hope this helps.
EventHandlers in .NET are typically of the form
void MyEventHandler(object sender, EventArgs e) { ... }
The sender argument is the object that the event occurred on. Since it can be just about anything, object is used. The EventArgs argument is typically either System.EventArgs itself, or a subclass of it. In your case it is a subclass.
The lambda matches the delegate
public delegate void DownloadStringCompletedEventHandler(
Object sender,
DownloadStringCompletedEventArgs e
)
Where s is "The source of the event."
http://msdn.microsoft.com/en-us/library/system.net.downloadstringcompletedeventhandler.aspx