Features
Tiles inherit from UserControl Allows full design time editing creation of Tiles Full Windows Gui look and feel Full theme support automatically. All custom rendering matched to system. Animation/Performance NOT a compromise Animation split into inherited control to avoid any performance hits unless you want them. Grouping, Sub grouping, etc support Group tiles supplied that handle all grouping functionality Built in drag drop re-order support Tiles can be drag-dropped to new positions and orders with events generated for absolute code level control over the functionality. External drag-drop option Allows control over whether Tiles can be copied/moved between two views without code.
Issues
Performance Because it instantiates a control (with subcontrols) for each line then there are performance issues with large lists Ability to deny Reorder before reordering Improved DragDrop placeholder Show when you are about to drop INTO a group, Show the placeholder over the next <Item> when closer to the next <Item>
Development problems solved to date
Define an <item>Collection from CollectionBase. Make sure the following are implemented.
public this[ int index ]
public int Add(<item> value)
public void AddRange(<item>[] parts)
public int IndexOf(<item> value)
public void Insert(int index, <item> value )
public void Remove(<item> value)
public bool Contains(<item> value )
First attempt I insisted on having a reference to the <Item>View so that I could call Add<Item> and Remove<Item> on it. i.e
public <item>Collection(parent)
protected override void OnInsert(int index, object value)
protected override void OnRemove(int index, object value)
However I now think that having events for Add and Remove allows me to construct a Collection and then wire up the Add, Remove if necessary. This also means I can create a Collection without the need for a <Item>View to update and more importantly, allows me to build a collection in a UITypeEditor and when it is added to the <Item>View, I can then add the Add, Remove event wiring. public event ControlEventHandler <Item>Added public event ControlEventHandler <Item>Removed// Deleted public <item>Collection(parent) protected override void OnInsert(int index, object value) protected override void OnRemove(int index, object value) Highlighting works of Focus (ie. GotFocus and LostFocus), not on <item>View.ActiveControl. However this does not allow MultiSelection. (see IContainerControl below) For a collection based on an abstract base class, then use a UITypeEditor that fetches the types available from the AppDomain, and shows any derived from the abstract base type. NB. If your TypeEditor also adds to the context.Container object then the Designer Generated Code will also contain your new <item> objects. Implemented uxTheme drawing by borrowing code from codeproject (maybe from Nick Hall, cant remember) Implemented a manually scrolling clientRectangle instead of relying on AutoScroll. (Avoids the undocumented feature in AutoScroll where adding controls after scrolling can produce a blank region in the scrollable view. And yes I was offsetting the newly added control by the scrolled amount). Impemented drag and drop rearranging referring to the TreeView dragDrop from CodeProject. Grouping - Ripped the clientRectangle functionality out of the Main control and created a base class. Subclassed this as clientRectScroll and clientRectResize. Derived a new class from called Group that aggregates the clientRectResize to handle grouping of s. Implemented View property on to provide a root Control for grouped items. (c.f. with TreeViewNode.TreeView). Yes I know I decided against this earlier BUT it now works differently i.e. The Collection is still not laboured with having a reference to the View. The View overloads the OnAdded functionality of the clientRectangles Collection so that each is set to have the correct reference to the View. Each Group has an overriden set_View to ensure all child s have the right reference. i.e. if you add s to a Group and then add it into a View then the children s get updated too. Mouse wheel scrolling - Implemented IContainerControl to provide an active control in View. Each now calls View.Scroll on receiving a MouseEventArgs event relating to mouse wheel. View.Scroll needs to go to the next or previous item for each wheel click. Think I might implement a specialised iterator. It will need to hold a stack for each Group that it is currently in to handle Next() and Previous(), and need to search the tree for references when a new is assigned in. Arrrggghhhh. The MouseWheel event is raised in every parent control that listens for the event. THIS means I get one scroll event for every Group. Having to move MouseWheel event to client panel. Double Arrrgghhh. The iterator is failing. It can't handle popping and then avoiding going back into the collection. So instead I am creating a cached flattened version, now you just moveup and down this. Calls added in the Group.Add/Remove and Container.Collection.Add/Remove to invalidate this cache.