Reputation: 157
In its simplest form...
I would like to create as many StackPanels as I want and then add Rectangles in them. Then to be able to change the Fill color of any one of the Rectangles when I click the Start Button for instance. All in Code Behind.
Any help would be appreciated.
For example, if our favorite beer wrote the framework I could do it like this:
XAML:
<Page
x:Class="Test2.MainPage"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:local="using:Test2"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
mc:Ignorable="d">
<Grid Background="White">
<Grid.RowDefinitions>
<RowDefinition Height="Auto"/>
<RowDefinition Height="*"/>
</Grid.RowDefinitions>
<StackPanel Orientation="Horizontal">
<Button Name="StartButton" Content="Start" Click="StartButton_Click" Height="30" Width="200" Margin="5"/>
</StackPanel>
<StackPanel Grid.Row="1" Name="myStackPanel" VerticalAlignment="Top"/>
</Grid>
</Page>
Code Behind:
namespace Test2
{
public sealed partial class MainPage : Page
{
public MainPage()
{
this.InitializeComponent();
for (var i = 0; i < 5; i++) // The 5 here could be any number
{
myStackPanel.Children.Add(new StackPanel
{
Name = "myPanel" + i,
Orientation = Orientation.Horizontal
});
for (var j = 0; j < 10; j++) // The 10 here could be any number
{
("myPanel" + i).Children.Add(new Rectangle
{
Name = "myRectangle" + i + "-" + j,
Fill = new SolidColorBrush(Colors.Black),
Width = 20,
Height = 20,
Margin = new Thickness(1)
});
}
}
}
private void StartButton_Click(object sender, RoutedEventArgs e)
{
// E.G. To change the Fill color of Rectangle4 in StackPanel2
("myRectangle" + 2 + "-" + 4).Fill = new SolidColorBrush(Colors.Red);
}
}
}
Upvotes: 3
Views: 10779
Reputation: 184526
That is not how you approach this in WPF, at all.
You usually do not concern yourself with any UI components but only the data. In this case you data bind an ItemsControl
to a list of rows, each row containing a list of cells. In the ItemsControl
definition you then set an ItemTemplate
that contains another ItemsControl
binding to the cells. In the nested ItemsControl
you then can set an ItemTemplate
where you bind the Background
to a (notifying) property of your cells which you then just need to change in code.
Check out these overviews:
You may also want to look into the Model-View-ViewModel pattern to ensure a suitable application architecture.
Upvotes: 2
Reputation: 4923
Firstly, to add Rectangle shapes, we can create an instance of StackPanel and manipulate its Children elements:
for (var i = 0; i < 5; i++) // The 5 here could be any number
{
StackPanel sp = new StackPanel
{
Name = "myPanel" + i,
Orientation = Orientation.Horizontal
};
myStackPanel.Children.Add(sp);
for (var j = 0; j < 10; j++) // The 10 here could be any number
{
sp.Children.Add(new Rectangle
{
Name = "myRectangle" + i + "-" + j,
Fill = new SolidColorBrush(Colors.Black),
Width = 20,
Height = 20,
Margin = new Thickness(1)
});
}
}
Then to be able to change the Fill color of any one of the Rectangles when I click the Start Button for instance. All in Code Behind.
As tgpdyk mentioned, we need to use VisualTreeHelper to find the specified rectangle shape.
Helper class:
public static class FrameworkElementExtensions
{
public static T TraverseCTFindShape<T>(DependencyObject root, String name) where T : Windows.UI.Xaml.Shapes.Shape
{
T control = null;
for (int i = 0; i < VisualTreeHelper.GetChildrenCount(root); i++)
{
var child = VisualTreeHelper.GetChild(root, i);
string childName = child.GetValue(FrameworkElement.NameProperty) as string;
control = child as T;
if (childName == name)
{
return control;
}
else
{
control = TraverseCTFindShape<T>(child, name);
if (control != null)
{
return control;
}
}
}
return control;
}
}
How to use it:
private void StartButton_Click(object sender, RoutedEventArgs e)
{
// E.G. To change the Fill color of Rectangle4 in StackPanel2
var rec = FrameworkElementExtensions.TraverseCTFindShape<Shape>(myStackPanel, "myRectangle" + 2 + "-" + 4);
rec.Fill = new SolidColorBrush(Colors.Red);
}
I've uploaded my sample to Github repository
Upvotes: 6