WPF控件之ListView控件
紧接上一篇《WPF笔记汇总之列表类控件与DataGrid控件》,这篇主要总结WPF中最复杂的控件之一,ListView控件,它类似ListBox和DataGrid,它可以实现上面两个控件的功能,但自定义制定的方式更加自由。
1 ListView简单使用
默认的ListView实际上只是一个ListBox,具有不同的选择模式,ListViewItem派生自ContentControl类,所以可以指定WPF控件作为其内容。
<!--简单使用-->
<ListView Margin="10">
<ListViewItem>A ListView</ListViewItem>
<ListViewItem IsSelected="True">with several</ListViewItem>
<ListViewItem>items</ListViewItem>
</ListView>
<!--有图片的ListViewItem-->
<ListView Margin="10">
<ListViewItem>
<StackPanel Orientation="Horizontal">
<Image Source="/images/file.png" Margin="0,0,5,0" />
<TextBlock>Green</TextBlock>
</StackPanel>
</ListViewItem>
<ListViewItem>
<StackPanel Orientation="Horizontal">
<Image Source="/images/file.png" Margin="0,0,5,0" />
<TextBlock>Blue</TextBlock>
</StackPanel>
</ListViewItem>
<ListViewItem IsSelected="True">
<StackPanel Orientation="Horizontal">
<Image Source="/images/file.png" Margin="0,0,5,0" />
<TextBlock>Red</TextBlock>
</StackPanel>
</ListViewItem>
</ListView>
2 ListView数据绑定和ItemTemplate
<!--简单数据绑定-->
<ListView Margin="10" Name="lvDataBinding"></ListView>
<TextBlock></TextBlock>
<!--自定义模板-->
<ListView Margin="10" Name="lvDataBinding2">
<ListView.ItemTemplate>
<DataTemplate>
<WrapPanel>
<TextBlock Text="Name: " />
<TextBlock Text="{Binding Name}" FontWeight="Bold" />
<TextBlock Text=", " />
<TextBlock Text="Age: " />
<TextBlock Text="{Binding Age}" FontWeight="Bold" />
<TextBlock Text=" (" />
<TextBlock Text="{Binding Mail}" TextDecorations="Underline" Foreground="Blue" Cursor="Hand" />
<TextBlock Text=")" />
</WrapPanel>
</DataTemplate>
</ListView.ItemTemplate>
</ListView>
public MainWindow()
{
InitializeComponent();
List<User> items = new List<User>();
items.Add(new User() { Name = "John Doe", Age = 42, Mail = "john@doe-family.com" });
items.Add(new User() { Name = "Jane Doe", Age = 39, Mail = "jane@doe-family.com" });
items.Add(new User() { Name = "Sammy Doe", Age = 13, Mail = "sammy.doe@gmail.com" });
lvDataBinding.ItemsSource = items;
lvDataBinding2.ItemsSource = items;
}
public class User
{
public string Name { get; set; }
public int Age { get; set; }
public string Mail { get; set; }
public override string ToString()
{
return this.Name + ", " + this.Age + " years old";
}
}
3 GridView模板
WPF内置了一个专门的视图:GridView,通过使用GridView,您可以在ListView中展示多列数据。Header属性用于指定列显示的文本,DisplayMemberBinding属性将值绑定到自定义数据类的属性。此外指定CellTemplate属性,可以完全控制内容在特定列单元格中的呈现方式。
<!--GridView简单使用-->
<ListView Margin="10" Name="lvUsers">
<ListView.View>
<GridView>
<GridViewColumn Header="Name" Width="120" DisplayMemberBinding="{Binding Name}" />
<GridViewColumn Header="Age" Width="50" DisplayMemberBinding="{Binding Age}" />
<GridViewColumn Header="Mail" Width="150" DisplayMemberBinding="{Binding Mail}" />
</GridView>
</ListView.View>
</ListView>
<!--CellTemplate属性-->
<ListView Margin="10" Name="lvUsers2">
<ListView.View>
<GridView>
<GridViewColumn Header="Name" Width="120" DisplayMemberBinding="{Binding Name}" />
<GridViewColumn Header="Age" Width="50" DisplayMemberBinding="{Binding Age}" />
<GridViewColumn Header="Mail" Width="150">
<GridViewColumn.CellTemplate>
<DataTemplate>
<TextBlock Text="{Binding Mail}" TextDecorations="Underline" Foreground="Blue" Cursor="Hand" />
</DataTemplate>
</GridViewColumn.CellTemplate>
</GridViewColumn>
</GridView>
</ListView.View>
</ListView>
public MainWindow()
{
InitializeComponent();
List<User> items = new List<User>();
items.Add(new User() { Name = "John Doe", Age = 42, Mail = "john@doe-family.com" });
items.Add(new User() { Name = "Jane Doe", Age = 39, Mail = "jane@doe-family.com" });
items.Add(new User() { Name = "Sammy Doe", Age = 13, Mail = "sammy.doe@gmail.com" });
lvUsers.ItemsSource = items;
lvUsers2.ItemsSource = items;
}
public class User
{
public string Name { get; set; }
public int Age { get; set; }
public string Mail { get; set; }
}
4 数据对齐与分组展示
HorizontalAlignment属性负责设置对齐方式。默认为Center,可以将其更改为Left等。CollectionView包含许多可能性,包括对项目进行分组的功能。通过向视图的GroupDescriptions添加所谓的PropertyGroupDescription来实现分组。
<!--更改数据对齐方式-->
<ListView Margin="10" Name="lvUsers">
<ListView.Resources>
<Style TargetType="{x:Type GridViewColumnHeader}">
<Setter Property="HorizontalContentAlignment" Value="Left" />
</Style>
</ListView.Resources>
<ListView.View>
<GridView>
<GridViewColumn Header="Name" Width="120" DisplayMemberBinding="{Binding Name}" />
<GridViewColumn Header="Age" Width="50" DisplayMemberBinding="{Binding Age}" />
<GridViewColumn Header="Mail" Width="150" DisplayMemberBinding="{Binding Mail}" />
</GridView>
</ListView.View>
</ListView>
<!--分组展示-->
<ListView Name="lvUsers2">
<ListView.View>
<GridView>
<GridViewColumn Header="Name" Width="120" DisplayMemberBinding="{Binding Name}" />
<GridViewColumn Header="Age" Width="50" DisplayMemberBinding="{Binding Age}" />
</GridView>
</ListView.View>
<ListView.GroupStyle>
<GroupStyle>
<GroupStyle.HeaderTemplate>
<DataTemplate>
<TextBlock FontWeight="Bold" FontSize="14" Text="{Binding Name}"/>
</DataTemplate>
</GroupStyle.HeaderTemplate>
</GroupStyle>
</ListView.GroupStyle>
</ListView>
<TextBlock></TextBlock>
<!--折叠和扩展组-->
<ListView Name="lvUsers3">
<ListView.View>
<GridView>
<GridViewColumn Header="Name" Width="120" DisplayMemberBinding="{Binding Name}" />
<GridViewColumn Header="Age" Width="50" DisplayMemberBinding="{Binding Age}" />
</GridView>
</ListView.View>
<ListView.GroupStyle>
<GroupStyle>
<GroupStyle.ContainerStyle>
<Style TargetType="{x:Type GroupItem}">
<Setter Property="Template">
<Setter.Value>
<ControlTemplate>
<Expander IsExpanded="True">
<Expander.Header>
<StackPanel Orientation="Horizontal">
<TextBlock Text="{Binding Name}" FontWeight="Bold" Foreground="Gray" FontSize="18" VerticalAlignment="Bottom" />
<TextBlock Text="{Binding ItemCount}" FontSize="18" Foreground="Green" FontWeight="Bold" FontStyle="Italic" Margin="10,0,0,0" VerticalAlignment="Bottom" />
<TextBlock Text=" item(s)" FontSize="18" Foreground="Silver" FontStyle="Italic" VerticalAlignment="Bottom" />
</StackPanel>
</Expander.Header>
<ItemsPresenter />
</Expander>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
</GroupStyle.ContainerStyle>
</GroupStyle>
</ListView.GroupStyle>
</ListView>
public MainWindow()
{
InitializeComponent();
List<User> items = new List<User>();
items.Add(new User() { Name = "John Doe", Age = 42, Mail = "john@doe-family.com", Sex = SexType.Male });
items.Add(new User() { Name = "Jane Doe", Age = 39, Mail = "jane@doe-family.com", Sex = SexType.Female });
items.Add(new User() { Name = "Sammy Doe", Age = 13, Mail = "sammy.doe@gmail.com", Sex = SexType.Male });
lvUsers.ItemsSource = items;
lvUsers2.ItemsSource = items;
lvUsers3.ItemsSource = items;
CollectionView view = (CollectionView)CollectionViewSource.GetDefaultView(lvUsers2.ItemsSource);
PropertyGroupDescription groupDescription = new PropertyGroupDescription("Sex");
view.GroupDescriptions.Add(groupDescription);
}
public enum SexType { Male, Female };
public class User
{
public string Name { get; set; }
public int Age { get; set; }
public string Mail { get; set; }
public SexType Sex { get; set; }
}
5 排序与过滤
<TextBox DockPanel.Dock="Top" Margin="0,0,0,10" Name="txtFilter" TextChanged="txtFilter_TextChanged" />
<ListView Name="lvUsers">
<ListView.View>
<GridView>
<GridViewColumn Header="Name" Width="120" DisplayMemberBinding="{Binding Name}" />
<GridViewColumn Header="Age" Width="50" DisplayMemberBinding="{Binding Age}" />
</GridView>
</ListView.View>
</ListView>
public MainWindow()
{
InitializeComponent();
List<User> items = new List<User>();
items.Add(new User() { Name = "John Doe", Age = 42, Mail = "john@doe-family.com", Sex = SexType.Male });
items.Add(new User() { Name = "Jane Doe", Age = 39, Mail = "jane@doe-family.com", Sex = SexType.Female });
items.Add(new User() { Name = "Sammy Doe", Age = 13, Mail = "sammy.doe@gmail.com", Sex = SexType.Male });
items.Add(new User() { Name = "Mike", Age = 13, Mail = "mike.doe@gmail.com", Sex = SexType.Male });
lvUsers.ItemsSource = items;
// 先使用年龄进行排序,当年龄相同时,使用名称排序。
CollectionView view = (CollectionView)CollectionViewSource.GetDefaultView(lvUsers.ItemsSource);
view.SortDescriptions.Add(new SortDescription("Age", ListSortDirection.Ascending));
view.SortDescriptions.Add(new SortDescription("Name", ListSortDirection.Ascending));
// 过滤
view.Filter = UserFilter;
}
private bool UserFilter(object item)
{
if (String.IsNullOrEmpty(txtFilter.Text))
return true;
else
return ((item as User).Name.IndexOf(txtFilter.Text, StringComparison.OrdinalIgnoreCase) >= 0);
}
private void txtFilter_TextChanged(object sender, System.Windows.Controls.TextChangedEventArgs e)
{
CollectionViewSource.GetDefaultView(lvUsers.ItemsSource).Refresh();
}
public enum SexType { Male, Female };
public class User
{
public string Name { get; set; }
public int Age { get; set; }
public string Mail { get; set; }
public SexType Sex { get; set; }
}