从绑定源过滤ListView项

时间:2016-08-05 15:09:08

标签: c# uwp uwp-xaml

我的应用程序显示了一个ListView,它使用数据绑定来显示多个项目的列表。一些变量使用TwoWay绑定,因此更改保存在viewmodel实例中,即datacontext。这是我的#34;主要" viewmodel的实例,因为它包含所有项目。

现在我要过滤此列表(包含所有项目)并仅显示部分项目。在过去,我在后面的代码中创建了一个viewmodel的新实例,并将我想要显示的所有项目从我的主实例复制到新创建的viewmodel实例,然后将这个新的viewmodel设置为DataContext。

这很好用,但是当我更改Data时,它只会保存到新创建的实例而不是主实例。因此,当我更改过滤器时,将再次从主实例加载项目而不进行任何更改。

有没有办法过滤我的视图模型的主要实例?我想在主实例上工作,以便自动保存更改。

ViewModel包含我自己的类的ObservableCollection,我想只显示一些根据过滤器绑定的项目。

2 个答案:

答案 0 :(得分:1)

  

过去,我在后面的代码中创建了一个viewmodel的新实例,并将我想要显示的所有项目从我的主实例复制到新创建的viewmodel实例,然后将这个新的viewmodel设置为DataContext

我认为没有必要创建新实例,您可以直接操纵ObservableCollection作为ListView的来源。

例如,我创建了一个包含所有数据的List,并将数据从ObservableCollection添加到List

<Page.DataContext>
    <local:MainPageViewModel x:Name="VM" />
</Page.DataContext>

<Grid>
    <Grid.RowDefinitions>
        <RowDefinition Height="4*" />
        <RowDefinition Height="*" />
        <RowDefinition Height="*" />
    </Grid.RowDefinitions>
    <ListView ItemsSource="{x:Bind VM.peopleCollection}">
        <ListView.ItemTemplate>
            <DataTemplate>
                <StackPanel>
                    <TextBox Text="{Binding Name, Mode=TwoWay}" />
                    <TextBox Text="{Binding Company, Mode=TwoWay}" />
                    <TextBox Text="{Binding Age, Mode=TwoWay}" />
                </StackPanel>
            </DataTemplate>
        </ListView.ItemTemplate>
    </ListView>
    <StackPanel Grid.Row="1">
        <Button Content="Age From 20-29" Click="{x:Bind VM.Age_Filter}" />
        <Button Content="Company AA" Click="{x:Bind VM.Company_Filter}" Margin="0,10" />
        <Button Content="Name Peter" Click="{x:Bind VM.Name_Filter}" />
    </StackPanel>
    <Button Content="Show All" Click="{x:Bind VM.Show_All}" Grid.Row="2" />
</Grid>

代码隐含在MainPageViewModel

public class MainPageViewModel
{
    public MainPageViewModel()
    {
        peopleList.Add(new Person { Name = "Jay", Company = "AA", Age = 25 });
        peopleList.Add(new Person { Name = "Peter", Company = "BB", Age = 35 });
        peopleList.Add(new Person { Name = "Jayden", Company = "AA", Age = 27 });
        peopleList.Add(new Person { Name = "John", Company = "AAC", Age = 26 });
        peopleList.Add(new Person { Name = "Alan", Company = "BB", Age = 45 });
        peopleList.Add(new Person { Name = "Frank", Company = "BB", Age = 29 });
        peopleList.Add(new Person { Name = "Ami", Company = "AA", Age = 24 });
        peopleList.Add(new Person { Name = "Elvis", Company = "AA", Age = 30 });
        peopleCollection.Clear();
        foreach (var person in peopleList)
        {
            peopleCollection.Add(person);
        }
    }

    private static List<Person> peopleList = new List<Person>();

    public ObservableCollection<Person> peopleCollection = new ObservableCollection<Person>();

    public void Age_Filter(object sender, RoutedEventArgs e)
    {
        foreach (var person in peopleList)
        {
            if (person.Age > 29 || person.Age < 20)
                peopleCollection.Remove(person);
        }
    }

    public void Company_Filter(object sender, RoutedEventArgs e)
    {
        foreach (var person in peopleList)
        {
            if (person.Company != "AA")
                peopleCollection.Remove(person);
        }
    }

    public void Name_Filter(object sender, RoutedEventArgs e)
    {
        foreach (var person in peopleList)
        {
            if (person.Name != "Peter")
                peopleCollection.Remove(person);
        }
    }

    public void Show_All(object sender, RoutedEventArgs e)
    {
        peopleCollection.Clear();
        foreach (var person in peopleList)
        {
            peopleCollection.Add(person);
        }
    }
}

在类Person的数据模型中,只有三个属性:Name,Company和Age。

public class Person : INotifyPropertyChanged
{
    private string _Name;

    public string Name
    {
        get { return _Name; }
        set
        {
            if (value != _Name)
            {
                _Name = value;
                OnPropertyChanged();
            }
        }
    }

    private string _Company;

    public string Company
    {
        get { return _Company; }
        set
        {
            if (value != _Company)
            {
                _Company = value;
                OnPropertyChanged();
            }
        }
    }

    private int _Age;

    public int Age
    {
        get { return _Age; }
        set
        {
            if (value != _Age)
            {
                _Age = value;
                OnPropertyChanged();
            }
        }
    }

    public event PropertyChangedEventHandler PropertyChanged;

    private void OnPropertyChanged([CallerMemberName]string propertyName = "")
    {
        if (this.PropertyChanged != null)
        {
            PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
        }
    }
}

正如您所看到的,我在过滤时会从ObservableCollection中删除该项目,这将根据上次过滤结果进行过滤。如果要根据所有项目进行过滤,可以使用以下代码:

public void Company_Filter(object sender, RoutedEventArgs e)
{
    peopleCollection.Clear();
    foreach (var person in peopleList)
    {
        if (person.Company == "AA")
            peopleCollection.Add(person);
    }
}

答案 1 :(得分:1)

通常是这样完成的:

ICollectionView dataView =
              CollectionViewSource.GetDefaultView(IncList.ItemsSource);
dataView.Filter = o =>
                {
                    EventData t = o as EventData;
                    return t.action == evGroup.action && t.objid == evGroup.objid;
                };
dataView.Refresh();

这种技术在 ListView 上进行过滤操作,而不是在 ItemSource 上进行,而且很方便:您只需像往常一样使用数据源(添加-删除元素),ListView 显示过滤后的当前视图。