Silverlight でスタイル ヘッダー グループComboBox
を表示したいと考えています。OPTGROUP
私が見つけたすべてのWebサイト(SOに関する質問を含む)は、このリンクを古いリンクに変換し、便利なことに、作業するためのコードスニペットを表示しません.
例えば:
では、これを行うにはどうすればよいですか?
Silverlight でスタイル ヘッダー グループComboBox
を表示したいと考えています。OPTGROUP
私が見つけたすべてのWebサイト(SOに関する質問を含む)は、このリンクを古いリンクに変換し、便利なことに、作業するためのコードスニペットを表示しません.
例えば:
では、これを行うにはどうすればよいですか?
私の同様の質問を参照してください: Silverlight コンボボックスで項目のグループ ヘッダーを表示する方法は? コレクション ソースにダミー エントリを配置してグループ ヘッダーを示し、DataTemplate を変更して、グループ ヘッダーを別の方法で表示し、通常のエントリを別の方法で表示しました。
これが一般化されたアプローチの 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;
}
}
}
ステップ 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")
});
}
}
ComboBox では、グループ ヘッダーはサポートされていません。DataGrid で実装するか、TreeView を使用してグループ化されたデータを表示する別の方法。
ただし、このようなことを試すことができます。