WPF:动态显示或隐藏Listview的某一列

      这几天做项目,需要做个listview满足能够动态显示或隐藏某些列,由于自己是菜鸟水平,查了两天资料也没有想出解决办法。就在我山穷水尽的时候看到了Mgen的一篇博客,给了我很大启发,所以我也决定把自己做的一些东西给大家说说,希望能帮助像我一样的菜鸟!

我读了Mgen的博文(http://www.cnblogs.com/mgen/archive/2011/07/24/2115458.html),给我很大启发,但也发现有些缺陷。我感觉的缺陷列举如下:

1、控制隐藏显示的逻辑关系有问题,搞不好会抛异常。

2、你设置管理控制显隐的控件只能是继承于itemcontrol的控件,有一定的局限性(比如说我想做一组button按钮,每个button控制一列话,它就不能用了)

下面,我贴出自己的代码,然后分析我是怎样解决这些问题的。

 1 <Window x:Class="mgen_autocolumns.MainWindow"
 2         xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
 3         xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
 4         xmlns:loc="clr-namespace:mgen_autocolumns"        
 5         Title="Mgen" Height="350" Width="525">
 6     <DockPanel>
 7         <!-- 已经有的ListView -->
 8         <ListView Name="list" DockPanel.Dock="Top" >
 9             <ListView.View>
10                 <GridView loc:GridViewUtility.ColumnObjectCollection="{Binding Path=ColumnCollection}">
11                     <GridViewColumn Header="姓名"
12                                 Width="100"
13                                 DisplayMemberBinding="{Binding Name}" />
14                     <GridViewColumn Header="年龄" 
15                                 Width="50"
16                                 DisplayMemberBinding="{Binding Age}" />
17                     <GridViewColumn Header="分数" 
18                                 Width="100">
19                         <GridViewColumn.CellTemplate>
20                             <DataTemplate>
21                                 <ProgressBar Width="80" Height="10" Maximum="100" Value="{Binding Score}" />
22                             </DataTemplate>
23                         </GridViewColumn.CellTemplate>
24                     </GridViewColumn>
25                 </GridView>
26             </ListView.View>
27         </ListView>
28 
29         <!-- 列管理代码 -->
30         <!-- loc命名空间是ColumnObject的CLR命名空间 -->
31         <ListBox  ItemsSource="{Binding Path=ColumnCollection.GViewAllCollection}">
32             <!--<ListBox.ItemContainerStyle>
33                 <Style TargetType="ListBoxItem">
34                     <Setter Property="Focusable" Value="False" />
35                 </Style>
36             </ListBox.ItemContainerStyle>-->
37             <ListBox.ItemTemplate>
38                 <DataTemplate>
39                     <CheckBox IsChecked="{Binding Path=IsVisable}" 
40                               Content="{Binding Path=Header}"
41                               Margin="2"/>
42                 </DataTemplate>
43             </ListBox.ItemTemplate>
44         </ListBox>
45     </DockPanel>
46 </Window>
XAML
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Windows;
using System.Windows.Controls;

namespace mgen_autocolumns
{
    public class GridViewUtility : GridView
    {
        #region 附加属性
        public static readonly DependencyProperty ColumnObjectCollectionProperty =
            DependencyProperty.RegisterAttached("ColumnObjectCollection", typeof(ColumnObjectCollections), typeof(GridView),
            new PropertyMetadata(GridViewUtility.OnColumnObjectCollectionChanged));

        static void OnColumnObjectCollectionChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
        {
            ColumnObjectCollections col = e.NewValue as ColumnObjectCollections;
            if (col != null)
            {
                col.GViewCollection = ((GridView)d).Columns;
                int index = 0;
                col.GViewAllCollection = new List<ColumnObject>();
                foreach (GridViewColumn gc in col.GViewCollection)
                {
                    col.GViewAllCollection.Add(new ColumnObject(index, true,gc, col));
                    index++;
                }

            }
            
        }

        public static ColumnObjectCollections GetColumnObjectCollection(GridView gridview)
        {
            return (ColumnObjectCollections)gridview.GetValue(ColumnObjectCollectionProperty);
        }

        public static void SetColumnObjectCollection(GridView gridew, ColumnObjectCollections collection)
        {
            gridew.SetValue(ColumnObjectCollectionProperty, collection);
        }


        #endregion      
    }
    public class ColumnObjectCollections
    {
        public GridViewColumnCollection GViewCollection
        {
            get;
            set;
        }
        public List<ColumnObject> GViewAllCollection
        {
            get;
            set;
        }
        public void SetColumnVisable(int index, bool isVisable)
        {
            if (index >= 0 && index < GViewAllCollection.Count)
            {
                GViewAllCollection[index].IsVisable = isVisable;
            }
        }

        public bool IsColumnVisable(int index)
        {
            if (index < 0 || index >= GViewAllCollection.Count)
            {
                return false;
            }
            return GViewAllCollection[index].IsVisable;
        }
    }
    public class ColumnObject
    {
        private int index;
        private ColumnObjectCollections col;
        private GridViewColumn column;
        private bool isVisable;
        public bool IsVisable
        {
            get
            {
                return isVisable;
            }
            set
            {
                isVisable = value;
                SetVisable(isVisable);
            }

        }
        public string Header
        {
            get
            {
                return this.column.Header.ToString();
            }
        }
        public ColumnObject(int index, bool isVisable,GridViewColumn column, ColumnObjectCollections col)
        {
            this.index = index;
            this.IsVisable = true;
            this.col = col;
            this.column = column;
        }
        private void SetVisable(bool isVisable)
        {
            if (isVisable)
            {
                if (!this.IsVisable)
                {
                    int index = this.index;
                    this.col.GViewAllCollection[index].isVisable = true;
                    for (int i = index + 1; i < this.col.GViewAllCollection.Count; i++)
                    {
                        if (this.col.GViewAllCollection[i].isVisable)
                        {
                            index = this.col.GViewAllCollection[i].index - 1;
                            break;
                        }
                    }
                    this.col.GViewCollection.Insert(index, this.column);
                }
            }
            else
            {
                this.col.GViewCollection.Remove(this.column);
            }
        }
    }
}
View Code
 1 using System;
 2 using System.Collections.Generic;
 3 using System.Linq;
 4 using System.Text;
 5 
 6 namespace mgen_autocolumns
 7 {
 8    public class Person
 9     {
10         public ColumnObjectCollections ColumnCollection
11         {
12             get;
13             set;
14         }
15         public Person()
16         {
17             ColumnCollection = new ColumnObjectCollections();
18         }
19         public Person(string name, int age, int score)
20         {
21             Name = name;
22             Age = age;
23             Score = score;
24         }
25         public string Name { get; set; }
26         public int Age { get; set; }
27         public int Score { get; set; }
28 
29         public static Person[] Get()
30         {
31             return new Person[]
32             {
33                 new Person("Zhang", 14, 91),
34                 new Person("Mgen",21,77),
35                 new Person("Lee",40,93),
36                 new Person("123",32,35),
37                 new Person("Gao",22,71),
38                 new Person("Sun",9,21),
39                 new Person("David",71,12)
40             };
41         }
42     }
43 }
Person Code
 1 using System;
 2 using System.Collections.Generic;
 3 using System.Linq;
 4 using System.Text;
 5 using System.Windows;
 6 using System.Windows.Controls;
 7 using System.Windows.Data;
 8 using System.Windows.Documents;
 9 using System.Windows.Input;
10 using System.Windows.Media;
11 using System.Windows.Media.Imaging;
12 using System.Windows.Navigation;
13 using System.Windows.Shapes;
14 
15 namespace mgen_autocolumns
16 {
17     /// <summary>
18     /// Interaction logic for MainWindow.xaml
19     /// </summary>
20     public partial class MainWindow : Window
21     {
22         public MainWindow()
23         {        
24             this.DataContext = new Person();
25             InitializeComponent();
26             list.ItemsSource = Person.Get();
27                                  
28         }
29        
30     }
31 }
MainWindow Code
原文地址:https://www.cnblogs.com/yongbufangqi1988/p/3429235.html