Reputation: 31
I am very new to WPF and just would to ask your help for a very basic method of getting the Windows controls and their children as in Winform app. Bottom line is to have reusable code for multiple window/pages in a different different class.
Bunches of thanks before.
Public Sub GetControl(Wn As Window)
For Each Ctrl As Control In Wn.Controls
'Code here
If Ctrl.HasChildren = True Then
'Code here
End If
Next
End Sub
Upvotes: 2
Views: 4372
Reputation: 6749
So here's the down low. You need to look for UIElement, which is a base class for all UIElements in XAML. There are two main types that host controls. ContentControl and Panel.
A ContentControl has a 'Content' property that is potentially containing an object.
A Panel has a collection of UIElements property 'Children' and of type UIElement.
If you're looking just for the elements of a Window or ANY UIElement then you need to recursively search and make that list based on that information.
A Window inherits from ContentControl but that Content might be a Grid or StackPanel or any Panel or sorts and may have Children of UIElement also.
You cycle through them all until you get the results.
public MainWindow()
{
InitializeComponent();
foreach (var element in GetAllElementsFrom(this))
Debug.WriteLine(element.ToString());
}
private IEnumerable<UIElement> GetAllElementsFrom(UIElement element)
{
var uiElements = GetSingleElement();
switch (element)
{
case Panel panel:
foreach (var child in panel.Children)
uiElements = uiElements.Concat(GetInnerElements(child));
break;
case UserControl userControl:
uiElements = uiElements.Concat(GetInnerElements(userControl.Content));
break;
case ContentControl contentControl:
if (contentControl.Content is UIElement uiElement)
uiElements = uiElements.Concat(GetInnerElements(uiElement));
break;
}
return uiElements;
IEnumerable<UIElement> GetSingleElement()
{
yield return element;
}
}
Here's the XAML I used.
<Grid>
<Button>
<DockPanel>
<ContentControl>
<Grid>
<TextBox />
</Grid>
</ContentControl>
</DockPanel>
</Button>
<StackPanel>
<Label />
<TextBlock>
Hey There!!
</TextBlock>
<Grid>
<Ellipse />
</Grid>
</StackPanel>
</Grid>
And here's the result I got in my debug window:
System.Windows.Controls.Grid
System.Windows.Controls.Button
System.Windows.Controls.DockPanel
System.Windows.Controls.ContentControl
System.Windows.Controls.Grid
System.Windows.Controls.TextBox
System.Windows.Controls.StackPanel
System.Windows.Controls.Label
System.Windows.Controls.TextBlock
System.Windows.Controls.Grid
System.Windows.Shapes.Ellipse
Happy Coding! Note: Uses C# 7 syntax; if you're not on C# 7 then just make the changes, I think they're straight forward.
Upvotes: 2