.net – How to get ElementHost control, given one of WPF control’s content

vb.netwpf

I am trying to get a reference to ElementHost control. For example in the below code I need to initially use the “testImage” content of the WPF user control to lunch the event. The WPF control is added at run-time, so does the ElementHost control, so I can’t use the WPF control’s name or ElementHost’s name.
My logic is to get the parent WPF user control of the “testImage”, and then get the parent ElementHost of the WPF’s user control.
But I am having troubles writing it in code. Please advise. Thanks.

<UserControl x:Class="WpfTest”
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" Width="300" Height="300">
    <Grid>
        <Label FontSize="10" Height="24" Margin="74,16,0,0" Name="testLabel" VerticalAlignment="Top" />
        <Image Name="testImage" Stretch="Uniform" HorizontalAlignment="Left" Width="64" Height="81" VerticalAlignment="Top" Margin="8,0,0,0"/>
    </Grid>
</UserControl>

Best Answer

Here is some code that might help you. The key points are:

  • Name the ElementHost when you create it at runtime
  • Make use the the help function FindVisualChildByName() to search the WPF tree to get the desired control

I Hope this helps!

  Private Sub Form1_Load(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.Load

        Dim ElementHost1 As New System.Windows.Forms.Integration.ElementHost
        Dim WpfTest1 As New WindowsApplication1.WPFTest

        ElementHost1.Dock = DockStyle.Fill
        ElementHost1.Name = "ElementHost1"
        ElementHost1.Child = WpfTest1

        Me.Controls.Add(ElementHost1)
    End Sub

    Private Sub GetImageReference_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click
        Dim ElementHost1 As System.Windows.Forms.Integration.ElementHost = Me.Controls("ElementHost1")
        Dim TheGrid As System.Windows.Controls.Grid = CType(ElementHost1.Child, WPFTest).MyGrid
        Dim ImageTest As System.Windows.Controls.Image = FindVisualChildByName(TheGrid, "testImage")
        Stop
    End Sub

    Public Function FindVisualChildByName(ByVal parent As System.Windows.DependencyObject, ByVal Name As String) As System.Windows.DependencyObject
        For i As Integer = 0 To System.Windows.Media.VisualTreeHelper.GetChildrenCount(parent) - 1
            Dim child = System.Windows.Media.VisualTreeHelper.GetChild(parent, i)
            Dim controlName As String = child.GetValue(System.Windows.Controls.Control.NameProperty)
            If controlName = Name Then
                Return child
            Else
                Dim res = FindVisualChildByName(child, Name)
                If Not res Is Nothing Then
                    Return res
                End If
            End If
        Next
        Return Nothing
    End Function