Solved

How to mix winform and wpf

Posted on 2010-08-21
4
965 Views
Last Modified: 2013-11-08
Hi experts,

I have a DLL that contains usercontrols in winforms and wpf
i have a winform that host those usercontrols

the way i load the usercontrols is reflection

activator.createinstance...

With Winform usercontrol, i have no problem but with wpf, i did a trick to create wpf usercontrol via reflection by launching it in another thread and set apartment state to STA...

by the way, every controls are created (win and wpf) all events are linked to methods between them too

but when the host forms load...

i have this error :

The calling thread cannot access this object because a different thread owns it.


MAIN CODE : 

        <STAThread()> _
        Sub Main()

            With _thread
                .SetApartmentState(ApartmentState.STA)
                .Priority = ThreadPriority.Normal
                .Start()
            End With

        End Sub

        Private Sub Run()

            Context = New MyContext(New Login)
            Application.EnableVisualStyles()
            Application.Run(Context)

        End Sub



CONTEXT Class : 


    Public Class MyContext
        Inherits ApplicationContext

        Private WithEvents mainFrm As Form

        Public Sub New(ByVal frm As Form)
            Me.SwitchTo(frm)
        End Sub

        Public Sub SwitchTo(ByVal frm As Form)

            Dim tmpFrm As Form = mainFrm
            mainFrm = frm
            If tmpFrm IsNot Nothing Then
                tmpFrm.Close()
                tmpFrm.Dispose()
                tmpFrm = Nothing
            End If
            If mainFrm IsNot Nothing Then
                mainFrm.Show()
            End If

        End Sub

        Private Sub mainFrm_Closed(ByVal sender As Object, ByVal e As System.EventArgs) Handles mainFrm.Closed
            Application.ExitThread()
        End Sub

    End Class



HOW I LOAD THE USERCONTROL : 

    Public Shared Function Create(Of T)(ByVal aAssembly As String, ByVal aComponent As String) As T

            Dim mAsm As Assembly
            Dim mType As Type
            Dim mObj As Object
            Dim mT As T
            Dim mInterface As Type

            Try
                mAsm = Assembly.Load(aAssembly)
            Catch exArgumentNullExc As ArgumentNullException
                Return Nothing
            Catch exBadImageFormatExc As BadImageFormatException
                Return Nothing
            Catch exFileNotFoundExc As FileNotFoundException
                Return Nothing
            End Try

            mType = mAsm.GetType(New StringBuilder().Append(aAssembly).Append(".").Append(aComponent).ToString)

            If mType IsNot Nothing Then
                mInterface = mType.GetInterface("IDispatcher", False)
            Else
                Return Nothing
            End If

            If mInterface Is Nothing Then
                Return Nothing
            End If

            Try
                mObj = Activator.CreateInstance(mType)
            Catch exTargetInvocationException As TargetInvocationException
                Return Nothing
            End Try

            mT = CType(mObj, T)

            Return mT

        End Function




AND ONLY FOR WPF USERCONTROL :

Me._threadWPF.Start(New Object() {lLinkedItemList, m})
Me._waitEvent.WaitOne()

     Private Sub ThreadWPF(ByVal aObject As Object)

            Dim lArgs() As Object = DirectCast(aObject, Object())
            Dim lControl As System.Windows.Controls.Control
            Dim lLinkedItemList As List(Of LinkedItem) = DirectCast(lArgs(0), List(Of LinkedItem))
            Dim m As PBox = DirectCast(lArgs(1), PBox)

            'create the element host 
            lControl = Utils.Create(Of System.Windows.Controls.Control)(m.Widget.Assembly.Name, m.Widget.Name)

            If lControl IsNot Nothing Then

                Dim lElementHost As New ElementHost
                Dim lUserControl As New UserControl

                lElementHost.Dock = DockStyle.Fill

                lElementHost.Child = lControl

                lUserControl.Name = m.Widget.ID.ToString
                lUserControl.Controls.Add(lElementHost)

                lUserControl.Name = m.Widget.ID.ToString

                lLinkedItemList.Add(New LinkedItem(lUserControl.Name, lUserControl))

            End If

            Me._waitEvent.Set()

        End Sub

Open in new window

0
Comment
Question by:Dnx_7
  • 2
  • 2
4 Comments
 
LVL 2

Expert Comment

by:Toony06
ID: 33514831
You are trying to access a variable from a different thread. You need to check the access before accessing it with the lock keyword. Simply create an lock object before accessing the variable.


'Create a mutex and wait for an access
Dim lock As Mutex
lockMutex = New Mutex(False, "Mutex Name")
lockMutex.WaitOne()

'Do Your Work Here

'Release the lock for further access
lockMutex.ReleaseMutex()

Open in new window

0
 
LVL 2

Author Comment

by:Dnx_7
ID: 33514917
In fact, i did lot of tests and seems that is only when i affect the wpf usercontrol to the CHILD property of the elementhost...

then i tried to overrides this property but cannot do this at this time

don't know how to figure it out :(
0
 
LVL 2

Accepted Solution

by:
Toony06 earned 500 total points
ID: 33521379
To build WPF along with Winform a couple assemblies are required in your project. Make shure you have included:

-WindowsBase
-PresentationCore
-PresentationFramework
-WindowsFormsIntegration

Also, mixing these radicaly different technologies is complex and require understanding of the underlying system. You will need to know about Airspace, here is a quick article:

http://msdn.microsoft.com/en-us/library/aa970688.aspx

Also, Microsoft hae done a tutorial on the subject you can refer to:

http://msdn.microsoft.com/en-us/library/aa970266.aspx
0
 
LVL 2

Author Closing Comment

by:Dnx_7
ID: 33607844
It resolved my problemd
0

Featured Post

Live: Real-Time Solutions, Start Here

Receive instant 1:1 support from technology experts, using our real-time conversation and whiteboard interface. Your first 5 minutes are always free.

Question has a verified solution.

If you are experiencing a similar issue, please ask a related question

More often than not, we developers are confronted with a need: a need to make some kind of magic happen via code. Whether it is for a client, for the boss, or for our own personal projects, the need must be satisfied. Most of the time, the Framework…
The ECB site provides FX rates for major currencies since its inception in 1999 in the form of an XML feed. The files have the following format (reducted for brevity) (CODE) There are three files available HERE (http://www.ecb.europa.eu/stats/exch…
Windows 10 is mostly good. However the one thing that annoys me is how many clicks you have to do to dial a VPN connection. You have to go to settings from the start menu, (2 clicks), Network and Internet (1 click), Click VPN (another click) then fi…
Microsoft Active Directory, the widely used IT infrastructure, is known for its high risk of credential theft. The best way to test your Active Directory’s vulnerabilities to pass-the-ticket, pass-the-hash, privilege escalation, and malware attacks …

815 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question

Need Help in Real-Time?

Connect with top rated Experts

10 Experts available now in Live!

Get 1:1 Help Now