开发者

VB.NET - For Each in WPF-Controls

I want to check some childelements in my WPF-Form. In WindowsForms that was quite easy with (like):

For Each control as Textbox in Me
 control.text = "hello people"
Next

How do I do that in WPF within my XAML.VB-File? I got a listbox with some childelements here which I want to analyse.

Greetz and开发者_运维技巧 thanks for your ideas!


It depends. Suppose you have a ListBox defined as:

<ListBox x:Name="listBox">
    <ListBoxItem>Item1</ListBoxItem>
    <ListBoxItem>Item2</ListBoxItem>
    <ListBoxItem>Item3</ListBoxItem>
</ListBox>

You can get the ListBoxItems within it by just iterating through the Items collection as such:

For Each x As ListBoxItem In Me.listBox.Items
    Console.WriteLine(x.Content.ToString())
Next

However, this will not work if the items in the ListBox was defined via the ItemsSource property. So if the items are defined like this:

    Dim itemsSource As New List(Of Object)
    itemsSource.Add("Object1")
    itemsSource.Add(200D)
    itemsSource.Add(DateTime.Now)
    Me.listBox.ItemsSource = itemsSource

you'll have to use the ItemContainerGenerator to get the actual ListBoxItem.

    For Each x In Me.listBox.Items
        Dim item As ListBoxItem = DirectCast(Me.listBox.ItemContainerGenerator.ContainerFromItem(x), ListBoxItem)
        Console.WriteLine(item.Content.ToString())
    Next

Now, the examples above are specific to a ListBox control. If you want a way to get all the items in the entire Visual Tree of a given control (e.g. the Window), you'll have to use the VisualTreeHelper.GetChild (as suggested by Brian).

Anyway, here's a little sample I wrote that might help you out. It contains everything I described above.

XAML:

<Window x:Class="MainWindow"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    Title="MainWindow" Height="350" Width="525" Loaded="Window_Loaded">
    <StackPanel x:Name="sp">
        <ListBox x:Name="listBox">
            <ListBoxItem>Item1</ListBoxItem>
            <ListBoxItem>Item2</ListBoxItem>
            <ListBoxItem>Item3</ListBoxItem>
        </ListBox>

        <Button x:Name="btnChange" Click="btnChange_Click">Change ItemsSource</Button>
        <Button x:Name="btnPrint" Click="btnPrint_Click">Print Items</Button>

        <Button x:Name="btnPrintVisualTree" Click="btnPrintVisualTree_Click">Print Visual Tree</Button>
    </StackPanel>
</Window>

Code-behind:

Class MainWindow 


    Private Sub Window_Loaded(ByVal sender As System.Object, ByVal e As System.Windows.RoutedEventArgs)

        'Get all ListBoxItems
        For Each x As ListBoxItem In Me.listBox.Items
            Console.WriteLine(x.Content.ToString())
        Next

        'Get all items in the StackPanel
        For Each y As UIElement In Me.sp.Children
            Console.WriteLine(y.ToString())
        Next

    End Sub

    Private Sub btnChange_Click(ByVal sender As System.Object, ByVal e As System.Windows.RoutedEventArgs)
        'Set an ItemsSource for the ListBox

        Me.listBox.Items.Clear()

        Dim itemsSource As New List(Of Object)
        itemsSource.Add("Object1")
        itemsSource.Add(200D)
        itemsSource.Add(DateTime.Now)
        Me.listBox.ItemsSource = itemsSource
    End Sub

    Private Sub btnPrint_Click(ByVal sender As System.Object, ByVal e As System.Windows.RoutedEventArgs)

        'Print the items within the ListBox
        For Each x In Me.listBox.Items
            Dim item As ListBoxItem = DirectCast(Me.listBox.ItemContainerGenerator.ContainerFromItem(x), ListBoxItem)
            Console.WriteLine(item.Content.ToString())
        Next

    End Sub

    Private Sub btnPrintVisualTree_Click(ByVal sender As System.Object, ByVal e As System.Windows.RoutedEventArgs)
        PrintVisualTreeRecursive(Me)
    End Sub

    Private Sub PrintVisualTreeRecursive(ByVal parent As DependencyObject)

        Console.WriteLine(parent.ToString())

        Dim count As Integer = VisualTreeHelper.GetChildrenCount(parent)
        If count > 0 Then
            For n As Integer = 0 To count - 1
                Dim child As DependencyObject = VisualTreeHelper.GetChild(parent, n)
                PrintVisualTreeRecursive(child)
            Next
        End If
    End Sub

End Class


You will have to use the VisualTreeHelper.GetChild method and call into it recursively to descend the tree. If you know the name of control you are looking for then you can use the FrameworkElement.FindName method. There is more information in this question with plenty of options and example code.

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜