七月 10, 2008

[WPF] ListView 中 View 的模板替换(添加/删除列)

Written by

=====================================================

今天在网上闲逛,突然发现这边文章竟然被人毫不尊重原作者权益而胡乱转载,让人气愤!

本人欢迎转载,但是做人要厚道,转载要留名!

                                         2008.9.24 

 本文原作者:YuanHui

联系方式:khler@163.com

原文地址:http://www.cnblogs.com/khler/archive/2008/07/10/1239862.html

=====================================================

    在WPF中使用ListView,往往需要根据情况隐藏或显示ListView的某一列,我们当然可以通过代码来对付它(利用VisualTreeHelper.GetChild(listView)来得到某一个Column,然后隐藏它),但是,既然使用了WPF,我们就要入乡随俗,使用模板来处理。其实模板是个好东西,他提供了非常便利的定制机制,你可以把任意可视元素定义的面目全非——当然如果你愿意
    为了增减ListView的Column,我们只需定义多个GridView资源,在运行时根据不同情况使用不同资源,就可以达到增减Column的目的。这里其实都算不上是真正的模板替换。
    本文附带源代码可以在这里下载到:TestListViewColumnCustom.rar
    下面就开始吧!
    老规矩,拖出VS2008,Create new project->WPF Application,名字就叫

TestListViewColumnCustom吧,我一贯以“Test”开头命名工程,这样表明这是一个测试项目,是对ListViewColumnCustom所做的测试工程。点击OK后进入Window1.xaml设计界面,拽一个ListView进主窗口(听说通过敲Xaml代码来创建控件而不是通过“拽”来创建控件的人都是牛人,所以我喜欢敲代码;当然了,在WPF设计器不成熟的早期阶段,很多控件定制后显示不正常,你不敲代码还能去敲微软?),添加几个Column,并为窗口添加几个Label、CheckBox,运行结果如下:


图1 界面

Xaml代码如下:

<Window x:Class=”TestListViewColumnCustom.Window1″
    xmlns
=”http://schemas.microsoft.com/winfx/2006/xaml/presentation”
    xmlns:x
=”http://schemas.microsoft.com/winfx/2006/xaml”
    Title
=”Window1″ Height=”300″ Width=”300″>
        
    
<Grid>
        
<Grid.RowDefinitions>
            
<RowDefinition Height=”42″/>
            
<RowDefinition Height=”32″/>
            
<RowDefinition/>
            
<RowDefinition Height=”60″/>
        
</Grid.RowDefinitions>
        
<Label Margin=”5″ Grid.Row=”0″ Grid.Column=”0″ HorizontalAlignment=”Center” VerticalAlignment=”Center” FontSize=”18″ Foreground=”Maroon”>List View Column Custom</Label>
        
<CheckBox Margin=”5″ Grid.Row=”1″ Grid.Column=”0″ Click=”CheckBox_Click” VerticalAlignment=”Center”>Hide Last Column</CheckBox>
        
<ListView Name=”listView1″ Margin=”5″ Grid.Row=”2″ Grid.Column=”0″>
            
<ListView.View>
                
<GridView>
                    
<GridViewColumn Header=”Name”></GridViewColumn>
                    
<GridViewColumn Header=”A” Width=”60″></GridViewColumn>
                    
<GridViewColumn Header=”B” Width=”60″></GridViewColumn>
                    
<GridViewColumn Header=”WillBeHiden”></GridViewColumn>
                
</GridView>
            
</ListView.View>
        
</ListView>
        
<StackPanel Margin=”5″ Grid.Row=”3″ Grid.Column=”0″>
            
<Label Foreground=”Maroon”>Author:He,YuanHui</Label>
            
<Label Foreground=”Maroon”>Date:  2008.7.10</Label>
        
</StackPanel>
    
</Grid>
</Window>

给ListView添加两个(任意多个)GridView资源,拥有不同的Columns:


    
<Window.Resources>
        
<GridView x:Key=”haveHidnColumn”>
            
<GridViewColumn Header=”Name”></GridViewColumn>
            
<GridViewColumn Header=”A” Width=”60″></GridViewColumn>
            
<GridViewColumn Header=”B” Width=”60″></GridViewColumn>
            
<GridViewColumn Header=”WillBeHiden”></GridViewColumn>
        
</GridView>
        
<GridView x:Key=”haveNoHidnColumn”>
            
<GridViewColumn Header=”Name”></GridViewColumn>
            
<GridViewColumn Header=”A” Width=”60″></GridViewColumn>
            
<GridViewColumn Header=”B” Width=”60″></GridViewColumn>
        
</GridView>
    
</Window.Resources>

为CheckBox添加Click处理事件:

        private void CheckBox_Click(object sender, RoutedEventArgs e)
        
{
            
// select different template
            CheckBox checkBox = sender as CheckBox;
            
if (checkBox.IsChecked == true)
            
{
                
this.listView1.View = this.Resources[haveNoHidnColumnas GridView;
            }

            
else
            
{
                
this.listView1.View = this.Resources[haveHidnColumnas GridView;
            }


            
// rebinding data
            this.listView1.ItemsSource = null;
            
this.listView1.ItemsSource = dataList;
        }

运行,点击CheckBox,可以发现最后一列可以动态“删除”:

图2 WillBeHiden列将被删除

勾选CheckBox:

图3 WillBeHiden列被删除

为了显得更加真实,上面绑定了数据:

        public Window1()
        
{
            InitializeComponent();

            
// init data
            for (int i = 0; i < 5; i++)
            
{
                dataList.Add(
new Data());
                dataList[i].Name 
= data + (i + 1).ToString();
                dataList[i].A 
= 1.0 + i / 10.0;
                dataList[i].B 
= 2.0 + i / 10.0;
            }


            
this.listView1.ItemsSource = dataList;
        }

简单总结一下:思想就是,在资源中定义具有不同Column的资源,根据程序需要,为ListView绑定不同GridView,达到动态修改ListView的列的目的。

注意,由于数据绑定的关系,替换模板后需要重新绑定一下数据:

            // rebinding data
            this.listView1.ItemsSource = null;
            
this.listView1.ItemsSource = dataList;

 

Category : WPF

Tags :

发表评论

电子邮件地址不会被公开。

Proudly powered by WordPress and Sweet Tech Theme