4

我想在 Silverlight中显示ComboBox带有样式的标题组。OPTGROUP我发现的每个网站(包括关于 SO 的问题)都将这个链接指向一个过时的链接,并且方便地显示没有代码片段供我使用。

例如:

在此处输入图像描述

那么我该怎么做呢?

4

3 回答 3

1

请参阅我的类似问题:如何在 Silverlight 组合框中显示项目的组标题? 我将虚拟条目放在集合源中以指示组头,然后修改 DataTemplate 以不同的方式显示组头,并以不同的方式显示正常条目。

于 2014-02-02T06:39:52.400 回答
1

这是一种通用方法。这还不错,而且应该足够灵活——尽管它有需要扩展集合类的弱点(不能使用 CollectionViewSource)。

分组组合框屏幕截图

步骤 1 ComboBoxGroupHeader 对象

这起到了@NiteshChordiya 提到的“虚拟条目”的作用。

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

    public object Header { get; protected set; }
}

步骤 2 扩展组合框

这会覆盖PrepareContainerForItemOverride,以便修补虚拟物品的容器。它还提供了一个(可选的)“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;
        }
    }
}

Step 3 扩展集合类

这会进行分组,并添加虚拟的“ComboBoxGroupHeader”条目。此实现本质上是只读的(如果您尝试添加新项目,分组会中断),但支持“添加”、“插入”等操作将是直截了当的。

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>())
            );
    }
}

用法

它像普通的一样工作ComboBox,带有可选的HeaderTemplate

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

要使分组生效,源必须使用上面的“GroupedCollection”,以便包含虚拟标题项。例子:

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")
        });
    }
}
于 2014-03-13T23:55:13.727 回答
0

ComboBox 不支持组标题。使用 DataGrid 实现它或使用 TreeView 显示分组数据的替代方法。

但是,您可以尝试这样的事情,

Silverlight 自定义组合框

于 2013-11-01T04:30:13.300 回答