ListView

ListView 继承自简单的没有特色的ListBox。增加了对基于列显示的支持,并增加了快速切换视图或显示模式的能力,而不需要重新绑定数据以及重新构建列表。

ListView类是一个特殊的列表类,它是专门针对显示相同数据的不同视图而设计的。如果要构建显示每个数据项几部分信息的多列视图,ListView 控件特别有用。ListView类继承自ListBox类,并使用 View 属性进行扩展。

GridView

GridView类继承自ViewBase类,表示具有多列的列表视图。通过GridVeiw.Columns 集合添加GridViewColumn 对象可定义这些列。


    
        
            
                
                
                
            
        
    

单元格模板

可以视图单元格模板 CellTemplate 属性来重写列,它与DataTemplate很相似,但是只能应用于一列数据。单元格模板并不局限于只能使用TextBlock属性,也可以使用其他元素,比如使用 转化器帮助从文件系统加载相应的图像文件。


    
        
            
                
                
                
                    
                        
                            
                        
                    
                
                
                    
                        
                            
                        
                    
                
            
        
    

创建自定义视图

如果GridView视图不能满足需要,可以创建自己的视图以扩展ListView 控件的功能。不过,这并不容易实现。

视图通过重写两个受保护的属性进行工作:DefaultStyleKey 和 ItemContainerDefaultStyleKey。这两个属性都返回名为 ResourceKey 的特殊对象,该对象指向在XAML中定义的样式。DefaultStyleKey 将被用于配置整个ListView控件的样式,而ItemContainerDefaultStyleKey 则将被用于配置ListView控件中的每个ListViewItem元素的样式。尽管这些样式可修改任意属性,但它们通常通过替换用于ListView 控件的ControlTemplate 以及用于每个ListViewItem元素的DataTemplate 进行工作。

视图类

这里除了ViewBase 所需的DefaultStyleKey 与 ItemContainerDefaultStyleKey 外,还另外定义了三个属性:ItemTemplate、SelectedBackground、SelectedBorderBrush,其中ItemTemplate用于使用时提供正确的数据模板,SelectedBackground与SelectedBorderBrush用于为视图传递额外信息,在视图样式中可以绑定到这两个属性来使用。

public class TileView : ViewBase
{
    private DataTemplate itemTemplate;
    public DataTemplate ItemTemplate
    {
        get { return itemTemplate; }
        set { itemTemplate = value; }
    }
    private Brush selectedBackground = Brushes.Transparent;
    public Brush SelectedBackground
    {
        get { return selectedBackground; }
        set { selectedBackground = value; }
    }
    private Brush selectedBorderBrush = Brushes.Black;
    public Brush SelectedBorderBrush
    {
        get { return selectedBorderBrush; }
        set { selectedBorderBrush = value; }
    }
    protected override object DefaultStyleKey
    {
        get { return new ComponentResourceKey(GetType(), "TileView"); }
    }

    protected override object ItemContainerDefaultStyleKey
    {
        get { return new ComponentResourceKey(GetType(), "TileViewItem"); }
    }
}

视图样式

视图样式需要放到资源文件,为了自动检索到,我们这里将其命名为Generic.xaml 并放到Themes文件夹下。视图样式中主要为 ListView 的 ItemsPanel 属性应用了 WrapPanel,将View.ItemTemplate 绑定到ListViewItem的 ContentTemplate属性上,同时应用了再视图里面定义的 SelectedBackground与SelectedBorderBrush 这两个属性。

Themes/Generic.xaml


    
    

创建视图

我们在窗口资源里面来创建视图,主要需要为视图类提供数据模板,如果有需要的话,也可以为在视图类里面定义的SelectedBackground与SelectedBorderBrush 这两个属性提供数据。


    
        
    
        
            
            
            
        
    
    
        
            
                
                    
                    
                
            
        
    
    
        
            
                
                    
                        
                        
                    
                    
                    
                        
                        
                        
                    
                
            
        
    

使用视图

使用视图比较简单,视图已经在窗口资源里面定义了,只需要绑定到ListView的View属性上即可。因为这里创建了多个视图,我们可以根据用户选择来使用不同的视图。




    
        
        
    
    Choose your view:
    
        NormalGridView
        ImageView
        ImageDetailView
    
private void ComboBox_SelectionChanged(object sender, SelectionChangedEventArgs e)
{
    ComboBoxItem selectedItem = (ComboBoxItem)((ComboBox)sender).SelectedItem;
    customListView.View = (ViewBase)this.FindResource(selectedItem.Content);
}

下面给出完整代码,Themes/Generic.xmal 在前面已经完整给出了,这里不再重复

MainWindow.xaml



    
        

        
            
                
                
                
                
            
        
        
            
                
                    
                        
                        
                    
                
            
        
        
            
                
                    
                        
                            
                            
                        
                        
                        
                            
                            
                            
                        
                    
                
            
        
    
    
    
        
            
            
        
        
            
            
            
        

        
            
                
                    
                        
                        
                        
                    
                
            
        

        
            
                
                    
                        
                        
                        
                            
                                
                                    
                                
                            
                        
                        
                            
                                
                                    
                                
                            
                        
                    
                
            
        

        

        
            
                
                
            
            Choose your view:
            
                GridView
                ImageView
                ImageDetailView
            
        
    

MainWindow.xaml.cs

using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.ComponentModel;
using System.IO;
using System.Linq;
using System.Runtime.CompilerServices;
using System.Text;
using System.Threading.Tasks;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Media;
using System.Windows.Media.Imaging;

namespace TestListView;


public class ViewModelBase : INotifyPropertyChanged
{
    public event PropertyChangedEventHandler? PropertyChanged;
    protected virtual void OnPropertyChanged([CallerMemberName] string? propertyName = null)
    {
        PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
    }
    protected virtual bool SetProperty(ref T member, T value, [CallerMemberName] string? propertyName = null)
    {
        if (EqualityComparer.Default.Equals(member, value))
        {
            return false;
        }
        member = value;
        OnPropertyChanged(propertyName);
        return true;
    }
}
public class Order : ViewModelBase
{
    public decimal price = 0;
    public decimal Price { get => price; set => SetProperty(ref price, value); }
    public int volume = 0;
    public int Volume { get => volume; set => SetProperty(ref volume, value); }

    public DateTime orderDate = DateTime.Now;
    public DateTime OrderDate { get => orderDate; set => SetProperty(ref orderDate, value); }

    public string image = string.Empty;
    public string Image { get => image; set => SetProperty(ref image, value); }
}
public class ImagePathConverter : IValueConverter
{
    private string imageDirectory = Directory.GetCurrentDirectory();
    public string ImageDirectory
    {
        get { return imageDirectory; }
        set { imageDirectory = value; }
    }
    public object Convert(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
    {
        string imagePath = Path.Combine(ImageDirectory, (string)value);
        return new BitmapImage(new Uri(imagePath));
    }
    public object ConvertBack(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
    {
        throw new NotSupportedException("The method or operation is not implemented.");
    }
}

public class TileView : ViewBase
{
    private DataTemplate itemTemplate;
    public DataTemplate ItemTemplate
    {
        get { return itemTemplate; }
        set { itemTemplate = value; }
    }
    private Brush selectedBackground = Brushes.Transparent;
    public Brush SelectedBackground
    {
        get { return selectedBackground; }
        set { selectedBackground = value; }
    }
    private Brush selectedBorderBrush = Brushes.Black;
    public Brush SelectedBorderBrush
    {
        get { return selectedBorderBrush; }
        set { selectedBorderBrush = value; }
    }
    protected override object DefaultStyleKey
    {
        get { return new ComponentResourceKey(GetType(), "TileView"); }
    }

    protected override object ItemContainerDefaultStyleKey
    {
        get { return new ComponentResourceKey(GetType(), "TileViewItem"); }
    }
}


public partial class MainWindow : Window
{
    public MainWindow()
    {
        InitializeComponent();

        myGrid.DataContext = this;

        InitOrder();
    }
    public ObservableCollection Orders { get; set; } = new();
    public void InitOrder()
    {
        Order order1 = new Order();
        Order order2 = new Order();
        Order order3 = new Order();
        Order order4 = new Order();

        order1.Price = 100;
        order1.Volume = 10;
        order1.Image = "image1.gif";

        order2.Price = 1000;
        order2.Volume = 100;
        order2.Image = "image2.gif";

        order3.Price = 10000;
        order3.Volume = 1000;
        order3.Image = "image3.gif";

        order4.Price = 100000;
        order4.Volume = 10000;
        order4.Image = "image4.gif";

        Orders.Add(order1);
        Orders.Add(order2);
        Orders.Add(order3);
        Orders.Add(order4);
    }

    private void ComboBox_SelectionChanged(object sender, SelectionChangedEventArgs e)
    {
        ComboBoxItem selectedItem = (ComboBoxItem)((ComboBox)sender).SelectedItem;
        customListView.View = (ViewBase)this.FindResource(selectedItem.Content);
    }
}

你可能感兴趣的:(紫云的程序人生,C#,WPF,wpf,ListView)