ビューにを作成しないCollectionViewSource
でください。代わりに、ICollectionView
ビューモデルにtypeのプロパティを作成し、それにバインドListView.ItemsSource
します。
これを行うと、ユーザーが変更するたびに呼び出すロジックをプロパティのセッターに配置できますFilterText
。Refresh()
ICollectionView
これにより、並べ替えの問題も単純化されることがわかります。並べ替えロジックをビューモデルに組み込み、ビューで使用できるコマンドを公開できます。
編集
これは、MVVMを使用したコレクションビューの動的な並べ替えとフィルタリングの非常に簡単なデモです。このデモは実装されていませんFilterText
が、すべてがどのように機能するかを理解すれば、FilterText
現在使用しているハードコードされたフィルターの代わりに、プロパティとそのプロパティを使用する述語を実装するのに問題はありません。
(ここのビューモデルクラスはプロパティ変更通知を実装していないことにも注意してください。これはコードを単純にするためです。このデモでは実際にプロパティ値を変更するものはないため、プロパティ変更通知は必要ありません。)
あなたのアイテムのための最初のクラス:
public class ItemViewModel
{
public string Name { get; set; }
public int Age { get; set; }
}
ここで、アプリケーションのビューモデル。ここで行われていることは3つあります。1つは、独自の機能を作成して設定することICollectionView
です。ApplicationCommand
次に、ビューが並べ替えとフィルタリングのコマンドを実行するために使用する(以下を参照)を公開し、最後に、ビューを並べ替えExecute
またはフィルタリングするメソッドを実装します。
public class ApplicationViewModel
{
public ApplicationViewModel()
{
Items.Add(new ItemViewModel { Name = "John", Age = 18} );
Items.Add(new ItemViewModel { Name = "Mary", Age = 30} );
Items.Add(new ItemViewModel { Name = "Richard", Age = 28 } );
Items.Add(new ItemViewModel { Name = "Elizabeth", Age = 45 });
Items.Add(new ItemViewModel { Name = "Patrick", Age = 6 });
Items.Add(new ItemViewModel { Name = "Philip", Age = 11 });
ItemsView = CollectionViewSource.GetDefaultView(Items);
}
public ApplicationCommand ApplicationCommand
{
get { return new ApplicationCommand(this); }
}
private ObservableCollection<ItemViewModel> Items =
new ObservableCollection<ItemViewModel>();
public ICollectionView ItemsView { get; set; }
public void ExecuteCommand(string command)
{
ListCollectionView list = (ListCollectionView) ItemsView;
switch (command)
{
case "SortByName":
list.CustomSort = new ItemSorter("Name") ;
return;
case "SortByAge":
list.CustomSort = new ItemSorter("Age");
return;
case "ApplyFilter":
list.Filter = new Predicate<object>(x =>
((ItemViewModel)x).Age > 21);
return;
case "RemoveFilter":
list.Filter = null;
return;
default:
return;
}
}
}
並べ替えの種類は最悪です。を実装する必要がありますIComparer
:
public class ItemSorter : IComparer
{
private string PropertyName { get; set; }
public ItemSorter(string propertyName)
{
PropertyName = propertyName;
}
public int Compare(object x, object y)
{
ItemViewModel ix = (ItemViewModel) x;
ItemViewModel iy = (ItemViewModel) y;
switch(PropertyName)
{
case "Name":
return string.Compare(ix.Name, iy.Name);
case "Age":
if (ix.Age > iy.Age) return 1;
if (iy.Age > ix.Age) return -1;
return 0;
default:
throw new InvalidOperationException("Cannot sort by " +
PropertyName);
}
}
}
Execute
ビューモデルのメソッドをトリガーするために、これはApplicationCommand
クラスを使用します。これは、ビューのオンボタンをビューモデルのメソッドにICommand
ルーティングする単純な実装です。アプリケーションビューモデルに多数のプロパティを作成したくなかったため、この方法で実装しました。また、すべての並べ替え/フィルタリングを1つのメソッドに保持して、実行方法を簡単に確認できるようにしたいと考えました。CommandParameter
Execute
RelayCommand
public class ApplicationCommand : ICommand
{
private ApplicationViewModel _ApplicationViewModel;
public ApplicationCommand(ApplicationViewModel avm)
{
_ApplicationViewModel = avm;
}
public void Execute(object parameter)
{
_ApplicationViewModel.ExecuteCommand(parameter.ToString());
}
public bool CanExecute(object parameter)
{
return true;
}
public event EventHandler CanExecuteChanged;
}
最後にMainWindow
、アプリケーションのは次のとおりです。
<Window x:Class="CollectionViewDemo.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:CollectionViewDemo="clr-namespace:CollectionViewDemo"
Title="MainWindow" Height="350" Width="525">
<Window.DataContext>
<CollectionViewDemo:ApplicationViewModel />
</Window.DataContext>
<DockPanel>
<ListView ItemsSource="{Binding ItemsView}">
<ListView.View>
<GridView>
<GridViewColumn DisplayMemberBinding="{Binding Name}"
Header="Name" />
<GridViewColumn DisplayMemberBinding="{Binding Age}"
Header="Age"/>
</GridView>
</ListView.View>
</ListView>
<StackPanel DockPanel.Dock="Right">
<Button Command="{Binding ApplicationCommand}"
CommandParameter="SortByName">Sort by name</Button>
<Button Command="{Binding ApplicationCommand}"
CommandParameter="SortByAge">Sort by age</Button>
<Button Command="{Binding ApplicationCommand}"
CommandParameter="ApplyFilter">Apply filter</Button>
<Button Command="{Binding ApplicationCommand}"
CommandParameter="RemoveFilter">Remove filter</Button>
</StackPanel>
</DockPanel>
</Window>