前提条件を一度にすべてのビューにフィルタを適用します。コントロールのItemsコレクションにフィルターを適用しようとすると、このフィルターは他のコントロールに自動的に伝播し、異なるコントロールで異なるフィルターを使用できなくなります。 コレクションのツリーインスタンスを一度に維持する必要がなく、同じ結果を達成する方法はありますか?複数のItemsControlは
この問題を示す例を以下に示します。最初の2つのListViewは、同じコレクションインスタンスに直接バインドされています。 3番目のインスタンスは、CompositeCollectionを介してそのインスタンスにバインドされています。そして4番目は独立したコレクションにバインドされています。最初のListViewがWTestウィンドウのIsAllowedItemメソッドに設定されている場合、 "Set Filter"ボタンItemsControl.Items.Filterプロパティを押します。この2番目のListView.Items.Filterプロパティは、3番目と4番目のListViewがnullを返す間、何らかの方法で同じメソッドを指しています。もう1つの効果は、3番目のListViewにnullフィルタが表示されますが、その例を実行するとわかるように、そのコレクションはまだフィルタリングされています。この非常に奇妙な結果は、ItemCollectionクラスの動作から発生します。これは、owner要素のItemsSourceプロパティに基づいて、アプリケーション全体のストレージからCollectionViewSource.GetDefaultCollectionViewメソッドを介して基礎となるCollectionViewを取得することです。私はこの実装の理由を知らないが、それがパフォーマンスであると思われる疑いがある。
テストウィンドウWTest.xaml:WTest.xaml.cs
背後<Window x:Class="Local.WTest"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:s="clr-namespace:System;assembly=mscorlib"
xmlns:c="clr-namespace:System.Collections;assembly=mscorlib"
xmlns:local="clr-namespace:Local"
Name="_WTest" Title="WTest" Height="300" Width="600">
<Window.Resources>
<c:ArrayList x:Key="MyArray">
<s:String>Letter A</s:String>
<s:String>Letter B</s:String>
<s:String>Letter C</s:String>
</c:ArrayList>
<CompositeCollection x:Key="MyCollection" >
<CollectionContainer Collection="{StaticResource ResourceKey=MyArray}"/>
</CompositeCollection>
<c:ArrayList x:Key="AnotherArray">
<s:String>Letter A</s:String>
<s:String>Letter B</s:String>
<s:String>Letter C</s:String>
</c:ArrayList>
</Window.Resources>
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="Auto"/>
<RowDefinition Height="*"/>
<RowDefinition Height="Auto"/>
</Grid.RowDefinitions>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="*"/>
<ColumnDefinition Width="*"/>
<ColumnDefinition Width="*"/>
<ColumnDefinition Width="*"/>
</Grid.ColumnDefinitions>
<TextBlock Grid.Row="0" Grid.Column="0" Name="FilterLabel1"/>
<TextBlock Grid.Row="0" Grid.Column="1" Name="FilterLabel2"/>
<TextBlock Grid.Row="0" Grid.Column="2" Name="FilterLabel3"/>
<TextBlock Grid.Row="0" Grid.Column="3" Name="FilterLabel4"/>
<ListView Grid.Row="1" Grid.Column="0" Name="View1" ItemsSource="{StaticResource ResourceKey=MyArray}"/>
<ListView Grid.Row="1" Grid.Column="1" Name="View2" ItemsSource="{StaticResource ResourceKey=MyArray}"/>
<ListView Grid.Row="1" Grid.Column="2" Name="View3" ItemsSource="{StaticResource ResourceKey=MyCollection}"/>
<ListView Grid.Row="1" Grid.Column="3" Name="View4" ItemsSource="{StaticResource ResourceKey=AnotherArray}"/>
<Button Grid.Row="2" Grid.Column="0" Grid.ColumnSpan="4" Content="Set Filter" Click="OnSetFilterButtonClick"/>
</Grid>
</Window>
コード
namespace Local {
using System.Windows;
public partial class WTest : Window {
public WTest() {
InitializeComponent();
UpdateFilterLabels();
}
private bool IsAllowedItem(object item) {
return "Letter A" == (string)item;
}
private void OnSetFilterButtonClick(object sender, RoutedEventArgs e) {
View1.Items.Filter = IsAllowedItem;
UpdateFilterLabels();
}
private void UpdateFilterLabels() {
FilterLabel1.Text = (null == View1.Items.Filter) ? "No Filter" : View1.Items.Filter.Method.Name;
FilterLabel2.Text = (null == View2.Items.Filter) ? "No Filter" : View2.Items.Filter.Method.Name;
FilterLabel3.Text = (null == View3.Items.Filter) ? "No Filter" : View3.Items.Filter.Method.Name;
FilterLabel4.Text = (null == View4.Items.Filter) ? "No Filter" : View4.Items.Filter.Method.Name;
}
}
}
その結果、 "フィルタの設定" ボタンをクリックした後: Example: result of clicking "Set Filter" button
、ありがとう、CollectionViewSourceのプロキシが役立ちました。 –