Форум программистов, компьютерный форум, киберфорум
C# Windows Forms
Войти
Регистрация
Восстановить пароль
 
Рейтинг 4.93/54: Рейтинг темы: голосов - 54, средняя оценка - 4.93
290 / 231 / 57
Регистрация: 03.02.2011
Сообщений: 1,954
Записей в блоге: 1
1

Динамическое создание и удаление компонентов

10.07.2011, 11:37. Показов 10037. Ответов 15
Метки нет (Все метки)

Есть код на VB6

Visual Basic
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
Dim RowQuantity As integer
 
 
Private Sub ChkAutoN_Click()  ' Включение\выключение автонумерации чекбоксом
RowQuantity = CboN.Count  'CboN - комбобокс, заполняется динамически.
For i = 1 To RowQuantity ' активизация\погашение переключателей нумерации строк и списков нумерации
    If ChkAutoN.Value = 1 Then       ' ChkAutoN - чекбокс
        ChkN(i - 1).Enabled = True     ' ChkN- чекбокс
        CboN(i - 1).Enabled = False    ' CboN- чекбокс
        If CboN(i - 1).Text = "->" Then
            ChkN(i - 1).Value = 0
        Else
            ChkN(i - 1).Value = 1
        End If
    Else
        ChkN(i - 1).Enabled = False
        ChkN(i - 1).Value = 0
        CboN(i - 1).Enabled = True
        ChkList.Value = 0
    End If
Next i
End Sub
Т.е. в программе динамически создаются и удаляются чекбоксы с комбобоксами. Как такой код реализовать в C#?
Операторы ++ и -- я так понял для компонентов не подходят?
Спасибо.

Добавлено через 19 минут
А вот код создания:
Visual Basic
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
Private Sub AutoN()
If ChkAutoN.Value = 1 Then   'ChkAutoN - чекбокс
    RowQuantity = CboN.Count
    j2 = 0
    If RowQuantity = 1 Then
        CboN(0).ListIndex = 0
        ChkN(0).Value = 0
        ChkN(0).Enabled = False
    Else
        For i2 = 1 To RowQuantity
            If ChkN(i2 - 1).Value = 1 Then
                j2 = j2 + 1
                CboN(i2 - 1).ListIndex = j2 + 1
            Else
                CboN(i2 - 1).ListIndex = 1
            End If
        Next i2
    End If
End If
End Sub
 Комментарий модератора 
Внимательнее выбирайте раздел для создания тем.
0
Programming
Эксперт
94731 / 64177 / 26122
Регистрация: 12.04.2006
Сообщений: 116,782
10.07.2011, 11:37
Ответы с готовыми решениями:

Динамическое создание и удаление компонентов
Доброго времени суток у меня такой вопрос. мне нужно динамически создавать определенное...

Динамическое создание компонентов
Как сделать так чтоб по клику на кнопку создавалась новая панель в другой панели, и сразу вылазило...

Реализовать динамическое добавление/удаление компонентов textbox на форму
Добрый день! Каким образом можно реализовать динамическое добавление/удаление компонентов textbox...

Динамическое создание компонентов Chart
Подскажите,пожалуйста,как динамически создать несколько charts на одной форме? Можно ли сделать это...

15
389 / 304 / 67
Регистрация: 10.07.2010
Сообщений: 802
10.07.2011, 11:38 2
Бейсик не знаю, но так создаются динамически компоненты в C#:
C#
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
CheckBox cb = new CheckBox();
cb.Location = new Point(100, 200);
/* или, что аналогично:
 * cb.Left=100;
 * cb.Top=200;*/
cb.Text = "Это чекбокс";
cb.Checked = true;
this.Controls.Add(cb);//добавление созданного компонента на форму
 
ComboBox combo = new ComboBox();
combo.Items.Add("11111");
/* если необходимо добавить сразу несколько значений, то:
 * string[] mas=new string[]{"111","222","333"};
 * combo.Items.AddRange(mas);*/
combo.Location = new Point(300,200);
combo.Width = 50;
this.Controls.Add(combo);
Ну это так, в общих чертах
0
290 / 231 / 57
Регистрация: 03.02.2011
Сообщений: 1,954
Записей в блоге: 1
10.07.2011, 11:46  [ТС] 3
т.е. чтобы узнать ChkN(i - 1) - нужно каждому новому элементу "красиво" давать имя, беря))) его из некоего массива (1,2,3,4,5,6.....) ? Ну чтоб по порядку.
А потом сравнивать имя с массивом чета-гдета вычитать = найдем имя.
Т.е. то что в басике в 1 строке, в шарпе нужно целый чуть ли не класс создавать? О_о
Может есть путь проще?
0
290 / 231 / 57
Регистрация: 03.02.2011
Сообщений: 1,954
Записей в блоге: 1
10.07.2011, 11:58  [ТС] 4
Вообще, логика такова:
Миниатюры
Динамическое создание и удаление компонентов  
0
389 / 304 / 67
Регистрация: 10.07.2010
Сообщений: 802
10.07.2011, 12:17 5
что именно делается в бейсике в одной строчке? и да, то что вы показали на картинке, будет побольше приведенного вами кода.
0
290 / 231 / 57
Регистрация: 03.02.2011
Сообщений: 1,954
Записей в блоге: 1
10.07.2011, 13:55  [ТС] 6
zelen, да, вы правы. Там побольше одной строки))

Visual Basic
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
Private Sub CboLoad() ' Процедура загрузки новой строки
RowQuantity = CboN.Count
Load CboN(RowQuantity)
    CboN(RowQuantity).Clear
        For i1 = 1 To RowQuantityMax + 2
        CboN(RowQuantity).AddItem N(i1)
        Next i1
    CboN(RowQuantity).Top = CboN(RowQuantity - 1).Top + CboN(RowQuantity - 1).Height + 120
    CboN(RowQuantity).Left = CboN(RowQuantity - 1).Left
    CboN(RowQuantity).Visible = True
    
Load CboTT(RowQuantity)
    CboTT(RowQuantity).Clear
        i1 = CboTTType.ListIndex + 1
        For j1 = 1 To TTQuantity(i1)
            CboTT(RowQuantity).AddItem TT(i1, j1)
        Next j1
    CboTT(RowQuantity).Top = CboN(RowQuantity).Top
    CboTT(RowQuantity).Left = CboTT(RowQuantity - 1).Left
    CboTT(RowQuantity).Visible = True
 
Load ChkN(RowQuantity)
    ChkN(RowQuantity).Top = CboN(RowQuantity).Top
    ChkN(RowQuantity).Left = ChkN(RowQuantity - 1).Left
    ChkN(RowQuantity).Visible = True
    m1 = 1 ' автонумерации выключена
    If ChkAutoN.Value = 1 Then
        ChkN(RowQuantity).Value = 1
        ChkN(RowQuantity).Enabled = True
        CboN(RowQuantity).Enabled = False
        If RowQuantity = 1 Then
            ChkN(0).Enabled = True
            ChkN(0).Value = 1
        End If
    Else
        ChkN(RowQuantity).Value = 0
        ChkN(RowQuantity).Enabled = False
        CboN(RowQuantity).Enabled = True
    End If
m1 = 0 ' автонумерации включена
FrmMain.Height = FrmMain.Height + CboN(RowQuantity - 1).Height + 120
End Sub
 
Private Sub CboUnLoad()  ' Процедура удаления  строки
RowQuantity = CboN.Count
Unload CboN(RowQuantity - 1)
Unload CboTT(RowQuantity - 1)
Unload ChkN(RowQuantity - 1)
FrmMain.Height = FrmMain.Height - CboN(RowQuantity - 2).Height - 120
End Sub
Добавлено через 9 минут
мне непонятно вот что? каким образом компонентам присваиваются имена? Или пофигу?)))
Удаление строк идет от комбобокса (длинный такой) с полученным фокусом.

Добавлено через 1 час 19 минут
Ёмаё, отпинали темку)))
Но вообще, да - .NET Windows Forms самое оно, спасибо. Пережнее место с бейсиком - никак не связано.
0
389 / 304 / 67
Регистрация: 10.07.2010
Сообщений: 802
10.07.2011, 14:29 7
имена не имеют тут большой роли. Можно вообще не указывать имя компонента. Имена можно указать для собственного удобства. Я вам кое что покажу что возможно прояснит ситуацию на примере чек бокса:
вот мы создали чек бокс а теперь для него определяем событие изменения "выделенности" так скажем
C#
1
2
3
4
 CheckBox check = new CheckBox();
..............................
check.CheckedChanged += new EventHandler(check_CheckedChanged);
this.Controls.Add(check);
так вот при выделении чек бокса, будет выполнятся метод check_CheckedChanged
C#
1
2
3
4
5
void check_CheckedChanged(object sender, EventArgs e)
{
      if (!((CheckBox)sender).Checked)
         ........................                
}
в sender передается чекбокс который вызвал событие, это стандартная шарповская штука. что бы получить доступ к этому объекту, так как sender - это переменная object (может принимать значения любого типа) и мы знаем что в ней хранится CheckBox то явно преобразуя данную переменную к CheckBox мы получаем доступ к управлению чекбоксом который вызвал метод. Так же происходит со всеми другими событиями, такими как Enter(получение фокуса) и тд.
1
290 / 231 / 57
Регистрация: 03.02.2011
Сообщений: 1,954
Записей в блоге: 1
10.07.2011, 23:15  [ТС] 8
Это я понял;
C#
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
public partial class Form1 : Form
    {
        CheckBox check = new CheckBox();
        public Form1()
        {
            InitializeComponent();
        }
 
        private void button1_Click(object sender, EventArgs e)
        {
            check.Location = new Point(checkBox1.Height + 1, checkBox1.Width + 1);
            check.Text = "Это чекбокс";
            check.Checked = true;
            this.Controls.Add(check);
        }
но как добавлять новый с height + 10 и Width +10 к уже динамически созданному с помощью одной кнопки?
Наверное нужно знать где он, а это либо по имени, либо ещё как-то. Вот это-то и не понятно

Добавлено через 21 минуту
тут не в focus дело. С focus можно и потом разобраться.
Изначальный вопрос стоял так:
(перефразируя) как динамически создать второй и последующие чекбоксы одной кнопкой и так же их (одной кнопкой, но другой) удалить. А потом уже и второй вопрос: как удалить динамически созданный чекбокс N если у него фокус, а остальные как бы " подвинуть".
0
290 / 231 / 57
Регистрация: 03.02.2011
Сообщений: 1,954
Записей в блоге: 1
11.07.2011, 17:03  [ТС] 9
Создать создал:
C#
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
List<ComboBox> lst = new List<ComboBox>();
        public Form1()
        {
            InitializeComponent();
 
 
        }
 
 
 
 
        private void button1_Click(object sender, EventArgs e)
        {
            
 
            ComboBox combo = new ComboBox();
            combo.Items.Add("Это чекбокс " + lst.Count.ToString());
            combo.SelectedIndex = 0;
            
            
            combo.Location = new Point(combo.Width, combo.Height * lst.Count + 10);
            this.Controls.Add(combo);
            lst.Add(combo);
 
        }
а как теперь удалить только тот компонент, который содержит курсор?
Focus не получится, потомучто как только жмакаем батон 2 фокус сразу на него переходит.
Не могли бы вы ещё раз объяснить про sender?
Миниатюры
Динамическое создание и удаление компонентов  
0
609 / 533 / 114
Регистрация: 24.03.2011
Сообщений: 576
11.07.2011, 18:19 10
Цитата Сообщение от skilllab Посмотреть сообщение
а как теперь удалить только тот компонент, который содержит курсор?
один из вариантов:
C#
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
        List<ComboBox> lst = new List<ComboBox>();
        object s;
 
        private void button1_Click(object sender, EventArgs e)
        {
            ComboBox combo = new ComboBox();
            combo.Enter += new System.EventHandler(this.combo_Enter);
            combo.Items.Add("Это чекбокс " + lst.Count.ToString());
            combo.SelectedIndex = 0;
 
            combo.Location = new Point(combo.Width, combo.Height * lst.Count + 10);
            this.Controls.Add(combo);
            lst.Add(combo);
        }
 
        private void button2_Click(object sender, EventArgs e)
        {
            this.Controls.Remove((s as ComboBox));
            lst.Remove((s as ComboBox));
        }
 
        private void combo_Enter(object sender, EventArgs e)
        {
            s = sender;
        }
1
290 / 231 / 57
Регистрация: 03.02.2011
Сообщений: 1,954
Записей в блоге: 1
11.07.2011, 20:17  [ТС] 11
Спасибо большое. Я уж собирался переопределять компонент комбобокс с новым свойством. )))

Добавлено через 1 час 39 минут
А как теперь можно подвинуть все нижние комбобоксы к тому, который идет выше списком?
Т.е. если удалили комбобокс3, как подвинуть комбобокс4, ... 5, ....6 к комбобоксу2?
C#
1
2
3
4
5
int lastcombo =  lst.IndexOf((s as ComboBox));
            for (int i = lastcombo; i < lst.Count; i--)
            {
                (s as ComboBox).Height = (s as ComboBox).Height - 30;
            }
1
609 / 533 / 114
Регистрация: 24.03.2011
Сообщений: 576
12.07.2011, 07:36 12
Цитата Сообщение от skilllab Посмотреть сообщение
А как теперь можно подвинуть все нижние комбобоксы к тому, который идет выше списком?
Добавьте на форму элемент управления FlowLayoutPanel, установите свойство FlowDirection = FlowDirection.TopDown, и на него добавляйте ComboBox:
C#
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
        private void button1_Click(object sender, EventArgs e)
        {
            ComboBox combo = new ComboBox();
            combo.Enter += new System.EventHandler(this.combo_Enter);
            combo.Items.Add("Это чекбокс " + lst.Count.ToString());
            combo.SelectedIndex = 0;
 
            flowLayoutPanel1.Controls.Add(combo);
            lst.Add(combo);
        }
 
        private void button2_Click(object sender, EventArgs e)
        {
            lst.Remove((c as ComboBox));
            flowLayoutPanel1.Controls.Remove((c as ComboBox));
        }
 
        private void combo_Enter(object sender, EventArgs e)
        {
            c = sender;
        }
ComboBox автоматически будут сдвигаться вверх.
1
290 / 231 / 57
Регистрация: 03.02.2011
Сообщений: 1,954
Записей в блоге: 1
12.07.2011, 20:19  [ТС] 13
Итого, чтобы решить поставленную задачу, нужен такой код:
C#
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
List<ComboBox> lst = new List<ComboBox>();
        object s;
 
public Form1()
        {
            InitializeComponent();
            flowLayoutPanel1.AutoSize = true;
        }
 
private void button5_Click(object sender, EventArgs e)
        {
            ComboBox combo = new ComboBox();
            combo.Enter += new System.EventHandler(this.combo_Enter);
            combo.Items.Add("Это чекбокс " + lst.Count.ToString());
            combo.SelectedIndex = 0;
 
            flowLayoutPanel1.Controls.Add(combo);
            lst.Add(combo);
            combo.Focus();
        }
 
        private void button6_Click(object sender, EventArgs e)
        {
            lst.Remove((s as ComboBox));
            flowLayoutPanel1.Controls.Remove((s as ComboBox));
            int old = lst.Count - 1;
            if (old != -1)
            {
                lst.ElementAt(old).Select();
            }
            else
            {
 
                comboBox1.Focus();
 
            }
        }
        private void combo_Enter(object sender, EventArgs e)
        {
            s = sender;
        }
Добавлено через 1 минуту
Именно это и нужно было получить.
Всем спасибо.

Добавлено через 11 часов 14 минут
Или ещё не всё))))
Как добавить новый комбобокс не в конец списка, а ниже предыдущего?

Добавлено через 26 минут
Т.е. если удалили 2-ой из 5-ти. Поставили фокус на 1-ом, жмакнули батон и вставился комбобокс ниже первого.
0
609 / 533 / 114
Регистрация: 24.03.2011
Сообщений: 576
14.07.2011, 14:31 14
Цитата Сообщение от skilllab Посмотреть сообщение
Как добавить новый комбобокс не в конец списка, а ниже предыдущего?
C#
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
        private void button5_Click(object sender, EventArgs e)
        {
            ComboBox combo = new ComboBox();
            combo.Enter += new System.EventHandler(this.combo_Enter);
            combo.Items.Add("Это чекбокс " + lst.Count.ToString());
            combo.SelectedIndex = 0;
 
            int n = flowLayoutPanel1.Controls.IndexOf((s as ComboBox)) + 1;
            Control[] c = new Control[flowLayoutPanel1.Controls.Count - n];
 
            for (int i = c.Length - 1; i >= 0; i--)
            {
                c[i] = flowLayoutPanel1.Controls[i + n];
                flowLayoutPanel1.Controls.RemoveAt(i + n);
            }
            
            flowLayoutPanel1.Controls.Add(combo);
            flowLayoutPanel1.Controls.AddRange(c);
            lst.Add(combo);
            combo.Focus(); 
        }
1
395 / 362 / 54
Регистрация: 23.05.2010
Сообщений: 716
14.07.2011, 14:58 15
Цитата Сообщение от skilllab Посмотреть сообщение
Не могли бы вы ещё раз объяснить про sender?
sender - это объект типа Object, который указывает на объект, породивший событие. Если у тебя есть две кнопки с текстом "Вася" и "Федя". И кнопки подписаны на события клика. И при клике на кнопку Вася sender будет указывать именно на кнопку Вася. А при клике на кнопку Федя - на кнопку Федя.
Вот пример и предыдущего поста, который как раз демонстрирует это:
C#
1
2
3
4
        private void combo_Enter(object sender, EventArgs e)
        {
            s = sender;//Тут мы записали объект sender в переменную. А что такое sender? Это тот КомбоБокс, в котором сработало событие. Следовательно мы в переменную s записали КомбоБокс.
        }
0
290 / 231 / 57
Регистрация: 03.02.2011
Сообщений: 1,954
Записей в блоге: 1
19.07.2011, 20:17  [ТС] 16
Нашёл ещё себе код Drag and Drop, чтоб можно было таскать строки. Это вместо кнопок (как показал ранее на гифе)
C#
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
private void button5_Click(object sender, EventArgs e)
        {
......
combo.MouseDown += new System.Windows.Forms.MouseEventHandler(this.combo_MouseDownHandler);
            combo.DragOver += new DragEventHandler(combo_DragOver);
            combo.AllowDrop = true;
.....
}
 
 
private void combo_MouseDownHandler(object sender, MouseEventArgs e)
        {
            if (e.Button == MouseButtons.Right)
            {
                base.OnMouseDoubleClick(e);
                DoDragDrop(sender, DragDropEffects.All);
            }
        }
 
        void combo_DragOver(object sender, DragEventArgs e)
        {
            base.OnDragOver(e);
            if (e.Data.GetData(typeof(ComboBox)) != null)
            {
                FlowLayoutPanel p = (FlowLayoutPanel)(sender as ComboBox).Parent;           
                int myIndex = p.Controls.GetChildIndex((sender as ComboBox));
                ComboBox q = (ComboBox)e.Data.GetData(typeof(ComboBox));
                p.Controls.SetChildIndex(q, myIndex);
            }
        }
Остался вопрос со вспомогательными комбобоксами, те, в которых номера строк + чекбокс.
Там логика такая, если чекбокс с галкой - то цифра в последующем комбобоке меняется на i +1, а сам комбобокс-перечислитель принимает индекс item-а "->".

Вообще, в конце выполнения программы должно получиться так: она вставляет в документ (отдельный обработчик) Номер строки, если стоит "->" в комбобоксе-перечислителе, то пропуск номера строки; непосредственно сами строки (которые грузятся в эти динамически создаваемые комбобоксы отдельно)

Вот код формирования этих строк на бейсике:
PureBasic
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
TTNote = ""
For i = 1 To RowQuantity
    NName = "N" & LTrim(Str(i))
    TTName = "TT" & LTrim(Str(i))
    AnalyserString = CboTT(i - 1).Text
    Analyser2
    TempString = AnalyserString
    If ChkList.Value = 1 Then ' Список включен
'        ok = ModelDoc2.AddCustomInfo2(NName, 30, "")
'        ModelDoc2.CustomInfo2("", NName) = ""
        If ChkN(i - 1).Value = 1 Then
            If i - 1 <> 0 Then
                If ChkN(i - 2).Value <> 1 Then
                    TempStringNew = "<PARA  indent=7 findent=-7 number=on ntype=1 nformat=$$.>" & TempString
                Else
                    TempStringNew = TempString
                End If
            Else
                TempStringNew = "<PARA  indent=7 findent=-7 number=on ntype=1 nformat=$$.>" & TempString
            End If
        Else
            If i - 1 <> 0 Then
                If ChkN(i - 2).Value <> 0 Then
                    TempStringNew = "<PARA  indent=7 findent=0 number=off>" & TempString
                Else
                    TempStringNew = TempString
                End If
            Else
                    TempStringNew = "<PARA  indent=7 findent=0 number=off>" & TempString
            End If
        End If
'        ok = ModelDoc2.AddCustomInfo2(TTName, 30, TempStringNew)
'        ModelDoc2.CustomInfo2("", TTName) = TempStringNew
        TTNote = TTNote & TempStringNew
    Else ' Список выключен
        TempStringNew = CboN(i - 1).Text
        If TempStringNew = "->" Then
           TempStringNew = "   "
        End If
'        ok = ModelDoc2.AddCustomInfo2(NName, 30, TempStringNew)
'        ModelDoc2.CustomInfo2("", NName) = TempStringNew
'        ok = ModelDoc2.AddCustomInfo2(TTName, 30, TempString)
'        ModelDoc2.CustomInfo2("", TTName) = TempString
        TTNote = TTNote & TempStringNew & TempString
    End If
    If RowQuantity - i <> 0 Then
            TTNote = TTNote & Chr(10)
    End If
Next i
Как такое реализовать с уже существующим кодом? Или тут вообще надо создавать отдельный компонент с чекбоксом и 2-мя комбобоксами?
0
19.07.2011, 20:17
IT_Exp
Эксперт
87844 / 49110 / 22898
Регистрация: 17.06.2006
Сообщений: 92,604
19.07.2011, 20:17

Динамическое создание компонентов при включении RadioButton
Вопрос такой. У меня есть RadioButtons Пусть зовутся RadioButton1, RadioButton2, .... ...

Динамическое создание и обращение к массиву разнотипных компонентов
C# Создаю массив разных контролов (Чекбоксы, Комбобоксы, Поля с датой). public List&lt;Control&gt;...

Динамическое создание и удаление элементов управления
В конструкторе есть комбобокс, нужно отображать n-ое кол-во textbox и label, в зависимости от...

Динамическое создание и удаление кнопок текстбоксов и прочего
Собственно есть код, добавляет нормально, удаляет тоже но только если удалять с последней строки и...


Искать еще темы с ответами

Или воспользуйтесь поиском по форуму:
16
Ответ Создать тему
Опции темы

КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2022, CyberForum.ru