Solved

How to mix winform and wpf

Posted on 2010-08-21
4
958 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
Comment Utility
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
Comment Utility
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
Comment Utility
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
Comment Utility
It resolved my problemd
0

Featured Post

Free Trending Threat Insights Every Day

Enhance your security with threat intelligence from the web. Get trending threat insights on hackers, exploits, and suspicious IP addresses delivered to your inbox with our free Cyber Daily.

Join & Write a Comment

In my previous two articles we discussed Binary Serialization (http://www.experts-exchange.com/A_4362.html) and XML Serialization (http://www.experts-exchange.com/A_4425.html). In this article we will try to know more about SOAP (Simple Object Acces…
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…
Here's a very brief overview of the methods PRTG Network Monitor (https://www.paessler.com/prtg) offers for monitoring bandwidth, to help you decide which methods you´d like to investigate in more detail.  The methods are covered in more detail in o…
When you create an app prototype with Adobe XD, you can insert system screens -- sharing or Control Center, for example -- with just a few clicks. This video shows you how. You can take the full course on Experts Exchange at http://bit.ly/XDcourse.

744 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

13 Experts available now in Live!

Get 1:1 Help Now