Solved

How to mix winform and wpf

Posted on 2010-08-21
4
994 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
[X]
Welcome to Experts Exchange

Add your voice to the tech community where 5M+ people just like you are talking about what matters.

  • Help others & share knowledge
  • Earn cash & points
  • Learn & ask questions
  • 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

What is a Denial of Service (DoS)?

A DoS is a malicious attempt to prevent the normal operation of a computer system. You may frequently see the terms 'DDoS' (Distributed Denial of Service) and 'DoS' used interchangeably, but there are some subtle differences.

Question has a verified solution.

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

Many of us here at EE write code. Many of us write exceptional code; just as many of us write exception-prone code. As we all should know, exceptions are a mechanism for handling errors which are typically out of our control. From database errors, t…
Real-time is more about the business, not the technology. In day-to-day life, to make real-time decisions like buying or investing, business needs the latest information(e.g. Gold Rate/Stock Rate). Unlike traditional days, you need not wait for a fe…
Michael from AdRem Software explains how to view the most utilized and worst performing nodes in your network, by accessing the Top Charts view in NetCrunch network monitor (https://www.adremsoft.com/). Top Charts is a view in which you can set seve…
In this video you will find out how to export Office 365 mailboxes using the built in eDiscovery tool. Bear in mind that although this method might be useful in some cases, using PST files as Office 365 backup is troublesome in a long run (more on t…

627 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