2016-11-11 8 views
1

Я создал UserControl и добавил его в FlowLayoutPanel. UserControl используется, чтобы позволить пользователю вводить в форму материал, стоимость и доставку. Когда пользователь заполнил его, я хочу другой UserControl появляться под ним в FlowLayoutPanelДинамическое добавление пользовательского элемента управления к FlowLayoutPanel

UserControl просто генерирует строку на основе введенного текста в два TextBox управления и состояние двух Checkbox управления. он также имеет свойство, которое указывает, когда пользователь заполнил достаточную информацию. Я хочу использовать это свойство для генерации нового UserControl.

На данный момент у меня есть мой первый UserControl на FlowLayoutPanel, он успешно передает свойство String и CreateNew.

Проблемы я сталкивающиеся являются:

  1. Как следить, чтобы увидеть, если CreateNew изменился Верно?
  2. Как добавить элемент управления в форме и +1 к имени элементов управления для будущего ссылающегося
  3. После того, как новый элемент управления добавляется, мне нужно следить, чтобы увидеть, если новые CreateNew изменения состояния, чтобы повторить цикл

Может ли кто-нибудь указать мне в правильном направлении, здесь есть много информации, но я не могу найти ничего полезного из других проблем/вопросов других.

UPDATE 1

Благодаря пользовательским Zaggler для комментария, я сейчас удалось получить контроль, чтобы создать новый экземпляр себе на FlowLayoutPanel. Но теперь я столкнулся с новой проблемой, связанной с созданием только одного нового пользовательского контроля, а затем он останавливается.

Вот код, я использую:

UserControl Код

Public Class Alv_Product_Order_Control 
    Public OutString As String 
    Public Event CreateNew() 
    Dim CreateNewRaised As Boolean 

    Private Sub OutputString(sender As Object, e As EventArgs) Handles tbMaterial.TextChanged, tbCost.TextChanged, 
     cbDelivered.CheckedChanged, cbOrderPlaced.CheckedChanged 

     OutString = "¦¦" & tbMaterial.Text & "¦" & tbCost.Text & "¦" 

     If cbOrderPlaced.Checked = True Then 
      OutString = OutString & "Yes¦" 
     Else 
      OutString = OutString & "No¦" 
     End If 

     If cbDelivered.Checked = True Then 
      OutString = OutString & "Yes¦" 
     Else 
      OutString = OutString & "No¦" 
     End If 

     If tbCost.Text = "" Or tbMaterial.Text = "" Then 
     Else 
      If CreateNewRaised = False Then 
       RaiseEvent CreateNew() 'Raise the event that's used to signal adding a new control to the layout 
       CreateNewRaised = True 'Create A Latched Boolean that cannot change again in the future 
      End If 
     End If 
    End Sub 

    Public ReadOnly Property Alv_Product_Order_Control As String 
     Get 
      Return OutString 'Pass string back to main form 
     End Get 
    End Property 

Главная форма Код

Private Sub CreateSecondPOC() Handles POC1.CreateNew 
    FlowLayoutPanel1.Controls.Add(New Alveare_VB.Alv_Product_Order_Control) 
End Sub 

Я здесь предполагаю, что проблема заключается в CreateSecondPOC обрабатывает событие только для первого POC1

Как создать новый Alveare_VB.Alv_Product_Order_Control, назовите его как POC2, а также добавьте обработчик для обработки POC2.CreateNew и добавьте еще один элемент управления?

Edit 2

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

Private Sub CreateSecondPOC(ByVal sender As Object, ByVal e As System.EventArgs) Handles POC1.CreateNew 
     Try 
      Dim oldPoc = DirectCast(sender, Alveare_VB.Alv_Product_Order_Control) 
      RemoveHandler oldPoc.CreateNew, AddressOf CreateSecondPOC 
     Catch ex As Exception 
      Debug.Print(ex.Message) 
     End Try 

     Dim newPoc As New Alveare_VB.Alv_Product_Order_Control 
     AddHandler newPoc.CreateNew, AddressOf CreateSecondPOC 
     FlowLayoutPanel1.Controls.Add(newPoc) 
    End Sub 

И я получаю следующее сообщение об ошибке в строке «RemoveHandler»:

Не удалось привести объект типа «System.Windows .Forms.TextBox 'для ввода' Alveare_VB.Alv_Product_Order_Control '.

Событие CreateNew возникает, когда написано текстовое поле, которое передается обратно в качестве отправителя, которого я предполагаю? Не совсем уверен, куда идти с этим сейчас.

Редактировать 3

Ошибка была в моей UserControl, я отправлял неправильный объект назад (в этом случае текстовое поле). Теперь я изменил RaiseEvent, чтобы вернуть UserControl в качестве объекта. Теперь все работает правильно.

+1

Создайте событие и поднимите его, когда вам нужно. Посмотрите на 'withevents' ... – Codexer

+0

@ Zaggler Спасибо за руководство, я сделал некоторый прогресс, см. Обновленный вопрос – SilverShotBee

+0

. Добро пожаловать, пожалуйста, см. Комментарий под Verdolino ответ вы приняли. – Codexer

ответ

1

Вы можете изменить свой обработчик на что-то вроде этого

Private Sub CreateSecondPOC() Handles POC1.CreateNew 
    Dim newPoc As New Alveare_VB.Alv_Product_Order_Control 
    AddHandler newPoc.CreateNew, AddressOf CreateSecondPOC 
    FlowLayoutPanel1.Controls.Add(newPoc) 
End Sub 

Я не уверен, если вы хотите сохранить обработку события, даже после того, как она была заселена один раз, то есть она может быть опустошена, то заселен , затем снова поднять событие? Возможно, вы хотите заблокировать его, когда он заселен, но это не ясно.

Вы также можете сохранить все свои элементы управления в контейнере и создать только новый, когда все они будут заполнены.

Edit:

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

Private Sub CreateSecondPOC(sender As Object) Handles POC1.CreateNew 
    Dim oldPoc = DirectCast(sender, Alveare_VB.Alv_Product_Order_Control) 
    RemoveHandler oldPoc, AddressOf CreateSecondPOC 
    Dim newPoc As New Alveare_VB.Alv_Product_Order_Control 
    AddHandler newPoc.CreateNew, AddressOf CreateSecondPOC 
    FlowLayoutPanel1.Controls.Add(newPoc) 
End Sub 

Но обработчик событий элемента управления последнийPOC никогда бы не отписался. Таким образом, вы также можете сделать что-то подобное при закрытии формы

For Each poc In Me.FlowLayoutPanel1.Controls.OfType(Of Alveare_VB.Alv_Product_Order_Control)() 
    RemoveHandler poc.CreateNew, AddressOf CreateSecondPOC 
Next poc 

я упоминал выше, что Вы также можете сохранить все ваши POC управления в контейнере, который был бы лучший способ следить за элементами управления, вместо использования FlowLayoutPanel в качестве логического контейнера. Просто делайте то, что работает для вас, и подумайте об удалении обработчиков.

+0

Я блокирую событие, «CreateNewRaised» Bool останавливает событие от повторного поднятия, даже если его заселение и повторное заполнение. Я дам это, спасибо – SilverShotBee

+0

На один шаг впереди меня - я должен был внимательно посмотреть на ваш код :) – djv

+0

@ Вердолино нужно помнить, что если добавлять динамиков динамически, вам также нужно их удалить. Последствия могут возникнуть, если нет. Например, если не удалить указатель на объект, плавающий круглый и GC не может его найти, поэтому память не будет выпущена и не вызовет утечки памяти .... С помощью Events обрабатывает это для вас, просто предложение. – Codexer

Смежные вопросы