I have hacked up this gorgeous files system tree view that looks like the windows 7 explorer sidebar. Its starts as one control, and that control lives in another control that makes up an "segment" whom are created and added to a host that handles scrolling ect.

I have the control working fine, assuming I rig up the resize event and directoryChanged event of each "segment" to the one handler method that they need to be attached to in the client code. I would really like this to be handled automatically by the host control.

I though that i could expose a collection of items as a property and when they were added to it I could rig up the events ect. I found that I could to this if I write a Addtoitems method and a removefromitems method. But I was hoping for that listview style items collection.

Just using a property I can't get the information I need from the changes made to the collection.

Any ideas?

Dani AI

Generated

Nice catch, — a custom collection is a solid fix. Two other patterns are worth considering depending on how your segments are used (visual WinForms controls vs. plain model objects) and how much designer support you want.

A simple, robust approach for WinForms controls is to let the host watch its Controls collection. ControlAdded/ControlRemoved fire whenever a child is added/removed — wire handlers there and always unsubscribe on removal to avoid leaks:

// attach in host control constructor
this.ControlAdded += Host_ControlAdded;
this.ControlRemoved += Host_ControlRemoved;

private void Host_ControlAdded(object sender, ControlEventArgs e)
{
    var seg = e.Control as SegmentControl;
    if (seg == null) return;

    // ensure single subscription
    seg.Resize -= Segment_Resize;
    seg.Resize += Segment_Resize;

    seg.DirectoryChanged -= Segment_DirectoryChanged;
    seg.DirectoryChanged += Segment_DirectoryChanged;
}

private void Host_ControlRemoved(object sender, ControlEventArgs e)
{
    var seg = e.Control as SegmentControl;
    if (seg == null) return;

    seg.Resize -= Segment_Resize;
    seg.DirectoryChanged -= Segment_DirectoryChanged;
}

If you prefer a strongly typed Items property (and want designer-friendly serialization), derive from Collection<T> rather than the older CollectionBase, override InsertItem/RemoveItem/SetItem/ClearItems, and attach/detach inside those overrides. Example outline:

public class SegmentCollection : Collection<SegmentControl>
{
    readonly HostControl owner;
    public SegmentCollection(HostControl owner) { this.owner = owner; }

    protected override void InsertItem(int index, SegmentControl item)
    {
        base.InsertItem(index, item);
        owner.Controls.Add(item);
        Attach(item);
    }

    protected override void RemoveItem(int index)
    {
        var item = this[index];
        Detach(item);
        owner.Controls.Remove(item);
        base.RemoveItem(index);
    }

    // implement SetItem and ClearItems similarly
}

Troubleshooting notes: always detach handlers on removal or Dispose to prevent memory leaks; unsubscribe before subscribing if re-adding; guard for cross-thread adds (use Invoke); and override SetItem/ClearItems so replacements and clears handle events correctly. These patterns complement your CollectionBase route and give you designer/usage flexibility.

OK, I figured it out. All those other controls use custom collections derived from CollectionBase, this allows you to do customize the add and remove methods of the collection class to do such things as that I mentioned. also its strongly types so I can easily make sure that only my Segment Controls can be added to the view.

Thanks again daniweb for giving me a place to talk to myself until I figure it out...

Be a part of the DaniWeb community

We're a friendly, industry-focused community of developers, IT pros, digital marketers, and technology enthusiasts meeting, networking, learning, and sharing knowledge.