Рекомендация: обрабатывать передачу команд от дочернего объекта к родительскому объекту, объекту дедушки и т. Д. И т. Д. c. VBNET - PullRequest
0 голосов
/ 11 марта 2020

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

У дочернего элемента управления есть кнопка для удаления самой себя. Но метод фактического удаления, удаления из GUI, et c., Все обрабатывается верхним родителем по необходимости.

Вот два способа, которыми я способствовал, оба из которых работают:

  1. Когда родитель создает экземпляр дочернего объекта, он передает ссылку на самого себя этому дочернему элементу. Это позволяет ребенку теперь вызывать publi c членов родителя. В коде это будет выглядеть примерно так:
'*~*~*~*~*~*~*~*~*~*~
'in the parent object
Dim child as new ChildObject
child.setParent(me)
'*~*~*~*~*~*~*~*~*~*~

'in the child object
public sub setParent(byref p as parentObject)
        myParent = p
end sub

'now the child can interact with the parent
'for example:
myParent.deleteMe()

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

myParent.myParent.myParent.deleteMe()

Не круто.

Другой способ, которым я способствовал, это переменная publi c, которая отслеживается высокоскоростным таймером в верхнем родительском элементе. Если дочернему элементу требуется запуск какого-либо родительского метода, он устанавливает флаг bool в значение TRUE, которое отслеживает таймер, а затем вызывает соответствующий метод. Но это влечет за собой переменную publi c, которую я бы предпочел избегать. Этот метод также использует непрерывный таймер, который потребляет ресурсы.

Вопрос:

Являются ли эти приемлемые способы достижения цели sh? Есть ли способ лучше? Или тот факт, что мне даже нужно сделать это, указывает на общий недостаток дизайна?

Ответы [ 2 ]

1 голос
/ 12 марта 2020

Когда вы связываете дочерний элемент управления с родительским элементом, как вы показали child.setParent(Me), вы можете иметь другое свойство и ссылку на элемент управления TopParent от текущего родительского элемента (называйте его как хотите). например. me.TopControl = p.TopControl Очевидно, что вам нужно определить / установить TopControl перед добавлением всех дочерних элементов.

Затем вы можете вызывать его в любом месте, например, me.TopControl.deleteMe()

1 голос
/ 11 марта 2020

Я мало работаю с WPF, но я полагаю, что вы можете использовать VisualTreeHelper.GetParent метод до пройти по визуальному дереву, чтобы найти родителя указанного c type.

Public Shared Function FindProgenitor(Of T As DependencyObject)(child As DependencyObject) As T
  Dim parent As DependencyObject = VisualTreeHelper.GetParent(child)
  Do Until parent Is Nothing OrElse TypeOf parent Is T
    parent = VisualTreeHelper.GetParent(parent)
  Loop
  Return DirectCast(parent, T)
End Function

Если исходный элемент управления имеет тип RootControl, тогда сценарий использования в дочернем элементе управления будет выглядеть примерно так:

Dim myParent As RootControl = FindProgenitor(Of RootControl)(Me)
If myParent IsNot Nothing Then
   ' call method on RootControl instance myParent
End If
...