我有一個silverlight 4 TreeView
控制與數據的層次結構。我希望每個級別的項目都按照字母順序排序,所以我使用的是CollectionViewSource
,但實際上並不關心如何完成排序。如何維護排序後的silverlight樹視圖中的當前選擇?
該CollectionViewSource
似乎觀察CollectionChanged
事件,所以排序工作正常,因爲項目添加和刪除。
CollectionViewSource
不會觀察對正在排序的屬性所做的更改,因此當項目的文本更改時,排序不會保留。調用CollectionViewSource.View.Refresh()
重新對列表進行排序,但放棄選擇。如何保持TreeView
選擇而不丟失並重新設置選擇?
範例項目:
說明:
該項目創建項目的單級樹。每個項目都有一個項目編號和一個數字前綴,以便排序實際上做一些有趣的事情。按鈕將添加一個項目,刪除最舊的項目,並重命名最舊的項目。
構建示例:
- 創建一個名爲 「SortTest」
- 添加到System.Windows.Controls的引用(樹視圖)
- 更新下列文件創建一個新的Silverlight應用程序:
行爲要注意:
- 當項目被添加和刪除時,當前選擇被保留。
- 重命名項目時(當在
OnRenameButtonClick()
內調用Refresh()
時),當前選擇將丟失。 - 如果刪除了對
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); }
}
}
}
謝謝!
添加一些代碼來闡明你的意思。 – Jehof 2011-05-20 14:05:38