我的应用程序显示了一个ListView,它使用数据绑定来显示多个项目的列表。一些变量使用TwoWay绑定,因此更改保存在viewmodel实例中,即datacontext。这是我的#34;主要" viewmodel的实例,因为它包含所有项目。
现在我要过滤此列表(包含所有项目)并仅显示部分项目。在过去,我在后面的代码中创建了一个viewmodel的新实例,并将我想要显示的所有项目从我的主实例复制到新创建的viewmodel实例,然后将这个新的viewmodel设置为DataContext。
这很好用,但是当我更改Data时,它只会保存到新创建的实例而不是主实例。因此,当我更改过滤器时,将再次从主实例加载项目而不进行任何更改。
有没有办法过滤我的视图模型的主要实例?我想在主实例上工作,以便自动保存更改。
ViewModel包含我自己的类的ObservableCollection,我想只显示一些根据过滤器绑定的项目。
答案 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 显示过滤后的当前视图。