WPFでグループ化したリストボックスを作ろうとしています。これは、WPF4 Unleashed および Web 上の他のチュートリアルで説明されているように簡単に実行できます。
XAML (共通の項目ソースを更新するためのグループ化 + ボタンがある場合とない場合の 2 つのリストを次に示します):
<Window x:Class="GroupTest.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Title="MainWindow" Height="350" Width="525"
Loaded="Window_Loaded">
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="*" />
<RowDefinition Height="*" />
<RowDefinition Height="Auto" />
</Grid.RowDefinitions>
<ListBox Grid.Row="0" ItemsSource="{Binding Path=Items}" x:Name="_listBox1">
<ListBox.GroupStyle>
<x:Static Member="GroupStyle.Default" />
</ListBox.GroupStyle>
<ListBox.ItemTemplate>
<DataTemplate>
<TextBlock Text="{Binding Path=Name}" />
</DataTemplate>
</ListBox.ItemTemplate>
</ListBox>
<ListBox Grid.Row="1" ItemsSource="{Binding Path=Items}" x:Name="_listBox2">
<ListBox.ItemTemplate>
<DataTemplate>
<TextBlock Text="{Binding Path=Name}" />
</DataTemplate>
</ListBox.ItemTemplate>
</ListBox>
<Button Grid.Row="2" Content="Update Items" Click="Button_Click" Focusable="False"/>
</Grid>
</Window>
コード (ここでは、ページが読み込まれたときにグループ化を設定し、ボタンがクリックされたときに項目ソースを更新/置換します):
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Navigation;
using System.Windows.Shapes;
using System.ComponentModel;
namespace GroupTest
{
public partial class MainWindow : Window, INotifyPropertyChanged
{
public class Item
{
public string Name { get; set; }
public bool Flag { get; set; }
}
private List<Item> _items;
public List<Item> Items
{
get { return _items; }
set
{
if (_items != value)
{
_items = value;
NotifyPropertyChanged("Items");
}
}
}
public event PropertyChangedEventHandler PropertyChanged;
public MainWindow()
{
InitializeComponent();
MakeItems();
DataContext = this;
}
private void Window_Loaded(object sender, RoutedEventArgs e)
{
ICollectionView view = CollectionViewSource.GetDefaultView(_listBox1.Items);
view.GroupDescriptions.Add(new PropertyGroupDescription("Flag"));
}
private void MakeItems()
{
_items = new List<Item>();
_items.Add(new Item() { Name = "1", Flag = true });
_items.Add(new Item() { Name = "2", Flag = true });
_items.Add(new Item() { Name = "3", Flag = false });
_items.Add(new Item() { Name = "4", Flag = true });
_items.Add(new Item() { Name = "5", Flag = false });
}
private void UpdateItems()
{
Items = new List<Item>(_items);
}
private void Button_Click(object sender, RoutedEventArgs e)
{
UpdateItems();
}
private void NotifyPropertyChanged(string propertyName)
{
if (PropertyChanged != null)
{
PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
}
}
}
}
動作しますが、回避できない奇妙なバグがあります。グループ化されたリスト #1 は、項目ソースを更新するたびにフォーカスを失います。グループ化されていないリスト#2はフォーカスを維持します。
完全なプロジェクト ソースへのリンクは次のとおりです: https://dl.dropbox.com/u/60611528/GroupTest.zip
助言がありますか?前もって感謝します!
更新 Items を ObservableCollection<> にしようとしましたが、これは役に立ちませんでした。グループ化されたリストからフォーカスが消えます。
更新 2 私の実際のアプリでは、リスト ボックスを認識しないモデル クラスに項目があります。ウィンドウとモデル クラスを密結合せずに問題を解決できるソリューションを期待しています。