当把一些数据(多个)也就是集合或者其他比如DataTable绑定到ItemsControl控件时,数据视图就作为数据和前台控件的桥梁被创建出来了,这个桥梁可以做很多事情,比如可以实现导航控件,因为数据视图会记录当前的那个具体的数据,你可以移到上一个,也可以移到下一个,或者移到第一个,或者最后一个,当然还可以实现分组或者排序。
这样做有什么好处呢?比如,我们从数据库读出一些数据,前台可能会对这串数据做各种展示性的筛选排序等等,但是不影响数据库里面的原始数据,那么我们就可以利用数据视图,有几个好处,不需要频繁的去读取数据库,也不需要去维护读出来的数据,而且可以分离筛选的规则,直接在前端去完成。
下面的示例,就是一个人的类,有几个常见的字段,姓名,年龄,身高,性别,我放置了几个按钮,去实现排序,分类等等,基本上这是一个很好理解,也很好学习的一个部分。
首先是人的类别
public class Person
{
public int Age { get; set; }
public string Name { get; set; }
public double Height { get; set; }
public string gender { get; set; }
}
前台代码,没有做布局优化,凑合看,主要展示数据视图
<Window x:Class="WpfApplication1.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Title="MainWindow" Height="350" Width="525">
<Grid>
<StackPanel>
<StackPanel Orientation="Horizontal">
<ListBox IsSynchronizedWithCurrentItem="True" Name="pls" Width="200" DisplayMemberPath="Name">
<ListBox.GroupStyle>
<GroupStyle>
<GroupStyle.HeaderTemplate>
<DataTemplate>
<TextBlock Text="{Binding Path=Name}"></TextBlock>
</DataTemplate>
</GroupStyle.HeaderTemplate>
</GroupStyle>
</ListBox.GroupStyle>
</ListBox>
<StackPanel Margin="0,0,0,-0.333" Width="312" DataContext="{Binding ElementName=pls, Path=SelectedItem}">
<DockPanel>
<Label>姓名</Label>
<TextBox Text="{Binding Path=Name}"></TextBox>
</DockPanel>
<DockPanel>
<Label>年龄</Label>
<TextBox Text="{Binding Path=Age}"></TextBox>
</DockPanel>
<DockPanel>
<Label>身高</Label>
<TextBox Text="{Binding Path=Height}"></TextBox>
</DockPanel>
</StackPanel>
</StackPanel>
<StackPanel>
<Button Click="Button_Click">下一个</Button>
<TextBlock Name="CurrentSelected" HorizontalAlignment="Center">第N个</TextBlock>
<Button Click="Button_Click_1">上一个</Button>
<Button Click="Button_Click_3">回到第一个</Button>
<Button Click="Button_Click_2">回到最后一个</Button>
</StackPanel>
<Button Content="显示年龄大于20的人" Click="Button_Click_4"/>
<Button Content="按照年龄排序" Click="Button_Click_5"/>
<Button Content="按性别分类" Click="Button_Click_6"/>
</StackPanel>
</Grid>
</Window>
最后就是具体实现了,用到数据视图替我们封装的一系列方法,我把整个后台代码都复制放在下面了。
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Navigation;
using System.Windows.Shapes;
namespace WpfApplication1
{
/// <summary>
/// MainWindow.xaml 的交互逻辑
/// </summary>
public partial class MainWindow : Window
{
private ListCollectionView DataView;
public MainWindow()
{
InitializeComponent();
Person p1 = new Person();
p1.Name = "洪波";
p1.Age = 31;
p1.Height = 176.7;
p1.gender = "男";
Person p2 = new Person();
p2.Name = "洪西南";
p2.Age = 1;
p2.Height = 72.7;
p2.gender = "男";
Person p3 = new Person();
p3.Name = "汪海静";
p3.Age = 30;
p3.Height = 165.2;
p3.gender = "女";
List<Person> lp = new List<Person>();
lp.Add(p1);
lp.Add(p2);
lp.Add(p3);
pls.ItemsSource = lp;
DataView = (ListCollectionView)CollectionViewSource.GetDefaultView(pls.ItemsSource);
DataView.CurrentChanged += DataView_CurrentChanged;
}
void DataView_CurrentChanged(object sender, EventArgs e)
{
CurrentSelected.Text = "选中的是" + (DataView.CurrentPosition + 1).ToString();
}
private void Button_Click(object sender, RoutedEventArgs e)
{
DataView.MoveCurrentToNext();
}
private void Button_Click_1(object sender, RoutedEventArgs e)
{
DataView.MoveCurrentToPrevious();
}
private void Button_Click_2(object sender, RoutedEventArgs e)
{
DataView.MoveCurrentToLast();
}
private void Button_Click_3(object sender, RoutedEventArgs e)
{
DataView.MoveCurrentToFirst();
}
private void Button_Click_4(object sender, RoutedEventArgs e)
{
DataView.Filter = new Predicate<object>(filter);
}
private bool filter(object obj)
{
Person p = (Person)obj;
return p.Age > 20;
}
private void Button_Click_5(object sender, RoutedEventArgs e)
{
DataView.SortDescriptions.Add(new SortDescription("Age",ListSortDirection.Descending));
}
private void Button_Click_6(object sender, RoutedEventArgs e)
{
DataView.GroupDescriptions.Add(new PropertyGroupDescription("gender"));
}
}
}