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" />
CodePudding user response:
First, name your parent Grid
. ("RootGrid" in this case.)
<Grid x:Name="RootGrid">
<Label x:Name="lblinch1" />
<TextBlock />
<Label x:Name="lblinch2" />
<TextBox />
<Label x:Name="lblinch3" />
<Button />
<Label x:Name="lblinch4" />
<Label x:Name="lblinch5" />
</Grid>
Then use the VisualTreeHelper
to get the children and filter them by their names.
public partial class MainWindow : Window
{
public MainWindow()
{
InitializeComponent();
this.Loaded = MainWindow_Loaded;
}
private List<Label> LabelControls { get; } = new();
private void MainWindow_Loaded(object sender, RoutedEventArgs e)
{
int count = VisualTreeHelper.GetChildrenCount(this.RootGrid);
for (int i = 0; i < count; i )
{
if (VisualTreeHelper.GetChild(this.RootGrid, i) is Label label &&
label.Name.StartsWith("lblinch") is true)
{
LabelControls.Add(label);
}
}
}
}
CodePudding user response:
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>