Solved

How to mix winform and wpf

Posted on 2010-08-21
4
972 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

The New “Normal” in Modern Enterprise Operations

DevOps for the modern enterprise offers many benefits — increased agility, productivity, and more, but digital transformation isn’t easy, especially if you’re not addressing the right issues. Register for the webinar to dive into the “new normal” for enterprise modern ops.

Question has a verified solution.

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

Suggested Solutions

Title # Comments Views Activity
how to remove duplicate code from my project 5 37
jquery tab header text 1 23
Code enhancement 4 22
Regarding swagger API 1 15
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…
Parsing a CSV file is a task that we are confronted with regularly, and although there are a vast number of means to do this, as a newbie, the field can be confusing and the tools can seem complex. A simple solution to parsing a customized CSV fi…
This video shows how to quickly and easily add an email signature for all users on Exchange 2016. The resulting signature is applied on a server level by Exchange Online. The email signature template has been downloaded from: www.mail-signatures…

821 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