How to change the default item container for ItemsControl?
-
Friday, February 29, 2008 9:16 PM
From what I can tell using Reflector, the ItemsControl returns a ContentPresenter as its item container (while a ListBox returns a ListBoxItem, etc.). I need to implement custom selection logic - rather than using that provided by a Selector - so I was thinking I could just subclass the ItemsControl and force it to use a ListBoxItem as its item container so that I can still get the benefit of the ListBoxItem.IsSelected property.
So far I haven't figured out what all I need to override in order to cause the subclassed ItemsControl to apply something other than the ContentPresenter as its item container...just overriding the GetContainerForItemOverride method apparently isn't enough. Any suggestions?
All Replies
-
Saturday, March 01, 2008 5:07 PM
Here's a small example taken from the WPFcontrib project.
Code Snippet/// <summary>
/// Represents an <see cref="ItemsControl"/> that hosts <see cref="Button"/>s.
/// </summary>
public class ButtonList : ItemsControl
{
static ButtonList()
{
FocusableProperty.OverrideMetadata(typeof(ButtonList), new FrameworkPropertyMetadata(false));
DefaultStyleKeyProperty.OverrideMetadata(typeof(ButtonList), new FrameworkPropertyMetadata(typeof(ButtonList)));
}
/// <summary>
/// Determines if the specified item is (or is eligible to be) its own container.
/// </summary>
/// <param name="item">The item to check.</param>
/// <returns>
/// true if the item is (or is eligible to be) its own container; otherwise, false.
/// </returns>
protected override bool IsItemItsOwnContainerOverride(object item)
{
return item is Button;
}
/// <summary>
/// Creates or identifies the element that is used to display the given item.
/// </summary>
/// <returns>
/// The element that is used to display the given item.
/// </returns>
protected override DependencyObject GetContainerForItemOverride()
{
return new Button();
}
} -
Saturday, March 01, 2008 7:15 PM
Each ItemsControl has a corresponding Item Container, as illustrated by this table from the MSDN docs:
ItemsControl
Item container
ComboBox
ComboBoxItem
ContextMenu
MenuItem
ListBox
ListBoxItem
ListView
ListViewItem
Menu
MenuItem
StatusBar
StatusBarItem
TabControl
TabItem
TreeView
TreeViewItem
It is not readily apparent to me exactly what it is that you are attempting to achieve. Can you provide some more detail on what you are looking to do?
Keith
-
Thursday, March 20, 2008 7:13 AM
This greate Bragi. It's work perfectly. But i face another problem after apply this. Item Container is generated but IsSelected property is not set when Seletor change SelectedIndex. And ItemContainerGenerator.ContainerFromItem always return null. Is there anyway that i can explicitly associate this property with Selector when SelectedIndex is changed.
Regards,
-
Thursday, March 20, 2008 8:40 AMAre you inheriting from ItemsControl or from Selector?
-
Thursday, March 20, 2008 9:13 AM
Actually my custom control structured like this:
- MyControl: inherited from Selector
- MyControl.ItemSource: List<T>
- MyControl ItemContainer: MyControlItem (inherited from ListBoxItem)
Then i set default ItemContainer like your instruction above. It's work. But it seems IsSelected of MyControlItem is always reset to false. is there anyway to create MyControlItem explicitly and set IsSelected whenever SelectedIndex of Selector is changed.
Thanks for any advise.
-
Thursday, March 20, 2008 9:22 AMHaven't done this yet, so no idea.

