Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/video/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Xaml 过滤ObservableCollection清除选择_Xaml_Mvvm_Winrt Xaml_Observablecollection_Winrt Xaml Toolkit - Fatal编程技术网

Xaml 过滤ObservableCollection清除选择

Xaml 过滤ObservableCollection清除选择,xaml,mvvm,winrt-xaml,observablecollection,winrt-xaml-toolkit,Xaml,Mvvm,Winrt Xaml,Observablecollection,Winrt Xaml Toolkit,我有一个页面PeopleView,它由一个显示人员列表的GridView组成。我希望提供一种通过弹出式用户控件从人员列表中添加或删除的方法。UserControl还允许搜索所有用户以添加更多内容 当UserControl第一次打开时,它应该显示所有的人,它确实显示了这些人,并且在弹出列表视图中应该已经选择了GridView中当前可见的任何人。当用户在UserControl中选择addition People时,应该将People集合添加到其中,主GridView会反映这一点。这一切都按预期进行

我有一个页面PeopleView,它由一个显示人员列表的GridView组成。我希望提供一种通过弹出式用户控件从人员列表中添加或删除的方法。UserControl还允许搜索所有用户以添加更多内容

当UserControl第一次打开时,它应该显示所有的人,它确实显示了这些人,并且在弹出列表视图中应该已经选择了GridView中当前可见的任何人。当用户在UserControl中选择addition 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" />
输入搜索文本后,将在viewmodel上调用FilterPeople方法,如下所示:

<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}"/>
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交叉,这在这个场景中有什么用处吗


我做错了什么?

Hmm,如果没有多个select,这很容易(只需将属性绑定到SelectedItem)。您可能希望在用户控件上创建一个属性,该属性绑定到VM上的SelectedPeople属性,该属性充当两者之间的中介…我认为这不会解决在重置FilteredPeople集合时清除选择的问题。
BindableSelection
扩展支持一些最基本的功能场景,但我自己会在出现问题时切换到自定义代码。这可能是您可以解决的问题,也可能是您可以对工具箱进行的更新,但要快速解除阻止,您只需处理
SelectionChanged
/
CollectionChanged
事件,以同步视图和视图模型中的选择。
private void FilterPeople(string searchField)
{
    FilteredPeople = _allPeople.Where(p => p.Name.Equals(searchField));
    People = FilteredPeople.Where(p => p.Selected);
}
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);
    }
}