0

How can i reference to a GUI element by it's name as String for all elements, even the ones in grids inside tab items. Now i have this code:

Module VisualExtensions
<System.Runtime.CompilerServices.Extension>
Public Iterator Function GetVisualChildren(Of T As Visual)(parent As DependencyObject) As IEnumerable(Of T)
    Dim child As T = Nothing
    Dim numVisuals As Integer = VisualTreeHelper.GetChildrenCount(parent)
    For i As Integer = 0 To numVisuals - 1
        Dim v As Visual = DirectCast(VisualTreeHelper.GetChild(parent, i), Visual)
        child = TryCast(v, T)
        If v IsNot Nothing Then
            For Each item In GetVisualChildren(Of T)(v)
                Yield item
            Next
        End If
        If child IsNot Nothing Then
            Yield child
        End If
    Next
End Function
End Module

Which is called by this piece of code:

Try
            For Each s In output
                Dim nameOfControl = s
                Dim window = Windows.Application.Current.Windows(0)
                Dim visuals = GetVisualChildren(Of FrameworkElement)(window)
                Dim child = visuals.OfType(Of FrameworkElement)()
                Dim match = child.FirstOrDefault(Function(x) x.Name = nameOfControl)
                match.Visibility = Visibility.Collapsed
            Next
        Catch ex As NullReferenceException

        Finally
        End Try

If s is "veleprodajaTab" it works well (code collapses that tab) and xml for that tab is:

<TabItem x:FieldModifier="public" x:Name="veleprodajaTab" Header="Maloprodaja"  FontSize="10"  VerticalAlignment="Bottom">

But if s is "buttonRefresh" it does not work, it can't reference to that object. I get a nullreferenceexception in debug child is Nothing

Code for "buttonRefresh" (with grids surounding it):

<TabItem x:FieldModifier="public" x:Name="maloprodajaTab"...
<Grid  x:FieldModifier="public" x:Name="maloprodajaTabGrid"...
<Grid   x:FieldModifier="public" x:Name="gridFckp"
<Button  x:FieldModifier="public" x:Name="buttonRefresh" Content="Refresh" HorizontalAlignment="Left" Margin="276,6,0,0" VerticalAlignment="Top" Width="75" Grid.ColumnSpan="2"/>
</grid>
</grid>

I can't seem to reference to anything inside **TabItem **

If i try to set window.buttonRefresh.Visibility = Visibility.Collapsed code works but there is a problem with referencing to childs inside grids

Thomas
  • 45
  • 1
  • 7

1 Answers1

1

You can't since the TabControl is virtualized. You need to navigate the Visual Tree passing it the name of the element you need. Have a look here: Find WPF controls by name or type

So you can do something like this:

private T FindChildByname<T>(DependencyObject parent, string name) where T : FrameworkElement
    {
        T child = default(T);
        for (int i = 0; i < VisualTreeHelper.GetChildrenCount(parent); i++)
        {
            var ch = VisualTreeHelper.GetChild(parent, i);
            child = ch as T;
            if (child != null && child.Name == name)
                break;
            else
                child = FindChildByname<T>(ch, name);

            if (child != null) break;
        }
        return child;
    }

And call it like:

Button button = FindChildByname<Button>(maloprodajaTabGrid, "buttonRefresh");
Community
  • 1
  • 1
Jinish
  • 1,983
  • 1
  • 17
  • 22
  • So, there is no way for me to call a element by x:Name as string and then set it's properties? @Jinish – Thomas Mar 07 '17 at 09:59
  • Your bindings will still work @Thomas. You can obtain the reference to the control by navigating through the Visual Tree and then set whatever properties you need to set on it. So long as proper bindings are defined on the control on dependency properties it should propogate – Jinish Mar 07 '17 at 10:03
  • Can you please show me based on my code above how would i obtain reference to refreshButton. It would be very helpfull and i would go study it from there, @Jinish – Thomas Mar 07 '17 at 10:11