2010-12-06 78 views
2

我有一个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); } 
     } 
    } 
} 

谢谢!

回答

0

将选定的项目保存到isolatedStorage并在重新加载树视图后重新选择它。

+0

添加一些代码来阐明你的意思。 – Jehof 2011-05-20 14:05:38

相关问题