c# silverlight xaml combobox optgroup

c# - Mostrar el encabezado del grupo ComboBox para Silverlight



xaml optgroup (3)

Quiero mostrar un ComboBox con OPTGROUP encabezado de estilo OPTGROUP en Silverlight. Cada sitio web que encuentro (incluidas las preguntas sobre SO) que sovle este enlace a un enlace obsoleto y, de forma práctica, no muestran fragmentos de código para que pueda trabajar.

P.ej:

Entonces, ¿cómo hago esto?


Aquí hay un enfoque generalizado. No está mal, y debe ser lo suficientemente flexible, aunque tiene la debilidad de requerir una clase de colección extendida (no puede hacer uso de CollectionViewSource).

Paso 1 Objeto ComboBoxGroupHeader

Esto cumple la función de "entrada ficticia" mencionada por @NiteshChordiya.

public class ComboBoxGroupHeader { public ComboBoxGroupHeader(object header) { Header = header; } public object Header { get; protected set; } }

Paso 2 Extended ComboBox

Esto anula PrepareContainerForItemOverride , para jugar con los contenedores de los elementos ficticios. También proporciona un (opcional) "HeaderTemplate".

public class GroupedComboBox : ComboBox { public DataTemplate HeaderTemplate { get { return (DataTemplate)GetValue(HeaderTemplateProperty); } set { SetValue(HeaderTemplateProperty, value); } } public static readonly DependencyProperty HeaderTemplateProperty = DependencyProperty.Register("HeaderTemplate", typeof(DataTemplate), typeof(GroupedComboBox), new PropertyMetadata(null)); protected override void PrepareContainerForItemOverride(DependencyObject element, object item) { base.PrepareContainerForItemOverride(element, item); var container = element as ComboBoxItem; if (container != null && item is ComboBoxGroupHeader) { // prevent selection container.IsHitTestVisible = false; // adjust the container to display the header content container.ContentTemplate = HeaderTemplate container.Content = ((ComboBoxGroupHeader)item).Header; } } }

Paso 3 Clase de colección extendida

Esto hace la agrupación y agrega las entradas ficticias "ComboBoxGroupHeader". Esta implementación es esencialmente de solo lectura (las agrupaciones se romperían si trataba de agregar nuevos elementos), pero sería sencillo admitir operaciones como "Agregar", "Insertar", etc.

public class GroupedCollection<T, TGroup> : ObservableCollection<object> { private Func<T, TGroup> _grouping; public IEnumerable<T> BaseItems { get { return base.Items.OfType<T>(); } } public GroupedCollection(IEnumerable<T> initial, Func<T, TGroup> grouping) : base(GetGroupedItems(initial, grouping)) { _grouping = grouping; } private static IEnumerable<object> GetGroupedItems(IEnumerable<T> items, Func<T, TGroup> grouping) { return items .GroupBy(grouping) .SelectMany(grp => new object[] { new ComboBoxGroupHeader(grp.Key) } .Union(grp.OfType<object>()) ); } }

Uso

Funciona como un ComboBox normal, con el HeaderTemplate opcional:

<local:GroupedComboBox ItemsSource="{Binding Source}"> <local:GroupedComboBox.HeaderTemplate> <TextBlock FontSize="9" TextDecorations="Underline" Foreground="DarkGray" Text="{Binding}" /> </local:GroupedComboBox.HeaderTemplate> </local:GroupedComboBox>

Para que el agrupamiento surta efecto, la fuente debe usar la "Agrupación de Recolección" arriba, para incluir los elementos del encabezado ficticio. Ejemplo:

public class Item { public string Name { get; set; } public string Category { get; set; } public Item(string name, string category) { Name = name; Category = category; } } public class Items : GroupedCollection<Item, string> { public Items(IEnumerable<Item> items) : base(items, item => item.Category) { } } public class ViewModel { public IEnumerable<Item> Source { get; private set; } public ViewModel() { Source = new Items(new Item[] { new Item("Apples", "Fruits"), new Item("Carrots", "Vegetables"), new Item("Bananas", "Fruits"), new Item("Lettuce", "Vegetables"), new Item("Oranges", "Fruits") }); } }


El encabezado de grupo no es compatible con ComboBox. Manera alternativa para implementarlo con DataGrid o usar TreeView para mostrar datos agrupados.

Sin embargo, puedes probar algo como esto,

Silverlight Custom ComboBox