Member 12603716 Ответов: 2

Как добавить текстовые поля на form2 dinamicaly, нажав кнопку на form1?


Я написал код, который добавляет текстовые поля при нажатии кнопки на той же странице . и код работает довольно хорошо. теперь я хочу добавить несколько текстовых полей в другую форму, скажем, Form2, когда я нажимаю на кнопку на Form1.
Ниже приведен код, который я написал для добавления текстовых полей на той же странице . не могли бы вы помочь мне добавить текстовые поля на другую страницу?

Что я уже пробовал:

общественности частичного класс form1:форма
{
статический int j=1;
открытый form1()
{
метод InitializeComponent();
}
частный недействительными обработчика button1_click(объект отправителя, EventArgs в электронной)

{
TextBox tb = новое текстовое поле();
tb. text = "" + j;

Точка p = новая точка(20 + j, 30* j);
ТБ.Расположение = Р
этот.Управления.Добавить (ТБ);
Дж++
}
}

2 Ответов

Рейтинг:
2

BillWoodruff

Глядя на ваш код, я вижу, что вы не храните ссылку на элементы управления Textbox, которые вы создаете во время выполнения. В тот момент, код обработчика button1_click выходов нет переменной 'ТБ.

Итак, если вы хотите прочитать текст в одном из этих созданных текстовых полей, вам придется найти его, но вы даже не дали текстовым полям четкого идентифицирующего значения имени: как вы его найдете, если в форме есть много других элементов управления ?

Это почти всегда ошибка, потому что вы будете хотеть ... в любом реальном приложении ... в какой-то момент используйте созданные во время выполнения элементы управления ... в случае текстовых полей: прочитайте их текстовое содержимое, установите их текстовое содержимое. И, вероятно, вы захотите прикрепить некоторые события к этим созданным во время выполнения элементам управления.

Существует множество способов отслеживать текстовые поля; вот одна идея:

a. создайте новый проект WinForm: 'TestRunTimeControlCreation

б. поместите две кнопки на форму 1: "button1", "button2".

c. добавьте в проект вторую форму: 'Form2

d. замените автоматически сгенерированный код для формы 1 следующим:

#region Region:

using System;
using System.Collections.Generic;
using System.Drawing;
using System.Windows.Forms;

#endregion

namespace TestRunTimeControlCreation
    public partial class Form1 : Form
    {
        private const string TextBoxNamePrefix = "tbx_";

        private readonly Dictionary<string, TextBox> _dctForm1NameToTBox = new Dictionary<string, TextBox>();

        private readonly Dictionary<string, TextBox> _dctForm2NameToTBox = new Dictionary<string, TextBox>();

        private readonly Form2 _form2Instance;

        public Form1()
        {
            InitializeComponent();
        }

        private void Form1_Load(object sender, EventArgs e)
        {
            _form2Instance = new Form2();
            _form2Instance.Show();
        }

        private void button1_Click(object sender, EventArgs e)
        {
            AddTextBoxToForm(this, 5);
        }

        private void button2_Click(object sender, EventArgs e)
        {
            AddTextBoxToForm(_form2Instance, 5);
        }

        public void AddTextBoxToForm(Form targetform, int nTextBox)
        {
            if (targetform == null || nTextBox < 1)
            {
                throw new ArgumentException("error in AddTextBoxToForm");
            }

            string namebase = string.Format("{0}{1}", targetform.Name, TextBoxNamePrefix);

            int tBxCnt;

            for (var x = 0; x < nTextBox; x++)
            {
                var newTextBox = new TextBox();
                newTextBox.Size = new Size(100,25);

                targetform.Controls.Add(newTextBox);

                if (targetform is Form1)
                {
                    tBxCnt = _dctForm1NameToTBox.Count;
                    newTextBox.Name = string.Format("{0}{1}", namebase, tBxCnt);

                    _dctForm1NameToTBox.Add(newTextBox.Name, newTextBox);
                    
                    // set location on Form1 here
                    newTextBox.Location = new Point(30, tBxCnt*40 + 60);
                }
                else if (targetform is Form2)
                {
                    tBxCnt = _dctForm2NameToTBox.Count;
                    newTextBox.Name = string.Format("{0}{1}", namebase, tBxCnt);

                    _dctForm2NameToTBox.Add(newTextBox.Name, newTextBox);

                    // set location on Form2 here
                    newTextBox.Location = new Point(30, tBxCnt*40 + 30);
                }
                else
                {
                    // something is wrong !
                    throw new ArgumentException(string.Format("invalid Form parameter{0}", targetform.Name));
                }

                newTextBox.Enter += OnTextBoxEnter;
                newTextBox.Leave += OnTextBoxLeave;

                // apply your own labeling scheme here ?
                newTextBox.Text = newTextBox.Name;
            }
        }

        private void OnTextBoxLeave(object sender, EventArgs eventArgs)
        {
            TextBox tBox = sender as TextBox;
            Console.WriteLine("Leave TextBox: {0} TextBox: {1} text: {2}", tBox.TopLevelControl.Name, tBox.Name, tBox.Text);
        }

        private void OnTextBoxEnter(object sender, EventArgs eventArgs)
        {
            TextBox tBox = sender as TextBox;
            Console.WriteLine("Enter TextBox: {0} TextBox: {1} text: {2}", tBox.TopLevelControl.Name, tBox.Name, tBox.Text);
        }
    }
}
Подключите обработчики событий для двух кнопок на форме 1 к обработчикам кликов "button1" и "button2".

Запуск проекта. Нажмите кнопки, нажмите в течение нескольких текстовых полей на форме form1 щелкните в несколько текстовых полей на форме Form2. Затем: проверьте, что было записано в консоль (в окне вывода Visual Studio).

После того как вы создали такую структуру словаря для сопоставления свойств "имя", назначенных созданным текстовым полям во время выполнения, вы можете получить доступ к любому текстовому полю с помощью строкового ключа " имя:
TextBox getATbx;

if(_dctForm1NameToTBox.TryGetValue("Form1_Tbx_2", out getATbx))
{
    // getATbx got a Textbox
}


Рейтинг:
17

OriginalGriff

Не.
Вместо этого используйте тот же код на Form2, чтобы добавить туда текстовые поля и вызвать его из Form1:

public partial class Form1:Form
    {
    ...
    private void button1_Click(object sender, EventArgs e)
        {
        Form2 f2 = new Form2();
        f2.AddTextBoxes();
        f2.Show();
        }
    }

public partial class Form2:Form
    {
    ...
    public void AddTextBoxes(int count)
        {
        for (int i = 1; i <= count; i++)
            {
            TextBox tb = new TextBox();
            tb.text = " " + i;
            Point p = new Point(20 + i,30 * i);
            tb.Location = p
            Controls.Add(tb);
            }
        }
    }
Таким образом, Form2 не нужно знать, что Form1 существует, и Form1 не заблокирован во внутренних элементах Form2.


BillWoodruff

Подходящая музыка для этого: https://www.youtube.com/watch?v=J1ia-OQThno

Примечание: Я бы разместил ссылку на оригинальное официальное видео с Летицией Кастой, но это, возможно, не будет SFW/KSS.

О боже, в моей голове звенят тревожные колокольчики. Вы не сохраняете ссылку на вновь созданный экземпляр Form2 в Form1, а в Form2 вы не сохраняете ссылку на созданные во время выполнения текстовые поля. Экземпляр Form2 теперь находится во внешнем пространстве; текстовые поля на Form2 теперь находятся во внутреннем пространстве :)

Моя голова-это сплод.

OriginalGriff

Экземпляр формы может быть релевантным, а может и не быть релевантным, и текстовые поля (при необходимости) могут быть доступны через коллекцию элементов управления.
Это не идеально, но я не хотел возиться с его кодом больше, чем должен был, чтобы показать ему контуры того, что нужно делать.
Твоя голова-это сплод? Ты меня просто пугаешь!

OriginalGriff

Я проверил оригинал Laetitia Casta, и вы, вероятно,правы насчет NSFW. Я никогда не видел его раньше, должно быть, я вел более защищенную жизнь, чем думал...: вздох: