Search code examples
c#arrayswpfarraylistlabel

Is there a possibility to get all Labels with the same name except different number at the end of the name?


I designed a window with WPF, and so I used a lot of Labels. My question now is, if it is possible to get all Labels that are named like this: lblinch, lblinch1, lblinch2 ... . Personally, I would like to store them in an array or in an arraylist. The Labels are not in the same parent-element except for "Window" and the first "Grid".

<Label Content="inch" Name="lblinch2" Grid.Row="0" Grid.Column="2" />
                            <Label Content="Distance between Beams Manual Input" Grid.Row="1" Grid.Column="0" />
                            <TextBox Name="tbDistanceBeamsManualInput" Width="{x:Static local:Constants.TOOL_WIDTH}" Grid.Row="1" Grid.Column="1" Margin="0,5,0,5" Background="Yellow" />
                            <Label Content="inch" Name="lblinch3" Grid.Row="1" Grid.Column="2" />
                            <Label Content="Bolt Hole Center to Column Wall * =" Grid.Row="2" Grid.Column="0" />
                            <TextBox Name="tbBHoleCenterToColumnWall" Width="{x:Static local:Constants.TOOL_WIDTH}" Grid.Row="2" Grid.Column="1" Margin="0,5,0,5" Background="Yellow" />
                            <Label Content="inch" Grid.Row="2" Name="lblinch4" Grid.Column="2" />

Solution

  • Here's what I'm doing to find controls of a specific type with a part of their x:Name:

    using System;
    using System.Collections.Generic;
    using System.Windows;
    using System.Windows.Controls;
    using System.Windows.Media;
    
    namespace WpfApp4
    {
        public partial class MainWindow : Window
        {
            public MainWindow()
            {
                InitializeComponent();
                Loaded += MainWindow_Loaded;
            }
    
            private void MainWindow_Loaded(object sender, RoutedEventArgs e)
            {
                //find labels that have "lbl" in their name
                var labels = GetControlsByName<Label>(LabelsContainer, "lbl", new List<Label>());
    
                //do something with them
                foreach (var label in labels)
                {
                    Console.WriteLine(label.Name);
                }
            }
    
            private List<T> GetControlsByName<T>(Visual root, string nameSearchTerm, List<T> result) where T : FrameworkElement
            {
                var childrenCount = VisualTreeHelper.GetChildrenCount(root);
    
                for (var i = 0; i < childrenCount; i++)
                {
                    var childVisual = (Visual)VisualTreeHelper.GetChild(root, i);
    
                    if (childVisual is T control && control.Name.Contains(nameSearchTerm))
                    {
                        result.Add(control);
                    }
    
                    GetControlsByName(childVisual, nameSearchTerm, result);
                }
    
                return result;
            }
        }
    }
    

    XAML

    <Window
        x:Class="WpfApp4.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
        xmlns:local="clr-namespace:WpfApp4"
        xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
        Title="MainWindow"
        Width="800"
        Height="450"
        mc:Ignorable="d">
        <Grid x:Name="LabelsContainer">
            <Label x:Name="lbl1" />
            <TextBlock x:Name="tbl1" />
            <Label x:Name="lbl2" />
            <Label x:Name="lbl3" />
        </Grid>
    </Window>