珂珂的个人博客 - 一个程序猿的个人网站

WPF ListView的用法

先上图,右边的就是ListView,为什么没用GridView ..因为我还要显示图标形式,暂时没有找GridView如何显示图标形式应该也可以实现。

ListView是继承自ListBox, 其实有时候WPF并不比Winform简单。



图标暂时无视...先随便找的一张图片


 关于列头排序,简单的就是在ListView中加入事件 GridViewColumnHeader.Click="GridViewColumnHeaderClickedHandler",用tag记录下来当前的顺序,不过列头没有小箭头可以想办法实现。

 private void Sort(ListView lv, string sortBy, ListSortDirection direction)
        {

            ICollectionView dataView = CollectionViewSource.GetDefaultView(lv.ItemsSource);//获取数据源视图
            dataView.SortDescriptions.Clear();//清空默认排序描述
            SortDescription sd = new SortDescription(sortBy, direction);
            dataView.SortDescriptions.Add(sd);//加入新的排序描述
            dataView.Refresh();//刷新视图
        }

        private void GridViewColumnHeaderClickedHandler(object sender, RoutedEventArgs e)
        {
            GridViewColumnHeader gch = e.OriginalSource as GridViewColumnHeader;
            ListSortDirection direction = ListSortDirection.Descending;
            if (gch.Tag == null)
            {
                gch.Tag = "asc";
            }

            if (gch.Tag.ToString() == "asc")
            {
                direction = ListSortDirection.Descending;
                gch.Tag = "desc";
            }
            else if (gch.Tag.ToString() == "desc")
            {
                direction = ListSortDirection.Ascending;
                gch.Tag = "asc";
            }

            Sort(this.listView1, "Name", direction);
        }


另外种方法是网上找的自定义附加属性

ListView 显示不同的视图是通过设置其View属性的,它是一个ViewBase,这个类是抽象类需要自己实现。在切换视图的时候需要先将ListView原来的ItemsPanel 记录下来,如果不这样做将图标形式切换到列表信息的时候就会有问题。

切换视图的代码

 /// <summary>
        /// 切换视图
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="args"></param>
        void SwitchViewMenu(object sender, RoutedEventArgs args)
        {
            MenuItem mi = (MenuItem)sender;

            if (mi.Header.ToString() == "详细信息")
            {
                listView1.View = listView1.FindResource("gridView") as ViewBase;
                listView1.ItemsPanel = gridItemsPanelTemplate;
                detailMenu.IsChecked = true;
                iconMenu.IsChecked = false;
            }
            else if (mi.Header.ToString() == "图标")
            {
                listView1.View = listView1.FindResource("iconView") as ViewBase;
                (listView1 as ListBox).ItemTemplate = listView1.FindResource("iconTemplate") as DataTemplate;
                listView1.ItemsPanel = listView1.FindResource("iconItemsPanelTemplate") as ItemsPanelTemplate;
                detailMenu.IsChecked = false;
                iconMenu.IsChecked = true;
            }
        }


完整的XAML代码

<Window x:Class="FYJ.Tools.Cloud.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
        xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
        xmlns:c="clr-namespace:FYJ.Windows.Controls;assembly=FYJ.Windows.Controls"
        xmlns:local="clr-namespace:FYJ.Tools.Cloud"
        xmlns:ext="clr-namespace:FYJ.Windows.Controls.Extention;assembly=FYJ.Windows.Controls"
        mc:Ignorable="d"
        Title="云存储工具" Height="350" Width="1000">

    <Window.Resources>

        <GridView x:Key="gridView">
            <GridViewColumn Header="名称" Width="300" CellTemplate="{Binding ID}" DisplayMemberBinding="{Binding Name}" ext:ListViewBehavior.SortField="Name"></GridViewColumn>
            <GridViewColumn Header="修改日期" Width="130" DisplayMemberBinding="{Binding LastModifiedDatetimeString}" ></GridViewColumn>
            <GridViewColumn Header="大小" Width="100"   DisplayMemberBinding="{Binding SizeString}"></GridViewColumn>
            <GridViewColumn Header="MD5" Width="100"  DisplayMemberBinding="{Binding MD5}"></GridViewColumn>
            <GridViewColumn Header="SHA1" Width="100"  DisplayMemberBinding="{Binding SHA1}"></GridViewColumn>
        </GridView>

        <local:ImageConvert x:Key="iconConvert"></local:ImageConvert>
        
        <DataTemplate x:Key="iconTemplate">
            <DockPanel>
                <Image Width="48" Height="48" DockPanel.Dock="Top" Source="{Binding Path=Icon,Converter={StaticResource iconConvert}}" Margin="2"/>
                <TextBlock  Text="{Binding Name}" 
                     FontSize="13" HorizontalAlignment="Center" 
                     Margin="0,5,0,0" />
            </DockPanel>
        </DataTemplate>

        <ItemsPanelTemplate x:Key="iconItemsPanelTemplate">
            <!--<VirtualizingStackPanel Orientation="Horizontal"/>-->
            <WrapPanel 
                Width="{Binding (FrameworkElement.ActualWidth), RelativeSource={RelativeSource  AncestorType=ScrollContentPresenter}}"
                ItemWidth="{Binding (ListView.View).ItemWidth, RelativeSource={RelativeSource AncestorType=ListView}}"
                ItemHeight="{Binding (ListView.View).ItemHeight,RelativeSource={RelativeSource AncestorType=ListView}}">
            </WrapPanel>
        </ItemsPanelTemplate>

        <local:PlainView x:Key="iconView"  ItemWidth="100"  ItemHeight="100" ItemTemplate="{StaticResource iconTemplate}">

        </local:PlainView>
    </Window.Resources>
    
    <DockPanel>
        <StackPanel DockPanel.Dock="Top" Height="40">
            <WrapPanel>
                <Button Content="上传" x:Name="btnUpload" Click="btnUpload_Click"></Button>
            </WrapPanel>
        </StackPanel>
        <StackPanel DockPanel.Dock="Top"  Margin="0,5,0,10">
            <Grid>
                <Grid.ColumnDefinitions>
                    <ColumnDefinition Width="60"></ColumnDefinition>
                    <ColumnDefinition Width="*"></ColumnDefinition>
                    <ColumnDefinition Width="40"></ColumnDefinition>
                </Grid.ColumnDefinitions>

                <TextBlock Text="当前路径:" Grid.Column="0"></TextBlock>
                <TextBox Text="" Margin="5,0,0,0" Grid.Column="1" x:Name="txtCurrentKey"></TextBox>
                <Button Content="go" Margin="5,0,0,0" Grid.Column="2"></Button>
            </Grid>
        </StackPanel>


        <StackPanel DockPanel.Dock="Bottom">
            <StackPanel>
                <c:LogListBox Margin="0,10,0,10" x:Name="listBox1" DockPanel.Dock="Bottom" Height="80"></c:LogListBox>
            </StackPanel>
            <c:TextBlockEx Text="就绪" x:Name="txtStatus"></c:TextBlockEx>
        </StackPanel>

        <Grid>
            <Grid.ColumnDefinitions>
                <ColumnDefinition Width="250"></ColumnDefinition>
                <ColumnDefinition Width="*"></ColumnDefinition>
            </Grid.ColumnDefinitions>
            <c:CustomTreeView Grid.Column="0" x:Name="objectTree"/>

            <GridSplitter x:Name="gridSplitter"  VerticalAlignment="Stretch"  Background="#FF0992F1" Width="1" >
            </GridSplitter>
            <ListView Grid.Column="1" x:Name="listView1" ext:ListViewBehavior.HeaderSort="True" GridViewColumnHeader.Click="GridViewColumnHeaderClickedHandler" SelectionChanged="listView1_SelectionChanged">
                <ListView.ContextMenu>
                    <ContextMenu>
                        <MenuItem Header="打开"></MenuItem>
                        <MenuItem Header="查看">
                            <MenuItem Header="详细信息"  Click="SwitchViewMenu" IsChecked="True" x:Name="detailMenu"/>
                            <MenuItem Header="图标" Click="SwitchViewMenu" x:Name="iconMenu"/>
                        </MenuItem>

                        <MenuItem Header="排序方式">
                            <MenuItem Header="名称"  Click="SortViewMenu" x:Name="sortNameMenu" />
                            <MenuItem Header="修改日期"  Click="SortViewMenu"  x:Name="sortDateMenu" />
                            <MenuItem Header="大小" Click="SortViewMenu" x:Name="sortSizeMenu"/>
                        </MenuItem>
                        
                        <MenuItem Header="刷新"></MenuItem>
                        <MenuItem Header="上传"></MenuItem>
                        <MenuItem Header="下载"></MenuItem>
                        <MenuItem Header="删除"></MenuItem>
                        <MenuItem Header="上一级"></MenuItem>
                    </ContextMenu>
                </ListView.ContextMenu>

            </ListView>
        </Grid>
    </DockPanel>

   
</Window>


后台代码

using FYJ.Windows.Controls;
using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.ComponentModel;
using System.Linq;
using System.Text;
using System.Threading;
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 FYJ.Tools.Cloud
{
    /// <summary>
    /// MainWindow.xaml 的交互逻辑
    /// </summary>
    public partial class MainWindow : Window
    {
        public MainWindow()
        {
            InitializeComponent();
            objectTree.CheckboxVisibility = Visibility.Collapsed;
            objectTree.SelectedItemChanged += ObjectTree_SelectedItemChanged;

            listView1.View = listView1.FindResource("gridView") as ViewBase;
        }

        ItemsPanelTemplate gridItemsPanelTemplate;
        private void ObjectTree_SelectedItemChanged(object sender, RoutedPropertyChangedEventArgs<object> e)
        {
            TreeModel currentNode = e.NewValue as TreeModel;
            if (currentNode != null)
            {
                List<StoreModel> list = new List<StoreModel>();
                foreach (var item in currentNode.Children)
                {
                    StoreModel model = item.Tag as StoreModel;
                    if (!model.IsDirectory)
                    {
                        model.Icon = "images/cat.png";
                    }

                    if (model != null)
                    {
                        list.Add(model);
                    }
                }
                this.listView1.ItemsSource = list;
                if (!(this.listView1.View is PlainView))
                {
                    gridItemsPanelTemplate = this.listView1.ItemsPanel;
                }

                this.txtCurrentKey.Text = currentNode.Id;
            }
        }

        private async void GetChildren2(TreeModel node, IList<TreeModel> list)
        {
            string icon = node.Icon;
            node.Icon = "/FYJ.Windows.Controls;component/Images/16_16/loading.gif";

            //await this.Dispatcher.BeginInvoke((Action)(() =>
            //{
            txtStatus.Text = "正在加载...";
            // }));

            IStore store = new AliyunStore();

            IList<StoreModel> models = new List<StoreModel>();
            await Task.Factory.StartNew(() =>
            {
                StoreModel model = node.Tag as StoreModel;
                if (model != null)
                {
                    models = store.ListObject(model.Bucket, model.Key);
                }
            });

            //await Task.Factory.StartNew(() =>
            //{
            //    //测试
            //    Thread.Sleep(1000);
            //});

            foreach (StoreModel model in models)
            {
                TreeModel childnode = new TreeModel();
                childnode.Id = model.ID;
                childnode.Name = model.Name;
                childnode.Icon = model.Icon;
                childnode.IsExpanded = false;
                if (model.IsDirectory)
                {
                    childnode.GetChildren = GetChildren;
                    childnode.Icon = "/FYJ.Windows.Controls;component/Images/16_16/folder.png";
                }
                else
                {
                    childnode.Icon = "/FYJ.Windows.Controls;component/Images/16_16/file.png";
                }
                childnode.Tag = model;
                childnode.IsExpanded = false;
                childnode.IsShowCheckbox = false;

                list.Add(childnode);
            }

            node.Icon = icon;
            txtStatus.Text = "就绪";
        }


        private IList<TreeModel> GetChildren(TreeModel node)
        {
            ObservableCollection<TreeModel> list = new ObservableCollection<TreeModel>();
            GetChildren2(node, list);

            return list;
        }


        private async void btnUpload_Click(object sender, RoutedEventArgs e)
        {
            txtStatus.Text = "正在加载buckets...";

            ObservableCollection<TreeModel> rootTreeList = new ObservableCollection<TreeModel>();

            IStore store = new AliyunStore();
            IList<string> buckets = store.ListBucket();

            await Task.Factory.StartNew(() =>
            {
                buckets = store.ListBucket();
            });

            if (buckets.Count == 0)
            {
                txtStatus.Text = "就绪";
                return;
            }

            foreach (string bucket in buckets)
            {
                IList<StoreModel> models = new List<StoreModel>();
                await Task.Factory.StartNew(() =>
                {
                    models = store.ListObject(bucket, "");
                });

                foreach (StoreModel model in models)
                {
                    TreeModel node = new TreeModel();
                    node.Id = model.ID;
                    node.Name = model.Name;
                    node.IsExpanded = false;
                    if (model.IsDirectory)
                    {
                        node.GetChildren = GetChildren;
                        node.Icon = "/FYJ.Windows.Controls;component/Images/16_16/folder.png";
                    }
                    else
                    {
                        node.Icon = "/FYJ.Windows.Controls;component/Images/16_16/file.png";
                    }

                    node.Tag = model;

                    rootTreeList.Add(node);
                }
            }

            this.objectTree.ItemsSourceData = rootTreeList;

            objectTree.CheckboxVisibility = Visibility.Collapsed;
        }

        /// <summary>
        /// 切换视图
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="args"></param>
        void SwitchViewMenu(object sender, RoutedEventArgs args)
        {
            MenuItem mi = (MenuItem)sender;

            if (mi.Header.ToString() == "详细信息")
            {
                listView1.View = listView1.FindResource("gridView") as ViewBase;
                listView1.ItemsPanel = gridItemsPanelTemplate;
                detailMenu.IsChecked = true;
                iconMenu.IsChecked = false;
            }
            else if (mi.Header.ToString() == "图标")
            {
                listView1.View = listView1.FindResource("iconView") as ViewBase;
                (listView1 as ListBox).ItemTemplate = listView1.FindResource("iconTemplate") as DataTemplate;
                listView1.ItemsPanel = listView1.FindResource("iconItemsPanelTemplate") as ItemsPanelTemplate;
                detailMenu.IsChecked = false;
                iconMenu.IsChecked = true;
            }
        }


        private void Sort(ListView lv, string sortBy, ListSortDirection direction)
        {

            ICollectionView dataView = CollectionViewSource.GetDefaultView(lv.ItemsSource);//获取数据源视图
            dataView.SortDescriptions.Clear();//清空默认排序描述
            SortDescription sd = new SortDescription(sortBy, direction);
            dataView.SortDescriptions.Add(sd);//加入新的排序描述
            dataView.Refresh();//刷新视图
        }

        private void GridViewColumnHeaderClickedHandler(object sender, RoutedEventArgs e)
        {
            //GridViewColumnHeader gch = e.OriginalSource as GridViewColumnHeader;
            //ListSortDirection direction = ListSortDirection.Descending;
            //if (gch.Tag == null)
            //{
            //    gch.Tag = "asc";
            //}

            //if (gch.Tag.ToString() == "asc")
            //{
            //    direction = ListSortDirection.Descending;
            //    gch.Tag = "desc";
            //}
            //else if (gch.Tag.ToString() == "desc")
            //{
            //    direction = ListSortDirection.Ascending;
            //    gch.Tag = "asc";
            //}

            //Sort(this.listView1, "Name", direction);
        }


        void SortViewMenu(object sender, RoutedEventArgs args)
        {
            MenuItem mi = (MenuItem)sender;

            ListSortDirection direction = ListSortDirection.Descending;
            if (mi.Tag == null)
            {
                mi.Tag = "asc";
            }

            if (mi.Tag.ToString() == "asc")
            {
                direction = ListSortDirection.Descending;
                mi.Tag = "desc";
            }
            else if (mi.Tag.ToString() == "desc")
            {
                direction = ListSortDirection.Ascending;
                mi.Tag = "asc";
            }

            if (mi.Header.ToString() == "名称")
            {
                sortNameMenu.IsChecked = true;
                sortDateMenu.IsChecked = false;
                sortSizeMenu.IsChecked = false;
                Sort(this.listView1, "Name", direction);
            }
            else if (mi.Header.ToString() == "修改日期")
            {
                sortNameMenu.IsChecked = false;
                sortDateMenu.IsChecked = true;
                sortSizeMenu.IsChecked = false;
                Sort(this.listView1, "LastModifiedDatetimeString", direction);
            }
            else if (mi.Header.ToString() == "大小")
            {
                sortNameMenu.IsChecked = false;
                sortDateMenu.IsChecked = false;
                sortSizeMenu.IsChecked = true;
                Sort(this.listView1, "Size", direction);
            }
        }

        private void listView1_SelectionChanged(object sender, SelectionChangedEventArgs e)
        {
            long size = 0;
            foreach(var item in this.listView1.SelectedItems)
            {
                StoreModel model = item as StoreModel;
                if(model!=null)
                {
                    size += model.Size;
                }
            }
            string str = this.listView1.Items.Count+"个项目 选中"+ this.listView1.SelectedItems.Count+" 共"+new SizeConvert().SizeToString(size);
            this.txtStatus.Text = str;
        }
    }
}

有一部分是TreeView 的。


上一篇:多线程域名查询工具

下一篇:个人代码全部开源


0 评论

查看所有评论

给个评论吧