tags:

views:

266

answers:

1

In my other methods I could do something like this,

    public void Add(T item)
    {
        if (dispatcher.CheckAccess())
        {
            ...
        }
        else
        {
            dispatcher.Invoke(new Action<T>(Add), item);
        }
    }

But how do I invoke a property for a situation like this?

    public T this[int index]
    {
        get
        {
            ...
        }
        set
        {
            if (dispatcher.CheckAccess())
            {
                ...
            }
            else
            {
                dispatcher.Invoke(???, value, index); // <-- problem is here
            }
        }
    }
+6  A: 

Edit: The following paragraph no longer applies, as the OP's question has since been edited.

First off, your second code seems logically incorrect: You apparently want to call the setter, but while you provide a value for index, you don't provide the actual value (i.e. item). I'll return to that issue in a second.


You could wrap an anonymous delegate or lambda function around the property setter, e.g. (using an anonymous delegate) to make it invokable:

dispatcher.Invoke(
    new Action<T>(  delegate (T item) { this[index] = item; }  ),
    item );

or (using a lambda function available since C# language version 3):

dispatcher.Invoke(
    new Action<T>(  (T item) => { this[index] = item; }  ),
    item );

Note: You create an anonymous delegate or lambda function that accepts one argument (item). The other required argument (index) is taken from the "outer" context. (The term closure comes to mind.) I see this as the only way how you would not have to change your dispatcher to a delegate type that is sometimes invoked with two arguments instead of one.

If this however is not an issue, the Invoke code could change to e.g.:

dispatcher.Invoke(
    new Action<int,T>(  (int index, T item) => { this[index] = item; }  ),
    index, item );
stakx
Oops, forgot to pass `value` back. I'll try this tomorrow. I *thought* I could do something like this, but I couldn't remember the proper syntax.
Mark
Why do you pass the item but not the index to the delegate? If it's not necessary to pass index, then it shouldn't be necessary to pass the item either? `dispatcher.Invoke(new Action(() => { this[index] = value; }));`
Mark
From looking at the code you posted in your question, I assumed that `dispatcher.Invoke` required an `Action<T>` (ie. a delegate with only one parameter). However, if you can pass two arguments, then of course you could just as well pass `index` directly to the delegate, too. Choose what works best in your case!
stakx
@Mark: added a third code example with a two-parameter lambda function.
stakx
Awesome. Thanks for all your help :)
Mark