2013-12-19 3 views
2

Есть ли способ, с помощью которого я могу программно получить доступ к ссылочным элементам управления, указанным в форме (myForm.designer.vb), в этих условиях:Vb.Net Как получить доступ к неизвестным элементам управления, объявленным в форме, но не содержащихся в Form.Controls

А.) название управления не всегда известно, и

Б.) контроль не были добавлены к myForm.Controls сбора?

Для Instance myForm.Designer.vb будет содержать строку

Friend WithEvents [UnknownControlName] As [KnownControlType] 

Но не содержит строку

Me.Controls.Add(Me.[UnknownControlName]) 

В конечном счете, я пытаюсь пройти через все элементы управления в форме (а не только в myForm.Controls), и если контрольный ТИП соответствует тому, что я ищу, он добавляется в коллекцию независимо от имени. Как мне это сделать?

+1

задается вопрос, почему вы управление, объявленные в вашем конструкторе форм, которые не предназначены, чтобы быть частью вашей формы? Очень интересно. –

+0

@TonyHopkinson - Было бы здорово удивиться, и именно поэтому. Я работаю с настраиваемым элементом управления (не сам по себе), который имеет плохую привычку требовать дополнительных компонентов, добавленных во время разработки (которые добавляются в родительскую форму), но не очищает их при удалении из формы. Я пытаюсь исправить эту проблему. Я либо хочу, чтобы эти элементы управления, созданные по времени разработки, были удалены из формы, когда пользовательский элемент управления, или я хотел бы иметь возможность получить к ним доступ позже, чтобы я мог быстро добавить их в новый экземпляр настраиваемого элемента управления , – ProtoNoob

+0

Это вещь дерева? Очень плохо то, что они накапливаются, пока их не будет много. Похоже, что они действительно добавлены в форму (Me.Controls.Add), но объявлены в дизайнере, но не добавлены в коллекцию телевизора. IIRC его UIEditor - это только редактор коллекций, который добавляет элементы управления в базовую коллекцию для нас. Что может случиться, так это то, что они неправильно помечены для сериализации и теряются из коллекции таким образом. Лучший способ удалить их - это исправить основную проблему (я знаю, время волшебной палочки). – Plutonix

ответ

0

Коллекция имущество будет реализовано что-то вроде этого:

' backing field, actual collection 
Private _TargetControls As New Collection(Of Control) 

<EditorAttribute(GetType(DlgFormControlCollectionUIEditor), _ 
    GetType(System.Drawing.Design.UITypeEditor))> _ 
<DesignerSerializationVisibility(DesignerSerializationVisibility.Content)> _ 
Public Property TargetControls() As Collection(Of Control) 
    Get 
     Return _TargetControls 
    End Get 
    Set(ByVal value As Collection(Of Control)) 
     _TargetControls = value 
    End Set 
End Property 

EditorAttribute говорит VS класса, который будет использоваться для редактирования свойства во время разработки. В этом случае это настраиваемый класс редактора с именем DlgFormControlCollectionUIEditor. Для того, чтобы использовать встроенный в .NET Редактор Collection было бы так:

Imports System.ComponentModel.Design 
... 
<Editor(GetType(CollectionEditor), GetType(System.Drawing.Design.UITypeEditor))> 

VS будет использовать базовый редактор, чтобы обеспечить диалог для редактирования открытых свойств (не поля или членов) базового класса. То есть, если свойство является Collection(Of Foo), редактор будет публиковать публичные члены Foo для редактирования пользователем.

Когда вы нажимаете Ok/Done в любом UITypeEditor, VS добавляет Type в проект. Если Foo - объект класса, он добавляется к Collection(Of Foo). Если «Foo» - это компонент или элемент управления, то в конструктор форм добавляются соответствующие операторы Friend Foo1 As Foo....

Атрибут DesignerSerializationVisibility указывает VS, как обрабатывать свойство. Как правило, мы хотим, чтобы VS сохранил всю информацию об элементе управления, например TextBox. В коллекции вместо этого вы хотите сохранить СОДЕРЖАНИЕ коллекции.

Кроме того, вам нужно рассказать VS, как сказать, когда изменилось содержимое коллекции (я не помню, чтобы видеть эту часть, когда я смотрел на этот prj, но это всего лишь несколько недель спустя, я не помню,). Они являются ShouldSerialize функции и Reset метод:

Public Sub ResetTargetControls() 
    _TargetControls = Nothing 
    ' or other logic: like '_TargetControls.Clear' 
End Sub 

Public Function ShouldSerializeTargetControls() As Boolean 
    Return _TargetControls IsNot Nothing 
    ' or 'Return True' since backing field is instanced 
    ' or 'Return _TargetControls.Count > 0' maybe 
End Function 

Я получил ошибку MsgBox сериализации после возвращения из редактора, когда есть что-то не так с этим - VS просто не знает, должен ли он сериализовать данные. Если вы переименовали имена свойств, они могут быть сломаны, так как имя свойства интегрировано в имена процедур (это относится к свойству TargetControls выше). VS использует их, чтобы определить, изменилась ли коллекция (содержимое в этом случае). Если это неудобно, VS может не знать, чтобы удалить детей из коллекции, когда родительский элемент управления удален из формы.

Это должно быть все, что вам нужно сделать, но вы также можете ознакомиться с хорошими рабочими примерами настраиваемых TabControls, чтобы узнать, как они не уходят от сиротов TabPage, объявленных в форме. Существует также вероятность того, что что-то происходит с объектом Column, который требует специальной обработки (или, скорее всего, ошибки) при уничтожении. Этот CP article about Collection Editors хорош, но немного скучен на части «persist», которая является сериализацией.

НТН

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