TreeView
データの階層を持つSilverlight 4コントロールがあります。各レベルのアイテムをアルファベット順に並べ替えたいので、を使用してCollectionViewSource
いますが、並べ替えがどのように行われるかは実際には気にしません。
はイベントCollectionViewSource
を監視しているように見えるCollectionChanged
ため、アイテムが追加および削除されると、並べ替えは正常に機能します。
はCollectionViewSource
並べ替え対象のプロパティの変更を監視しないため、アイテムのテキストが変更された場合、並べ替えは維持されません。呼び出すCollectionViewSource.View.Refresh()
とリストが再ソートされますが、選択は破棄されます。選択を失ったり再設定したりせずTreeView
に選択を保持するにはどうすればよいですか?
サンプル プロジェクト:
説明:
このプロジェクトは、アイテムの単一レベル ツリーを作成します。各項目には、項目番号と、並べ替えを実際に興味深いものにするための数字の接頭辞が与えられます。ボタンは、アイテムを追加し、最も古いアイテムを削除し、最も古いアイテムの名前を変更します。
サンプルのビルド:
- 「SortTest」という名前の新しい Silverlight アプリケーションを作成します。
- System.Windows.Controls への参照を追加します (ツリービュー用)。
- 次のファイルを更新します。
注意すべき動作:
- 項目が追加および削除されても、現在の選択が維持されます。
Refresh()
項目の名前が変更されると (内から が呼び出されると) 、現在の選択は失われますOnRenameButtonClick()
。- への呼び出し
Refresh()
が削除された場合、アイテムの名前を変更するときに選択が維持されますが、リストは名前の変更を考慮して再ソートされません。
MainPage.xaml
<UserControl x:Class="SortTest.MainPage"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:sdk="http://schemas.microsoft.com/winfx/2006/xaml/presentation/sdk">
<UserControl.Resources>
<Style x:Key="expandedStyle" TargetType="sdk:TreeViewItem">
<Setter Property="IsExpanded" Value="true" />
</Style>
<sdk:HierarchicalDataTemplate x:Key="template">
<TextBlock Text="{Binding Name}" />
</sdk:HierarchicalDataTemplate>
</UserControl.Resources>
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="Auto" />
<RowDefinition Height="*" />
</Grid.RowDefinitions>
<StackPanel Grid.Row="0" Orientation="Horizontal">
<Button Click="OnAddButtonClick">
<TextBlock Text="Add an item" />
</Button>
<Button Click="OnRemoveButtonClick">
<TextBlock Text="Remove lowest numbered item" />
</Button>
<Button Click="OnRenameButtonClick">
<TextBlock Text="Rename lowest numbered item" />
</Button>
</StackPanel>
<sdk:TreeView Grid.Row="1" ItemsSource="{Binding Items}" ItemTemplate="{StaticResource template}" />
</Grid>
</UserControl>
MainPage.xaml.cs
using System.Windows.Controls;
using System.Collections.ObjectModel;
using System.Windows;
using System.Windows.Data;
using System.ComponentModel;
using System;
using System.Collections.Specialized;
namespace SortTest
{
public partial class MainPage : UserControl
{
private ObservableCollection<ItemViewModel> items = new ObservableCollection<ItemViewModel>();
private CollectionViewSource sortedItems = new CollectionViewSource();
private int itemNumber = 1;
public MainPage()
{
sortedItems.Source = items;
sortedItems.SortDescriptions.Add(new SortDescription("Name", ListSortDirection.Ascending));
DataContext = this;
InitializeComponent();
}
public ICollectionView Items { get { return sortedItems.View; } }
private void OnAddButtonClick(object sender, RoutedEventArgs e)
{
ItemViewModel item = new ItemViewModel();
item.Name = DateTime.Now.Millisecond.ToString("D3") + " Item #" + itemNumber;
itemNumber++;
items.Add(item);
}
private void OnRemoveButtonClick(object sender, RoutedEventArgs e)
{
if (items.Count > 0)
{
items.RemoveAt(0);
}
}
private void OnRenameButtonClick(object sender, RoutedEventArgs e)
{
if (items.Count > 0)
{
items[0].Name = DateTime.Now.Millisecond.ToString("D3") + items[0].Name.Substring(3);
sortedItems.View.Refresh();
}
}
}
public class ItemViewModel : DependencyObject
{
public static DependencyProperty NameProperty = DependencyProperty.Register("Name", typeof(string), typeof(ItemViewModel), null);
public string Name
{
get { return GetValue(NameProperty) as string; }
set { SetValue(NameProperty, value); }
}
}
}
ありがとう!