2

How can I add extra string parameter into Dispatchertimer Eventhandler ?.

I would like achieve something like this:

string ObjectName = "SomeObjectName";
System.Windows.Threading.DispatcherTimer dispatcherTimer = new System.Windows.Threading.DispatcherTimer();
dispatcherTimer.Tick += new EventHandler(dispatcherTimer_Tick(ObjectName));

And function:

private void dispatcherTimer_Tick(object sender, EventArgs e, string ObjectName)
{
    [...]
}

How Can I achieve that?

Edit:

My intention is add some animation for moving object. I've got canvas with few objects. I can move this objects on canvas by mouse clicking, i would like to add animations for this movement.

Shagohad
  • 365
  • 1
  • 7
  • 23

3 Answers3

8

You can use a closure for that:

... 
{    
    string objectName = "SomeObjectName";
    var dispatcherTimer = new DispatcherTimer();

    dispatcherTimer.Tick += (sender, e) => { myTick(sender, e, objectName); };
}

private void myTick(object sender, EventArgs e, string objectName)
{
    [...]
}

Note, though, that the variable objectName is captured, rather than it's current value. That means if you do this:

... 
{    
    string objectName = "SomeObjectName";
    var dispatcherTimer = new DispatcherTimer();

    dispatcherTimer.Tick += (sender, e) => { myTick(sender, e, objectName); };
    objectName = "SomeOtherObjectName";
}

myTick will be called with SomeOtherObjectName, which might be counter-intuitive at a first glance. The reason for this is that, under the hood, a separate object instance with an objectName field is created -- very similar to what Chris' solution is doing explicitly.

Community
  • 1
  • 1
Heinzi
  • 167,459
  • 57
  • 363
  • 519
  • @Chris: It's basically an implicit variant of what you are doing explicitly. – Heinzi Jan 25 '15 at 15:42
  • Yeah, just wish I had thought of that before my solution hehe. – Chris Jan 25 '15 at 15:47
  • imma just say, registering Lambda like that to this event has extreme limitations, for one, it can be registered multiple times and you cant unregistered it through -=, thus limiting you to an one time only use, just using an outer score field would be a simpler solution. – Xeorge Xeorge Apr 30 '20 at 10:51
1

You can use this trick to pass along as much data as you'd like:

class Foo
{
    public string PropertyA { get; set; }
    public string PropertyB { get; set; }
    // ...

    public void OnTick( object sender, EventArgs e )
    {
        // logic here
    }
}

var f = new Foo() { PropertyA = "some stuff here",
                    PropertyB = "some more stuff here" };
dispatcherTimer.Tick += f.OnTick;

Obviously, if you only ever have one event handler for the same timer you could just as well store the required data in whatever class is using this.

Chris
  • 5,442
  • 17
  • 30
0

You could use the Tag property of DispatcherTimer

string ObjectName = "SomeObjectName";
System.Windows.Threading.DispatcherTimer dispatcherTimer = new System.Windows.Threading.DispatcherTimer();
dispatcherTimer.Tick += dispatcherTimer_Tick;
dispatcherTimer.Tag = ObjectName

Then

private void dispatcherTimer_Tick(object sender, EventArgs e)
{
    var timer = sender as DispatcherTimer;
    
    var objectName = (string)timer.Tag;
       
}
komodosp
  • 3,316
  • 2
  • 30
  • 59