0

我有一个页面 PeopleView,它由一个显示人员列表的 GridView 组成。我希望提供一种通过弹出用户控件从人员列表中添加删除的方法。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 中添加和删除人员。它还允许搜索人员:

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);

当输入搜索文本时,会在视图模型上调用 FilterPeople 方法,如下所示:

private void FilterPeople(string searchField)
{
    FilteredPeople = _allPeople.Where(p => p.Name.Equals(searchField));
    People = FilteredPeople.Where(p => p.Selected);
}

我正在使用 WinRT XAML 工具包提供的 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