在使用WPF进行应用程序的开发时,经常会为DataGrid生成行号,这里主要介绍一下生成行号的方法。通常有三种方法,这里主要介绍其中的两种,另一种简单提一下。

1. 直接在LoadingRow事件中操作。

这种方式是在code behind文件中操作。即相应的*.xaml.cs文件。

代码如下:


this.dataGridSoftware.LoadingRow += new EventHandler<DataGridRowEventArgs>(this.DataGridSoftware_LoadingRow);     

// ...

private void DataGridSoftware_LoadingRow(object sender, DataGridRowEventArgs e)
{
    e.Row.Header = e.Row.GetIndex() + 1;
}

这种方式最为简洁,也最容易理解。

但现在很多应用程序的开发都采用了MVVM(Model-View-ModelView)的开发模式。这种模式通常为了更好的解耦,所以通常不会在code behind文件中加入代码,为了在这种方式下实现上面的自动生成行号的操作,可以采用下面要讲到第二种方法。但我个人认为,不能太死板的使用MVVM,对于生成行号这种需求,不是业务逻辑的范畴,而是view的范畴,所以放到code behind文件中也可以。

2. 正如在第一种方法末尾提到的,为了适应MVVM的开发模式,不希望把自动生成行号的操作放到code behind文件中去实现,而也是想放到viewmodel中去实现。这时候可以使用为事件绑定command的方法,具体做法见下面代码:

在设计页面中引入下面命名空间,该dll在安装blend后会存在,目录为C:\Program Files\Microsoft SDKs\Expression\Blend\.NETFramework\v4.0\Libraries,如果没有,自己可以到网上下载。

xmlns:i="clr-namespace:System.Windows.Interactivity;assembly=System.Windows.Interactivity"  

为DataGrid设置EventTrigger, CommandParameter绑定datagrid本身,也就是将该datagrid作为command的参数。


<DataGrid x:Name="dataGridAllUsers" ...>
    <i:Interaction.Triggers>                                        
        <i:EventTrigger EventName="Loaded">
            <i:InvokeCommandAction Command="{Binding Path=DatagridLoadedCommand}"
                                   CommandParameter="{Binding ElementName=dataGridAllUsers}">                            
            </i:InvokeCommandAction>
        </i:EventTrigger>
     </i:Interaction.Triggers>
</DataGrid>

ViewModel中的代码,DatagridLoadedCommand的实现:


private ICommand datagridLoadedCommand;

public ICommand DatagridLoadedCommand
        {
            get
            {
                if (this.datagridLoadedCommand == null)
                {
                    this.datagridLoadedCommand = new RelayCommand(
                        param =>
                        {
                            //// Get the passed dataGrid.
                            System.Windows.Controls.DataGrid dataGrid = (System.Windows.Controls.DataGrid)param;                             //// After loaded, change all the row header to asending number.
                            foreach (var v in dataGrid.Items)
                            {
                                System.Windows.Controls.DataGridRow dgr = (System.Windows.Controls.DataGridRow)dataGrid.ItemContainerGenerator.ContainerFromItem(v);
                                if (dgr != null)
                                {
                                    dgr.Header = dgr.GetIndex() + 1;
                                }
                                else
                                {
                                    //// At this point, the v is not loaded into the DataGrid, so it will be null
                                    //// Once you scroll the datagrid, it begins loading, and it will trigger the LoadingRow event
                                    //// As we registered in following code lines, the line number will generated automatically.
                                    break;
                                }
                            }                             //// Rgister the LoadingRow event.
                            dataGrid.LoadingRow += (sender, e) => { e.Row.Header = e.Row.GetIndex() + 1; };
                        });
                }                 return this.datagridLoadedCommand;
            }
        }

由于是Loaded事件之后才注册LoadingRow事件,所以一开始加载的数据并没有行号。所以想着是不是绑定其他的事件比较好呢,也没有找到。如果你找到,欢迎分享。为了在加载好DataGrid之后显示行号,需要循环datagrid的所有行,然后修改DataGridRow.Header属性,这就是Command中那个foreach语句的作用。还有一点要注意的是,假如datagrid有很多数据,在可视范围内没有显示完全(有滚动条),datagrid只加载可视范围内的数据(items),其他数据在拖动滚动条要查看时才加载,但其Items集合属性包含了所有item,所以foreach里面多了个if语句来判断,如果取到的DataGridRow为空时,说明可视范围内的行号已更新完毕,这时可以终止循环,注册LoadingRow事件即可。当其他items加载的时候就会自动触发该事件改变行号了。

虽然这种方式可以实现自动生成行号的功能,但给人感觉也不爽,毕竟还是在ViewModel中操作具体控件的。

3. 第三种方法是在为DataGrid生成数据源时,在集合中加一index列。在数据源变更时也更新这一列,这种方式我没试,觉得更麻烦。

最后,你可能会想,如果在第二种方法中,如果能够把LoadingRow事件的参数作为command的参数,那么viewmodel中的command的实现就可以像第一种方法中一样简单了。下面有一篇关于MVVM中实现Command绑定获取事件参数EventArgs的做法,可以参考:http://blog.csdn.net/qing2005/article/details/6680047

WPF DataGrid自动生成行号的更多相关文章

  1. WPF DataGrid 自动生成行号的方法(通过修改RowHeaderTemplate的方式)

    WPF中的DataGrid自动生成行号的方法有很多,这里记录了一种通过修改 RowHeaderTemplate的方式来生成行号: 方法一: xaml界面: <Window ... xmlns:l ...

  2. WPF DataGrid 绑定DataSet数据 自动生成行号

    1.绑定数据:dataGrid1.ItemsSource = dataSet.Tables[0].DefaultView; 注意:在创建DataGrid 时可以通过AutoGenerateColumn ...

  3. Dev的GridView中如何自动生成行号

    这里提供一个方法,使用简单,只需将GridView传入,即可自动生成行号 public static void SetRowNumberIndicator(GridView gridView) { g ...

  4. 用ClientDataSet更新数据表,怎样自动生成行号? [问题点数:40分]

    ClientDataSet.First;while not ClientDataSet.eof dobegin  ClientDataSet.edit;  ClientDataSet.FieldByN ...

  5. WPF DataGrid自动生成序号

    需求和效果 应用WPF技术进行开发的时候,大多都会遇到给DataGrid添加序号的问题,今天分享一下查阅了很多stackoverflow的文章后,总结和改进过来的方法,先看一下效果图,文末附Demo下 ...

  6. Flex 生成行号

    private function formatIndexNumber(item:Object, colum:Object):String {      return indexNumLabelFun( ...

  7. wpf DataGrid加载行号

    <DataGrid Name="tkdg" HorizontalContentAlignment="Center" AutoGenerateColumns ...

  8. WPF DataGrid自动生成列

    <Window x:Class="DataGridExam.MainWindow"        xmlns="http://schemas.microsoft.c ...

  9. Wpf DataGrid 自动滚动到最后一行

    if (mainDataGrid.Items.Count > 0) { var border = VisualTreeHelper.GetChild(mainDataGrid, 0) as De ...

随机推荐

  1. [js高手之路]Vue2.0基于vue-cli+webpack同级组件之间的通信教程

    我们接着上文继续,本文我们讲解兄弟组件的通信,项目结构还是跟上文一样. 在src/assets目录下建立文件EventHandler.js,该文件的作用在于给同级组件之间传递事件 EventHandl ...

  2. bgp选路原则【第二部】

    面向逻辑谈bgp选路原则(第二部) 终于到了BGP终极解析的第二部曲--BGP选路原则.与题目相呼应,我不会直接介绍选路原则的规则,而是从时间逻辑和空间逻辑上将所有的选路原则分层分类.因为只有从这种角 ...

  3. css预处理器less和scss之less介绍(一)

    第一次发的标题有误,重发一遍,抱歉了 一.less基础语法 1.声明变量:@变量名:变量值 使用变量:@变量名 例如 @color : #ff0000; @length : 100px; #div1{ ...

  4. 团队作业8——Beta 阶段冲刺7th day

    一.当天站立式会议 二.每个人的工作 (1)昨天已完成的工作(具体在表格中) 完善支付功能 (2)今天计划完成的工作(具体如下) 测试与正式发布 (3) 工作中遇到的困难(在表格中) 成员 昨天已完成 ...

  5. 201521145048《Java程序设计》第5周学习总结

    1. 本章学习总结 2. 书面作业 Q1.代码阅读:Child压缩包内源代码 1.1 com.parent包中Child.java文件能否编译通过?哪句会出现错误?试改正该错误.并分析输出结果. 错误 ...

  6. 201521123048 《Java程序设计》第5周学习总结

    1. 本周学习总结 1.1 尝试使用思维导图总结有关多态与接口的知识点. 2. 书面作业 1.代码阅读:Child压缩包内源代码 //child public class test extends P ...

  7. JAVA课程设计个人博客 学生成绩管理 201521123001 张陈东芳

    1. 团队课程设计博客链接 http://www.cnblogs.com/kawajiang/p/7062407.html 2.个人负责模块或任务说明 我主要负责实现学生信息的添加功能.学生成绩的录入 ...

  8. Java第十二周学习总结

    1. 本周学习总结 1.1 以你喜欢的方式(思维导图或其他)归纳总结多流与文件相关内容. 2. 书面作业 将Student对象(属性:int id, String name,int age,doubl ...

  9. 201521123031 《Java程序设计》第13周学习总结

    1. 本周学习总结 以你喜欢的方式(思维导图.OneNote或其他)归纳总结多网络相关内容. 2. 书面作业 1. 网络基础 1.1 比较ping www.baidu.com与ping cec.jmu ...

  10. Spring security csrf实现前端纯html+ajax

    spring security集成csrf进行post等请求时,为了防止csrf攻击,需要获取token才能访问 因此需要添加 <input type="hidden" na ...