2

Given the following method :

public static void ExecuteAsync( this EventHandler eH, object sender, EventArgs eA ) {
    eH.GetInvocationList( ).Cast<EventHandler>( ).ToList( ).ForEach( e => {         
        e.BeginInvoke( sender, eA, IAR =>
            ( ( IAR as AsyncResult ).AsyncDelegate as EventHandler ).EndInvoke( IAR ), null );
    } );
}

I noticed that e has a property Target.

When I was looking further into it I discovered I can check if e.Target is System.Windows.Controls.Control or e.Target is System.Windows.Forms.Control.

This is awesome because in the case of using this extension, as a matter of convenience (and me being lazy), I want to be able to tell if the delegate target needs to invoke the delegate or not (In the case of WinForms : Control.Invoke( foo ); In the case of WPF : Control.Dispatcher.Invoke( foo )).

I don't need to know how to cast the object to what it's actual type is (I can live without that) : I just need to know if how I can cast the object such that I can access the InvokeRequired property and Invoke methods (in the case of a WinForms control), or the Dispatcher property (For access to the Dispatcher.CheckAccess( ) function and Dispatcher.Invoke( ) method).

Is this possible? How can I go about doing this? (I've tried casting e.Target to System.Windows.Control.Control but the result does not have a Dispatcher property).

EDIT

As per the request for the casting code (and imports/references) :

To determine if it is a WPF control :

( if e.Target is System.Windows.Controls.Control ){ //Fully Qualified
    ( e.Target as System.Windows.Controls.Control)./*...*/;
}

To determine if it is a WinForms control :

( if e.Target is System.Windows.Forms.Control ){ //Fully Qualified
    ( e.Target as System.Windows.Forms.Control )./*...*/;
}

The project makes reference to several libraries :

Microsoft.CSharp
MySql.Data
PresentationFramework
System
System.Configuration
System.Configuration.Install
System.Core
System.Data
System.Data.DataSetExtensions
System.Drawing
System.Management
System.Windows.Forms
System.Xml
System.Xml.Linq
Will
  • 3,413
  • 7
  • 50
  • 107
  • Show the casting code you are using, including all imports- my guess is that the problem lies there. – Chris Shain Dec 10 '15 at 02:32
  • @ChrisShain See Edit – Will Dec 10 '15 at 02:45
  • From the data provided I can't see what the problem is. Can you provide a small, complete, reproducable example program? – Chris Shain Dec 10 '15 at 14:17
  • I found it. I need to reference System.Xaml to access the Dispatcher property. The class in which the extension method was being created is in a Non-UI project which is why the problem. Thanks – Will Dec 10 '15 at 15:27

1 Answers1

1

Doesn't that work for you. It's not the most elegant way but does the job of checking whether the target is a WPF or WinForms control:

if (e.Target is System.Windows.Controls.Control)
{
    var wpfTarget = ((System.Windows.Controls.Control)e.Target);
    if (wpfTarget.Dispatcher.CheckAccess()) // check if on dispatcher thread
    {
        wpfTarget.Dispatcher.Invoke(/*...*/);
    }

}
else if (e.Target is System.Windows.Forms.Control)
{
    var formsTarget = (System.Windows.Forms.Control)e.Target;
    if (formsTarget.InvokeRequired)
    {
        formsTarget.Invoke(/*...*/);
    }
}

In VisualStudio I have Intelisense support for the Dispatcher on the wpfTarget:

enter image description here

EDIT

Below the references I've included

using System;
using System.Collections.Generic;
using System.Linq;
using System.Runtime.Remoting.Messaging;
using System.Text;
using System.Threading.Tasks;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Navigation;
using System.Windows.Shapes;

of which only four are in use:

using System;
using System.Linq;
using System.Runtime.Remoting.Messaging;
using System.Windows;
PiotrWolkowski
  • 8,408
  • 6
  • 48
  • 68
  • I'm fundamentally opposed to using var unless it's absolutely necessary. Anyway, if I were to try and cast the object like above the resultant does not have a Dispatcher property. A simple test on your own system using VS should show you. It says : `System.Windows.Controls.Control does not contain a definition for 'Dispatcher'...` – Will Dec 10 '15 at 02:50
  • I wrote it in Visual Studio 2015 it has dispatcher property. Let me provide a printscreen. As to using var it makes the code lighter to read - it doesn't draw your attention to the implementation detail but rather to the algorithm. But that's only my personal feeling. – PiotrWolkowski Dec 10 '15 at 02:52
  • I believe you. I'm using VS 2013, however. – Will Dec 10 '15 at 02:53
  • I've seen you cast using `as`. Did you try the direct cast? – PiotrWolkowski Dec 10 '15 at 02:53
  • Yes. Both results the same. – Will Dec 10 '15 at 02:55
  • They must have made a change to that between VS 2013 and VS 2015. Do you use Community or the paid solution? – Will Dec 10 '15 at 03:02
  • Community. Wanted to test on 2013 as well but no longer have it installed – PiotrWolkowski Dec 10 '15 at 03:03
  • I'm installing VS 2015 now... suppose I can't let myself get stuck in the past... next year they'll have out VS 2016 FML – Will Dec 10 '15 at 03:12
  • Okay so I installed VS 2015 and the result was the same - so evidently you have included/referenced something that I have not... – Will Dec 10 '15 at 04:52
  • Let us [continue this discussion in chat](http://chat.stackoverflow.com/rooms/97559/discussion-between-piotrwolkowski-and-will). – PiotrWolkowski Dec 10 '15 at 20:24
  • No need : I was missing a reference to System.XAML; thanks though. – Will Dec 10 '15 at 23:27