Home > Enterprise >  How can i use a Textbox, that was created programmatically?
How can i use a Textbox, that was created programmatically?

Time:10-25

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;
            }

        }
    }

This is how it looks so far

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;
    }
}
  • Related