I have an issue with XAML in my Maui project. Disclaimer: I'm not an expert with this technology, so please show me some mercy ;).
This is my xaml:
<ContentView xmlns="http://schemas.microsoft.com/dotnet/2021/maui"
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
x:Class="ApeEvoPrototype.NumPad">
<ScrollView>
<Grid
ColumnDefinitions="{DynamicResource NumPad_GridColumnPrincipale}"
RowDefinitions="{DynamicResource NumPad_GridRowPrincipale}">
<Frame
Grid.Row="0"
Grid.Column="0"
Style="{DynamicResource NumPad_Frame}">
<Grid x:Name="numPadGrid" Style="{DynamicResource NumPad_GridInterno}">
<StackLayout Grid.Row="0" Grid.ColumnSpan="3">
<Grid x:Name="containerEditor" Style="{DynamicResource NumPad_GridLinguetta}">
<Label Grid.Column="0" VerticalTextAlignment="Center" Text="Quantity:" TextColor="Black" />
<Editor Grid.Column="1" x:Name="txtQuantity" VerticalTextAlignment="Center" HorizontalTextAlignment="End"/>
<Button Grid.Column="2" x:Name="btnBck" Text="Bck" Clicked="Button_Clicked_Bck" BindingContext="2000" />
</Grid>
</StackLayout>
<StackLayout Grid.Column="0" Grid.Row="1" Style="{DynamicResource NumPad_StackTastierino}">
<Grid Style="{DynamicResource NumPad_GridTastierino}">
<Button x:Name="btn1" Style="{DynamicResource NumPad_Button}" Text="1" Clicked="Button_Clicked" BindingContext="1"/>
</Grid>
<Grid Style="{DynamicResource NumPad_GridTastierino}">
<Button x:Name="btn4" Style="{DynamicResource NumPad_Button}" Text="4" Clicked="Button_Clicked" BindingContext="4"/>
</Grid>
<Grid Style="{DynamicResource NumPad_GridTastierino}">
<Button x:Name="btn7" Style="{DynamicResource NumPad_Button}" Text="7" Clicked="Button_Clicked" BindingContext="7"/>
</Grid>
<Grid Style="{DynamicResource NumPad_GridTastierino}">
<Button x:Name="btnTot" Style="{DynamicResource NumPad_Button}" Text="All" Clicked="Button_Clicked_Tot" BindingContext="3000" />
</Grid>
</StackLayout>
<StackLayout Grid.Column="1" Grid.Row="1" Style="{DynamicResource NumPad_StackTastierino}">
<Grid Style="{DynamicResource NumPad_GridTastierino}">
<Button x:Name="btn2" Style="{DynamicResource NumPad_Button}" Text="2" Clicked="Button_Clicked" BindingContext="2"/>
</Grid>
<Grid Style="{DynamicResource NumPad_GridTastierino}">
<Button x:Name="btn5" Style="{DynamicResource NumPad_Button}" Text="5" Clicked="Button_Clicked" BindingContext="5"/>
</Grid>
<Grid Style="{DynamicResource NumPad_GridTastierino}">
<Button x:Name="btn8" Style="{DynamicResource NumPad_Button}" Text="8" Clicked="Button_Clicked" BindingContext="8"/>
</Grid>
<Grid Style="{DynamicResource NumPad_GridTastierino}">
<Button x:Name="btn0" Style="{DynamicResource NumPad_Button}" Text="0" Clicked="Button_Clicked" BindingContext="0"/>
</Grid>
</StackLayout>
<StackLayout Grid.Column="2" Grid.Row="1" Style="{DynamicResource NumPad_StackTastierino}">
<Grid Style="{DynamicResource NumPad_GridTastierino}">
<Button x:Name="btn3" Style="{DynamicResource NumPad_Button}" Text="3" Clicked="Button_Clicked" BindingContext="3"/>
</Grid>
<Grid Style="{DynamicResource NumPad_GridTastierino}">
<Button x:Name="btn6" Style="{DynamicResource NumPad_Button}" Text="6" Clicked="Button_Clicked" BindingContext="6" />
</Grid>
<Grid Style="{DynamicResource NumPad_GridTastierino}">
<Button x:Name="btn9" Style="{DynamicResource NumPad_Button}" Text="9" Clicked="Button_Clicked" BindingContext="9"/>
</Grid>
<Grid Style="{DynamicResource NumPad_GridTastierino}">
<Button x:Name="btnC" Style="{DynamicResource NumPad_Button}" Text="C" Clicked="Button_Clicked_C" BindingContext="1000" />
</Grid>
</StackLayout>
</Grid>
</Frame>
</Grid>
</ScrollView>
</ContentView>
As you see I have a lot of buttons named "btn?", my objective is access these buttons dynamically, without utilizing their names. The only way that I can do that is to define a name of the single Grid that contains the button, like I do here:
<Grid x:Name="containerEditor" Style="{DynamicResource NumPad_GridLinguetta}">
and in my code perform:
var buttons = containerEditor.Children.OfType<Button>();
In this way I can access all the resource buttons in Grid. The problem with this approach is that the Children
method explores only the first tier of the Control it doesn't work recursively.
Can someone help me?
CodePudding user response:
A method like this should do.
public static IEnumerable<T> FindChildrenOfType<T>(DependencyObject parent) where T : DependencyObject
{
if (parent is ContentControl contentControl)
{
if (contentControl.Content is T contentOfT)
{
yield return contentOfT;
}
if (contentControl.Content is DependencyObject dependencyObjectContent)
{
foreach (T grandChild in FindChildrenOfType<T>(dependencyObjectContent))
{
yield return grandChild;
}
}
}
else
{
for (int i = 0; i < VisualTreeHelper.GetChildrenCount(parent); i )
{
DependencyObject child = VisualTreeHelper.GetChild(parent, i);
if (child is T childOfT)
{
yield return childOfT;
}
foreach (T grandChild in FindChildrenOfType<T>(child))
{
yield return grandChild;
}
}
}
}
Name your root, "Root" in this example, and use it like this:
var buttons = FindChildrenOfType<Button>(this.Root)
.Where(x => x.Name.StartsWith("btn"))
.ToList();
CodePudding user response:
I solve my issue with List with handle all the controls into my View
List<IVisualTreeElement> listButton = (List<IVisualTreeElement>)numPadGrid.GetVisualTreeDescendants();
foreach (IVisualTreeElement button in listButton)
{
if (button is Button)
{
Button buttonCatch = (Button)button;
ButtonCatch.BorderColor = ColorBorderButton;
}
}