DevComponents.Silverlight.ItemsHostControl is a control for displaying a collection of items. It inherits from System.Windows.Controls.ItemsControl. ItemsHostControl differs from ItemsControl in one key manner: by default it completely by-passes the base class’s mechanism for creating and filling the hosting panel. This allows for greater flexibility:
- The panel used to host the visual containers is easily accessible via a public property (ItemsHostControl.ItemsHost)
- The hosting panel can be set in code, as well as in Xaml.
- No restrictions on adding and removing UIElements from the hosting panel, making it easy, for example, to remove an element from one location of the visual tree before placing it into another, or for a custom panel to add elements which support functionality and/or visual appearance of the collection being displayed.
- Derived classes can create containers that are specifically targeted to the objects that they are intended to contain (without relying on undocumented behavior.)
Like with Silverlight’s ItemsControl, the Items collection can be populated directly either in Xaml or in code, or it can be populated by binding an enumerable data source to the ItemsSource dependency property. To support dynamically adding and removing items at runtime, the data source object must implement interface INotifyCollectionChanged.
By default, all items which derive from UIElement are their own containers. For other items a System.Windows.ContentPresenter is created. The Content Presenter’s ContentTemplate property is bound to the ItemHostControl’s ItemTemplate property. The exception to this is when a typed DataTemplate, described below, is applicable. To specify a style to apply to all containers of a specific Type, use property ItemContainerStyle.
As with the base class, container creation can be customized by overriding method GetContainerForItemOverride. In addition to the base class version of this method, which is parameterless, ItemsHostControl exposes an override with a single parameter of type object containing the item for which the container is meant to contain. Like the base class, virtual methods PrepareItemContainerOverride and ClearContainerForItemOverride are also available. The first is called before an item’s container is inserted into the items host panel, and the latter is called when the item has been removed from the Items collection.
By default, items are hosted in a StackPanel, with vertical orientation. Define a custom Panel in code by overriding the CreateCustomItemsHost virtual method, or in Xaml by setting a value for property ItemsHostTemplate. The top element in the DataTemplate defined by ItemsHostTemplate must inherit from System.Windows.Controls.Panel. Note that if you re-template the ItemsHostControl or your derived class defines its own template, a ContentPresenter with the name "ItemsPresenter" needs to be present at the position where the items host panel is to be displayed. This is comparable to Silverlight’s ItemsPresenter used by ItemsControl. Alternatively, any control appearing in the template which derives from Panel and has the name "ItemsHost" will be used as the hosting panel.
ItemsHostControl can be used to simulate the typed DataTemplate feature found in Wpf but missing in Silverlight. For items which are not UIElements, the default implementation of ItemsHostControl.CreateContainerForItem will search through the Resources of the visual tree looking for a DataTemplate which has a value for the attached property DevComponents.Silverlight.Controls.TypedDataTemplate.DataType that is equal to the type of the item being added. If found, the container is then generated directly from the template, and its DataContext property set to equal the item being added.
More about typed data templates in DotNetBar for Silverlight can be found here.
It is necessary for the control’s template to contain either a System.Windows.Controls.ContentPresenter or System.Windows.Controls.ContentControl named "ItemsPresenter" which is used to present the items host panel. The default template contains only a single element:
<ControlTemplate TargetType="ctrls:ItemsHostControl"> <ContentPresenter Name="ItemsPresenter" /> </ControlTemplate>