0

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を使用していますが、これはこのシナリオでの用途です

私は何を間違っていますか?

4

0 に答える 0