People のリストを表示する GridView で構成される PeopleView ページがあります。ポップアップ ユーザー コントロールを使用して、People のリストから削除を追加する方法を提供したいと考えています。UserControl では、すべてのユーザーを検索してさらに追加することもできます。
UserControl が最初に開いたときに、すべての人が表示され、GridView に現在表示されている人は、ポップアップ ListView で既に選択されている必要があります。ユーザーが UserControl で追加の People を選択すると、People コレクションが追加され、メインの GridView にこれが反映されます。これはすべて意図したとおりに機能します。
ポップアップで人のリストをフィルタリングしようとすると、問題が発生します。これにより、FilteredPeople コレクションがリセットされ、ListView からすべての選択が削除されるため、ObservableCollection からメイン ページの GridView がクリアされます。
選択を保持しながら人物を検索し、検索中にこのリストに追加および削除したいと考えています。
これは、メイン ページの GridView です。
<GridView x:Name="PeopleGridView"
Grid.Row="1"
Padding="116, 0, 0, 0"
ItemsSource="{Binding People}"
ItemTemplate="{StaticResource PeopleSelectItemTemplate}"
SelectionMode="Multiple" />
このページには、この GridView から People を追加および削除できるポップアップ ユーザー コントロールがあります。また、人を検索することもできます。
xaml は次のようになります。
<TextBlock Style="{StaticResource PopupHeaderTextStyle}"
Text="Enter person name:"
TextWrapping="Wrap"/>
<TextBox Grid.Column="1"
x:Name="SearchFieldTextBox"
TextChanged="SearchField_Changed"
Margin="20,0,20,0"
Height="30" />
<ListView Grid.Row="1"
Grid.ColumnSpan="2"
SelectedIndex="1"
SelectionMode="Multiple"
ItemsSource="{Binding FilteredPeople}"
extensions:ListViewExtensions.BindableSelection="{Binding People}"
ItemTemplate="{StaticResource PeopleSearchItemTemplate}"
HeaderTemplate="{StaticResource PeopleSearchHeaderTemplate}"/>
People と FilteredPeople は、ビュー モデルのプロパティです。
private ObservableCollection<PeopleViewModel> _people;
public ObservableCollection<PeopleViewModel> People
{
get { return people; }
set
{
if (Equals(people, value)) return;
people = value;
RaisePropertyChanged(() => People);
}
}
private IEnumerable<PeopleViewModel> _filteredPeople;
public IEnumerable<PeopleViewModel> FilteredPeople
{
get { return _filteredPeople; }
set
{
if (_filteredPeople == value) return;
_filteredPeople = value;
RaisePropertyChanged(() => FilteredPeople);
}
}
それらはロード時に次のように設定されます。
FilteredPeople = _allPeople = _peopleService.GetAll();
People = _allPeople.Where(p => p.Selected);
検索テキストが入力されると、次のように、viewmodel で FilterPeople メソッドが呼び出されます。
private void FilterPeople(string searchField)
{
FilteredPeople = _allPeople.Where(p => p.Name.Equals(searchField));
People = FilteredPeople.Where(p => p.Selected);
}
WinRT XAML Toolkit によって提供される BindableSelection 拡張機能を使用しています。ListView の項目が選択されると、基になるモデル オブジェクトが更新されます。
void People_CollectionChanged(object sender, NotifyCollectionChangedEventArgs e)
{
if (e.Action == NotifyCollectionChangedAction.Add)
{
var person = e.NewItems[0] as PeopleViewModel;
person.Selected = true;
_personService.Save(person);
}
else if (e.Action == NotifyCollectionChangedAction.Remove)
{
var person = e.OldItems[0] as PeopleViewModel;
person.Selected = false;
_personService.Save(person);
}
}
問題は、FilteredPeople コレクションがリセットされることですが、これを行う方法がわかりません。これを行う方法の例をオンラインで見つけることができません。
私はMVVM Crossを使用していますが、これはこのシナリオでの用途です
私は何を間違っていますか?