mooman_fl Posted March 23, 2004 Posted March 23, 2004 (edited) Ok... abandoned my ealier post on collections as properties. I figured out what I needed there and started making a test application to get it all sorted the way I want it. I have a new problem now though... Here is the code for the collection... this goes in a component (not a usercontrol since there is no visible elements): In the declarations section: Private _Widget As WidgetCollection In the code section of the components class: <DesignerSerializationVisibility(DesignerSerializationVisibility.Content)> _ Public Property Widget() As WidgetCollection Get Return _Widget End Get Set(ByVal Value As WidgetCollection) _Widget = Value End Set End Property As a separate set of classes: 'This is the class that will be added to the collection. Public Class Widget Private _Name As String Private _TestNumber As Integer 'puts parentheses around the 'Name' property <ParenthesizePropertyNameAttribute(True)> _ Public Property Name() As String Get Return _Name End Get Set(ByVal Value As String) _Name = Value End Set End Property 'just for a test Public Property TestNumber() As Integer Get Return _TestNumber End Get Set(ByVal Value As Integer) _TestNumber = Value End Set End Property End Class Public Class WidgetCollection Inherits CollectionBase Public Sub Add(ByVal awidget As Widget) ' Invokes Add method of the List object to add a widget. List.Add(awidget) End Sub Public Sub Remove(ByVal index As Integer) ' Check to see if there is a widget at the supplied index. If index > Count - 1 Or index < 0 Then ' If no widget exists, a messagebox is shown and the operation is ' cancelled. System.Windows.Forms.MessageBox.Show("Index not valid!") Else ' Invokes the RemoveAt method of the List object. List.RemoveAt(index) End If End Sub ' This line declares the Item property as ReadOnly, and ' declares that it will return a Widget object. Public ReadOnly Property Item(ByVal index As Integer) As Widget Get ' The appropriate item is retrieved from the List object and ' explicitly cast to the Widget type, then returned to the ' caller. Return CType(List.Item(index), Widget) End Get End Property Build, start a Test application, add to the toolbox, and drop onto the form in the form designer. As you will see it adds the "Widget" property and it calles up the collection editor with the (Name) and TestNumber properties when a Widget is added.... The problems are this: ....1. In the property panel next to the Widget property there is no "(Collection)" listed. I have noticed that all the standard controls and components have this shown for collection properties. How is this done? ....2. When Widget items are added in the collection editor I want them added as "Widget1", "Widget2", etc. If the Widget class inherits from "System.ComponentModel.Components" this is done automatically but that method isn't desirable since it then adds a new component to the tray for each item added. Is there a way to do this automatically or will I have to code it manually? ....3. If Widget items are added in the collection editor then the editor is closed down and reopened the previous items are gone. Is there something in my code that is missing or am I doing something wrong? ....4. This may be tied to #3... but I would like the items accessable programmatically as such: Component1.Widget.Item(0).TestNumber Currently this doesn't seem to be possible with the code I have. I get an error telling me the Widget class is not instanced. Again a pointer as to what I am doing wrong would be appreciated. Any help would be appreciated. Edited March 23, 2004 by mooman_fl Quote "Programmers are tools for converting caffeine into code." Madcow Inventions -- Software for the Sanity Challenged.
Prelsidente Posted March 24, 2004 Posted March 24, 2004 ....1. In the property panel next to the Widget property there is no "(Collection)" listed. I have noticed that all the standard controls and components have this shown for collection properties. How is this done? In the sub new (Constructor) of the Control: _Widget = new WidgetCollection ....2. When Widget items are added in the collection editor I want them added as "Widget1", "Widget2", etc. If the Widget class inherits from "System.ComponentModel.Components" this is done automatically but that method isn't desirable since it then adds a new component to the tray for each item added. Is there a way to do this automatically or will I have to code it manually? Still inherit from component, but add this attribute to the top of the class: <DesignTimeVisible(False)> 'Hides the component from the tray ....3. If Widget items are added in the collection editor then the editor is closed down and reopened the previous items are gone. Is there something in my code that is missing or am I doing something wrong? Solved with question #1 ....4. This may be tied to #3... but I would like the items accessable programmatically as such: Component1.Widget.Item(0).TestNumber Currently this doesn't seem to be possible with the code I have. I get an error telling me the Widget class is not instanced. Again a pointer as to what I am doing wrong would be appreciated. Any help would be appreciated. Add this attribute to the top of the widget Class: <DefaultProperty("Index")> Also make sure you have a "Index" property. I hope this helps. Quote
mooman_fl Posted March 24, 2004 Author Posted March 24, 2004 Thanks!!! I am going to go give this a shot... stay tuned. LOL Quote "Programmers are tools for converting caffeine into code." Madcow Inventions -- Software for the Sanity Challenged.
mooman_fl Posted March 24, 2004 Author Posted March 24, 2004 Ok... did some test on what you said. Excellent advice so far. You have my vote next election. ;-) One hitch... I don't want the Widget items selectable as a normal control... I only want the accessable from within the collection. More akin to the way an imagelist works rather than the way a tabpage works. Added widgets as components (visible in the components list or not) the are still visible and selectable through the collection editor and not through the normal property panel. With this method the appear in the drop-down list of controls to choose from. Any idea how I would maintain this functionality while keeping them limited to the collection only? Quote "Programmers are tools for converting caffeine into code." Madcow Inventions -- Software for the Sanity Challenged.
Prelsidente Posted March 24, 2004 Posted March 24, 2004 well, for what you want to do, just don't inherit Class Widget from component. But, i must warn you, you will no longer have the functionality of code being generated like you wanted (Widget1, Widget2,...), in fact, they will only be persisted to the resources, not being added to code. After that you will only access them through 'Control.Widgets(Index)' at runtime. Quote
mooman_fl Posted March 24, 2004 Author Posted March 24, 2004 As long as I can add them through the IDE and access them programmitcally through the collection that is all I want. For the component that I am making it really won't make much sense to do it any other way. As for the names. I have figured that out. Make a Name property as part of the Widget class... that sets the name that gets displayed in the Collection editor automatically it seems. The names will be mainly for keeping things straight for the user at designtime although you could write code that checks the name property of each element at run-time too. This much I have already tested at it works. I just won't be able to reference them DIRECTLY by name which is ok. Thanks for all the help... I am finally able to move forward with my project. This was holding the whole thing up. :-) Quote "Programmers are tools for converting caffeine into code." Madcow Inventions -- Software for the Sanity Challenged.
Recommended Posts
Join the conversation
You can post now and register later. If you have an account, sign in now to post with your account.