С Новым годом! Форум программистов, компьютерный форум, киберфорум
Visual Basic .NET
Войти
Регистрация
Восстановить пароль
Блоги Сообщество Поиск Заказать работу  
 
Рейтинг 4.62/21: Рейтинг темы: голосов - 21, средняя оценка - 4.62
 Аватар для 6cnitymi
82 / 50 / 14
Регистрация: 28.10.2013
Сообщений: 200

Клонирование элементов управления

30.03.2015, 23:37. Показов 4000. Ответов 10
Метки нет (Все метки)

Студворк — интернет-сервис помощи студентам
Впервые столкнулся с подобной проблемой...
Требуется создать на форме панель, равную(по содержанию и всей начинке) панели с другой формы...
VB.NET
1
2
3
        Dim a As New Panel
         a = Form2.Panel1
        Me.Controls.Add(a)
панель вызывается, и появляется, но повторно вызвать вторую такую же панель, не удаётся...
то бишь, сколько раз не обращайся к этому коду, появляется только она копия...
Как исправить код, что бы появлялось копий больше одной?
0
Programming
Эксперт
39485 / 9562 / 3019
Регистрация: 12.04.2006
Сообщений: 41,671
Блог
30.03.2015, 23:37
Ответы с готовыми решениями:

Клонирование элементов управления с сохранением всех свойств
Успешно клонировал строки, массивы, холсты (*.bmp). Но возникла необходимость клонировать Label и ...тупик. Читал, искал, гуглил - не...

Клонирование динамических элементов
Привет. У меня есть вкладка, на вкладке кнопки текстбокс и ТД. Как сделать, чтобы при создании новой вкладки все элементы создались как...

Клонирование элементов
Подскажите, пожалуйста, что не так, по нажатию на кнопку "Новый пункт" должно под текстовым полем добавлять текстовое поле и кнопку...

10
COM‐пропагандист
 Аватар для Замабувараев
936 / 785 / 149
Регистрация: 18.12.2014
Сообщений: 2,256
Записей в блоге: 4
31.03.2015, 01:49
Вот функция для клонирования элемента управления
VB.NET
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
' Ctrl — элемент управления для клонирования
' Parent — родительский элемент
Private Function CloneControl(ByVal Ctrl As Control, ByVal Parent As Control) As Control
    Try
        Dim CtrlObject As Object = Activator.CreateInstance(Ctrl.GetType())
        Dim CtrlNew As Control = CType(CtrlObject, Control)
        Dim pdcCtrl As System.ComponentModel.PropertyDescriptorCollection = System.ComponentModel.TypeDescriptor.GetProperties(Ctrl)
        Dim pdcCtrlNew As System.ComponentModel.PropertyDescriptorCollection = System.ComponentModel.TypeDescriptor.GetProperties(CtrlNew)
        For i As Integer = 0 To pdcCtrl.Count - 1
            If pdcCtrl(i).Name = "Parent" Then
                CtrlNew.Parent = Parent
            Else
                If pdcCtrl(i).Name = "Controls" Then
                    If Not Ctrl.Controls Is Nothing Then
                        For Each CtrlChild As Control In Ctrl.Controls
                            CtrlNew.Controls.Add(CloneControl(CtrlChild, CtrlNew))
                        Next
                    End If
                End If
            End If
            pdcCtrlNew(i).SetValue(CtrlNew, pdcCtrl(i).GetValue(Ctrl))
        Next
        Return CtrlNew
    Catch ex As Exception
        Return Nothing
    End Try
End Function
Использование:
VB.NET
1
2
3
Dim tb As New TextBox
tb.Text = "Привет, мир!"
Dim tb1 As Control = CloneControl(tb, Nothing)
0
 Аватар для 6cnitymi
82 / 50 / 14
Регистрация: 28.10.2013
Сообщений: 200
31.03.2015, 12:07  [ТС]
Замабувараев, данное решение не работает, хотя по идеи, я всё верно делаю...
на второй форме есть панель, на которой расположены некоторые контролы - текстовые поля, лэйблы, кнопки и тд..
при использовании данного метода, панель появляется, но вместо всех этих контролов отображается пустой просвет, через который виднеется фон формы...
пробовал разные варианты, пробовал менять и переписывать данный код, но либо происходит так, либо панель вообще не появляется...
Хотел бы описать проблему более конкретно, но никаких ошибок студия не выдаёт...
0
4708 / 3661 / 857
Регистрация: 02.02.2013
Сообщений: 3,518
Записей в блоге: 2
31.03.2015, 14:44
Лучший ответ Сообщение было отмечено Памирыч как решение

Решение

Функция Clone (источник не помню)
VB.NET
1
2
3
4
5
6
7
8
9
10
11
12
Public Shared Function Clone(Of T As Control)(controlToClone As T) As T
    Dim instance As T = Activator.CreateInstance(Of T)()
    Dim control As Type = controlToClone.GetType()
    Dim info As PropertyInfo() = control.GetProperties()
    Dim p As Object = control.InvokeMember("", System.Reflection.BindingFlags.CreateInstance, Nothing, controlToClone, Nothing)
    For Each pi As PropertyInfo In info
        If (pi.CanWrite) AndAlso Not (pi.Name = "WindowTarget") AndAlso Not (pi.Name = "Capture") Then
            pi.SetValue(instance, pi.GetValue(controlToClone, Nothing), Nothing)
        End If
    Next
    Return instance
End Function
(+ добавить Imports System.Reflection)
Использование, предполагается, что на панели Form4.Panel1 только Button и Label. (Полагаю, что все это можно оптимизировать; избавится от прямого указания типа объекта не смог)
VB.NET
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
Dim ii As Integer
Private Sub Button1_Click(sender As System.Object, e As System.EventArgs) Handles Button1.Click
    Dim a As New Panel
    Dim jj As Integer
    a = Clone(Form4.Panel1)
    ii += 1
    a.Name = "copy" & ii.ToString
    For Each cc As Control In Form4.Panel1.Controls
        If cc.GetType.Name = "Button" Then
            Dim bb As Button = cc
            a.Controls.Add(Clone(bb))
        End If
        If cc.GetType.Name = "Label" Then
            Dim bb As Label = cc
            a.Controls.Add(Clone(bb))
        End If
    Next
    Me.Controls.Add(a)
    jj = Me.Controls.IndexOf(a)
    With Me.Controls.Item(jj)
        .Location = New Point(10 * ii, 10 * ii)
        .Visible = True
        For Each c As Control In .Controls
            c.Visible = True
        Next
    End With
End Sub
Добавлено через 1 час 6 минут
Можно перевести функцию Clone в расширение Control
VB.NET
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
Imports System.Reflection
Imports System.Runtime.CompilerServices
Module Module2
    <Extension()> _
    Public Function Clone(Of T As Control)(ByVal controlToClone As Control) As T
        Dim instance As T = Activator.CreateInstance(Of T)()
        Dim control As Type = controlToClone.GetType()
        Dim info As PropertyInfo() = control.GetProperties()
        Dim p As Object = control.InvokeMember("", System.Reflection.BindingFlags.CreateInstance, Nothing, controlToClone, Nothing)
        For Each pi As PropertyInfo In info
            If (pi.CanWrite) AndAlso Not (pi.Name = "WindowTarget") AndAlso Not (pi.Name = "Capture") Then
                pi.SetValue(instance, pi.GetValue(controlToClone, Nothing), Nothing)
            End If
        Next
        Return instance
    End Function
End Module
Тогда Button1_Click примет следующий вид
VB.NET
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
Dim a As New Panel
Dim jj As Integer
a = Form4.Panel1.Clone(Of Panel)()
ii += 1
a.Name = "copy" & ii.ToString
For Each cc As Control In Form4.Panel1.Controls
    If cc.GetType.Name = "Button" Then a.Controls.Add(cc.Clone(Of Button))
    If cc.GetType.Name = "Label" Then a.Controls.Add(cc.Clone(Of Label))
Next
Me.Controls.Add(a)
jj = Me.Controls.IndexOf(a)
With Me.Controls.Item(jj)
    .Location = New Point(10 * ii, 10 * ii)
    .Visible = True
    For Each c As Control In .Controls
        c.Visible = True
    Next
End With
2
 Аватар для 6cnitymi
82 / 50 / 14
Регистрация: 28.10.2013
Сообщений: 200
31.03.2015, 15:05  [ТС]
ovva, код действительно рабочий, прописать каждый тип объекта труда не составит, но вот с панелью проблемно...
если переписывать код под панели, то почему-то контролы на панели не отображаются, и панель видится пустой...
главная проблема же в том, что копируются лишь контролы, без прописанных на них событий...
пробовал прикрутить события - не удалось...

простейший код
VB.NET
1
2
3
  Dim a As New Panel
         a = Form2.Panel1
        Me.Controls.Add(a)
создаёт панель, со всеми контролами и их событиями...
не уж то не существует простого способа реализовать копирование?
0
4708 / 3661 / 857
Регистрация: 02.02.2013
Сообщений: 3,518
Записей в блоге: 2
31.03.2015, 15:42
Цитата Сообщение от 6cnitymi Посмотреть сообщение
создаёт панель
Это лишь ссылка на существующий объект.
Самый оптимальный вариант, на мой взгляд, оформлять такую панель в виде пользовательского элемента управления.
0
 Аватар для 6cnitymi
82 / 50 / 14
Регистрация: 28.10.2013
Сообщений: 200
31.03.2015, 16:20  [ТС]
ovva,
Цитата Сообщение от ovva Посмотреть сообщение
оформлять такую панель в виде пользовательского элемента управления
а динамически такое возможно, или только в проекте создавать как собственный контрол?
0
2282 / 1598 / 400
Регистрация: 26.06.2017
Сообщений: 4,726
Записей в блоге: 1
03.04.2019, 21:21
А кто знает как можно клонировать контролы используя интерфейс ICloneable?
В частности объекты Panel со всеми внутренними объектами. Мне нужно сделать глубокое копирование.

Добавлено через 47 минут
Или это возможно только переопределив метод Clone() своей реализацией?
0
4708 / 3661 / 857
Регистрация: 02.02.2013
Сообщений: 3,518
Записей в блоге: 2
04.04.2019, 11:10
Интерфейс лишь устанавливает, какие процедуры должны присутствовать в классе, поддерживающем этот интерфейс. Класс, реализующий интерфейс, обязан реализовать все его свойства, методы и события. Конкретная реализация процедур лежит на разработчике.
0
4708 / 3661 / 857
Регистрация: 02.02.2013
Сообщений: 3,518
Записей в блоге: 2
04.04.2019, 16:07
Лучший ответ Сообщение было отмечено 6cnitymi как решение

Решение

Пример клонирования
Кликните здесь для просмотра всего текста
VB.NET
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
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
Public Class Form2
    Private Sub Button1_Click(sender As System.Object, e As System.EventArgs) Handles Button1.Click
        Dim p1 As Panel = Me.Panel1.Clone(Of Panel)()
        p1.Name &= "Copy"
        addControls(p1)
        p1.Location = New Point(12, 130)
        Me.Controls.Add(p1)
        p1.BringToFront()
        'список Controls новой панели
        Dim s As String = p1.Name & vbCrLf
        For Each cc As Control In p1.Controls
            s &= cc.Name & vbCrLf
        Next
        MsgBox(s)
    End Sub
    Private Sub Button2_Click(sender As System.Object, e As System.EventArgs) Handles Button2.Click
        Dim p1 As Panel = Me.Panel1.Clone(Of Panel)()
        p1.Name &= "Copy"
        addControls(p1)
        p1.Location = New Point(230, 130)
        Me.Controls.Add(p1)
        p1.BringToFront()
        'список Controls новой панели
        Dim s As String = p1.Name & vbCrLf
        For Each cc As Control In p1.Controls
            s &= cc.Name & vbCrLf
        Next
        MsgBox(s)
    End Sub
    Private Sub addControls(ByVal pp As Panel)
        For Each contr As Control In Me.Panel1.Controls
            Select Case contr.GetType.Name
                Case "Button"
                    pp.Controls.Add(contr.Clone(Of Button))
                    AddHandler pp.Controls(pp.Controls.Count - 1).Click, AddressOf btn_Click
                Case "RadioButton"
                    pp.Controls.Add(contr.Clone(Of RadioButton))
                    AddHandler pp.Controls(pp.Controls.Count - 1).Click, AddressOf rb_CheckedChanged
                Case "CheckBox"
                    pp.Controls.Add(contr.Clone(Of CheckBox))
                    AddHandler pp.Controls(pp.Controls.Count - 1).Click, AddressOf cb_CheckedChanged
                Case Else
            End Select
        Next
    End Sub
    'события новых панелей
    Private Sub btn_Click(ByVal sender As Object, ByVal e As System.EventArgs)
        MsgBox("Событие нажатия кнопки " & sender.name)
    End Sub
    Private Sub rb_CheckedChanged(ByVal sender As Object, ByVal e As System.EventArgs)
        Dim rb As RadioButton = CType(sender, RadioButton)
        Select Case rb.Name
            Case "RadioButton1"
                Me.BackColor = Color.Aqua
            Case "RadioButton2"
                Me.BackColor = Color.LawnGreen
            Case "RadioButton3"
                Me.BackColor = SystemColors.Control
        End Select
    End Sub
    Private Sub cb_CheckedChanged(sender As System.Object, e As System.EventArgs)
        Dim cb As CheckBox = CType(sender, CheckBox)
        If cb.Checked Then
            cb.BackColor = Color.YellowGreen
        Else
            cb.BackColor = Panel1.BackColor
        End If
    End Sub
    'события базовой панели
    Private Sub CheckBox1_CheckedChanged(sender As System.Object, e As System.EventArgs) Handles CheckBox1.CheckedChanged
        If CheckBox1.Checked Then
            CheckBox1.BackColor = Color.Red
        Else
            CheckBox1.BackColor = Panel1.BackColor
        End If
    End Sub
    Private Sub Button3_Click(sender As System.Object, e As System.EventArgs) Handles Button3.Click
        MsgBox("vbOK!")
    End Sub
    Private Sub RadioButton1_CheckedChanged(sender As System.Object, e As System.EventArgs) Handles RadioButton3.CheckedChanged, RadioButton2.CheckedChanged, RadioButton1.CheckedChanged
        Dim rb As RadioButton = CType(sender, RadioButton)
        Select Case rb.Name
            Case "RadioButton1"
                Panel1.BackColor = Color.Aqua
            Case "RadioButton2"
                Panel1.BackColor = Color.LawnGreen
            Case "RadioButton3"
                Panel1.BackColor = SystemColors.Control
        End Select
    End Sub
End Class
'…
Imports System.Runtime.CompilerServices
Imports System.Reflection
Module Module1
    <Extension()> _
    Public Function Clone(Of T As Control)(ByVal controlToClone As Control) As T
        Dim instance As T = Activator.CreateInstance(Of T)()
        Dim control As Type = controlToClone.GetType()
        Dim info As PropertyInfo() = control.GetProperties()
        Dim p As Object = control.InvokeMember("", System.Reflection.BindingFlags.CreateInstance, Nothing, controlToClone, Nothing)
        For Each pi As PropertyInfo In info
            If (pi.CanWrite) AndAlso Not (pi.Name = "WindowTarget") AndAlso Not (pi.Name = "Capture") Then
                pi.SetValue(instance, pi.GetValue(controlToClone, Nothing), Nothing)
            End If
        Next
        Return instance
    End Function
End Module
Миниатюры
Клонирование элементов управления  
2
2282 / 1598 / 400
Регистрация: 26.06.2017
Сообщений: 4,726
Записей в блоге: 1
16.04.2019, 12:54
Решил обновить тему, мало ли кому пригодится.
Для клонирования контролов применил код от ovva:
VB.NET
1
2
3
4
5
6
7
8
9
10
11
12
Public Shared Function Clone(Of T As Control)(byval controlToClone As T) As T
    Dim instance As T = Activator.CreateInstance(Of T)()
    Dim control As Type = controlToClone.GetType()
    Dim info As PropertyInfo() = control.GetProperties()
    Dim p As Object = control.InvokeMember("", System.Reflection.BindingFlags.CreateInstance, Nothing, controlToClone, Nothing)
    For Each pi As PropertyInfo In info
        If (pi.CanWrite) AndAlso Not (pi.Name = "WindowTarget") AndAlso Not (pi.Name = "Capture") Then
            pi.SetValue(instance, pi.GetValue(controlToClone, Nothing), Nothing)
        End If
    Next
    Return instance
End Function
Однако функция клонирования требует явно указать тип объекта клонирования, о чём также писал ovva. Данный нюанс удалось обойти изменив строку 2 таким образом:
VB.NET
1
Dim instance As T = Activator.CreateInstance(controlToClone.GetType())
2
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
inter-admin
Эксперт
29715 / 6470 / 2152
Регистрация: 06.03.2009
Сообщений: 28,500
Блог
16.04.2019, 12:54
Помогаю со студенческими работами здесь

Нужен элемент управления со сворачиваемым списком, похожий на панель элементов управления в VS
Нужен элемент управления со сворачиваемым списком, как панель элементов в VS, желательно с возможностью установки чекбокса есть набор...

Как сделать чтобы панели элементов управления находились "элементы управления" нужного формата?
По умолчанию формат &quot;элемента управления&quot; &quot;Поле&quot;: высота - 0,556 см; ширина - 3,0 см; шрифт - 11. Как сделать чтобы по...

Массивы элементов. Найти количество элементов управления во frame
Добрый вечер. Подскажите пожалуйста как перебрать элементы управления в определённом фрейме или просто найти кол-во например текстовых...

Создать на форме кнопку очистки элементов управления Label от старых данных и кнопку заполнения этих элементов с
Создать на форме кнопку очистки элементов управления Label от старых данных и кнопку заполнения этих элементов с испол-ием функции InputBox

Массив элементов управления
Уважаемые специалисты, помогите, пожалуйста, новичку в VB 2008! На Form есть 30 PictureBox1, ..., PictureBox30, загоняем их в массив...


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

Или воспользуйтесь поиском по форуму:
11
Ответ Создать тему
Новые блоги и статьи
Модель микоризы: классовый агентный подход 3
anaschu 06.01.2026
aa0a7f55b50dd51c5ec569d2d10c54f6/ O1rJuneU_ls https:/ / vkvideo. ru/ video-115721503_456239114
Owen Logic: О недопустимости использования связки «аналоговый ПИД» + RegKZR
ФедосеевПавел 06.01.2026
Owen Logic: О недопустимости использования связки «аналоговый ПИД» + RegKZR ВВЕДЕНИЕ Введу сокращения: аналоговый ПИД — ПИД регулятор с управляющим выходом в виде числа в диапазоне от 0% до. . .
Модель микоризы: классовый агентный подход 2
anaschu 06.01.2026
репозиторий https:/ / github. com/ shumilovas/ fungi ветка по-частям. коммит Create переделка под биомассу. txt вход sc, но sm считается внутри мицелия. кстати, обьем тоже должен там считаться. . . .
Расчёт токов в цепи постоянного тока
igorrr37 05.01.2026
/ * Дана цепь постоянного тока с сопротивлениями и напряжениями. Надо найти токи в ветвях. Программа составляет систему уравнений по 1 и 2 законам Кирхгофа и решает её. Последовательность действий:. . .
Новый CodeBlocs. Версия 25.03
palva 04.01.2026
Оказывается, недавно вышла новая версия CodeBlocks за номером 25. 03. Когда-то давно я возился с только что вышедшей тогда версией 20. 03. С тех пор я давно снёс всё с компьютера и забыл. Теперь. . .
Модель микоризы: классовый агентный подход
anaschu 02.01.2026
Раньше это было два гриба и бактерия. Теперь три гриба, растение. И на уровне агентов добавится между грибами или бактериями взаимодействий. До того я пробовал подход через многомерные массивы,. . .
Советы по крайней бережливости. Внимание, это ОЧЕНЬ длинный пост.
Programma_Boinc 28.12.2025
Советы по крайней бережливости. Внимание, это ОЧЕНЬ длинный пост. Налог на собак: https:/ / **********/ gallery/ V06K53e Финансовый отчет в Excel: https:/ / **********/ gallery/ bKBkQFf Пост отсюда. . .
Кто-нибудь знает, где можно бесплатно получить настольный компьютер или ноутбук? США.
Programma_Boinc 26.12.2025
Нашел на реддите интересную статью под названием Anyone know where to get a free Desktop or Laptop? Ниже её машинный перевод. После долгих разбирательств я наконец-то вернула себе. . .
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2026, CyberForum.ru