I'm trying to write a four-in-a-row game in WPF.
I want to programmatically insert textboxes, which are my gameboxes. It works now, but I don't know how to control them with a button afterwards because I can't use the names I assign them.
The goal is to change the background color of the textboxes after pressing a button.
public MainWindow()
{
InitializeComponent();
int x = 100;
int y = 190;
for (int i = 1; i < 43; i )
{
TextBox tbx = new TextBox();
tbx.Name = "Field" i;
tbx.Height = tbx.Width = 50;
tbx.HorizontalAlignment = HorizontalAlignment.Left;
tbx.VerticalAlignment = VerticalAlignment.Top;
tbx.Margin = new Thickness(x, y, 0, 0);
myGrid.Children.Add(tbx);
x = 55;
if (i % 7 == 0)
{
y = 55;
x = 100;
}
}
}
CodePudding user response:
Implement the MVVM architectural pattern, using WPF Data Binding and Data Templating.
Use an ItemsControl
with a UniformGrid as ItemsPanel
and a TextBox in the ItemTemplate
. Bind its ItemsSource
property to a collection of data items with a string property.
<ItemsControl ItemsSource="{Binding Items}">
<ItemsControl.ItemsPanel>
<ItemsPanelTemplate>
<UniformGrid Columns="7"/>
</ItemsPanelTemplate>
</ItemsControl.ItemsPanel>
<ItemsControl.ItemTemplate>
<DataTemplate>
<TextBox Text="{Binding Text}"/>
</DataTemplate>
</ItemsControl.ItemTemplate>
</ItemsControl>
Use code behind with a view model like this:
public partial class MainWindow : Window
{
public MainWindow()
{
InitializeComponent();
DataContext = new ViewModel();
}
}
public class ViewModel
{
public List<Item> Items { get; }
public ViewModel()
{
// create a List of 42 Item objects
Items = Enumerable.Range(0, 42).Select(i => new Item()).ToList();
}
}
public class Item
{
public string Text { get; set; }
}
CodePudding user response:
Integer division and modulo operations work best when numbering from 0 to N-1. If you started numbering i at 0, you could write
x = 100 (i % 7) * 55;
y = 190 i/7 * 55;
// and
a[i/7, i%7] = tbx;
Then you can access the textboxes with a[col, row]
with both indexes ranging from 0 to 6.
To store textboxes you must use an array of TextBox
. E.g. declare a class field as:
private TextBox[] a = new TextBox[7, 7];
(You of course it is better to choose a speaking name like textBoxes
instead of a
. Or at least t
.)
But you could simply use nested for loops instead of doing any index calculations
for (int ix = 0; ix < 7; ix ) {
for (int iy = 0; iy < 7; iy ) {
int x = 100 55 * ix;
int y = 190 55 * iy;
var tbx = new TextBox();
tbx.Height = tbx.Width = 50;
tbx.HorizontalAlignment = HorizontalAlignment.Left;
tbx.VerticalAlignment = VerticalAlignment.Top;
tbx.Margin = new Thickness(x, y, 0, 0);
myGrid.Children.Add(tbx);
textBoxes[ix, iy] = tbx;
}
}