WPF DataGrid自动生成行号

在使用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

 

 

转载于:https://www.cnblogs.com/CSharpSPF/archive/2012/02/29/2373287.html

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
WPF DataGrid 中添加行号,可以使用以下两种方法: 1. 在 XAML 中定义行号列 可以在 DataGrid 中添加一个新列,用于显示行号。在 XAML 中,可以使用 DataGridTemplateColumn 和 MultiBinding 来实现,如下所示: ```xml <DataGrid x:Name="dataGrid1"> <DataGrid.Columns> <DataGridTemplateColumn Header="#" Width="50"> <DataGridTemplateColumn.CellTemplate> <DataTemplate> <TextBlock Text="{Binding RelativeSource={RelativeSource AncestorType={x:Type DataGrid}}, Path=Items.IndexOf(this) + 1}" /> </DataTemplate> </DataGridTemplateColumn.CellTemplate> </DataGridTemplateColumn> <!-- 其他列 --> </DataGrid.Columns> </DataGrid> ``` 上述代码中,定义了一个名为“#”的 DataGridTemplateColumn,宽度为50。该列的单元格使用 TextBlock 来显示行号,Text 属性绑定到 Items.IndexOf(this) + 1,表示当前行在 Items 集合中的索引值加1,即为行号。 2. 在代码中添加行号列 可以在代码中处理 DataGrid 的 LoadingRow 事件,为每一行添加一个新的列,用于显示行号。如下所示: ```csharp private void dataGrid1_LoadingRow(object sender, DataGridRowEventArgs e) { e.Row.Header = (e.Row.GetIndex() + 1).ToString(); } ``` 上述代码中,使用 LoadingRow 事件处理程序为每一行添加一个行头,行头的内容为当前行在 DataGrid 中的索引值加1。需要注意的是,需要将 DataGrid 的 RowHeadersVisible 属性设置为 true,才能显示行头。可以在 XAML 中或者在代码中设置该属性,如下所示: ```csharp dataGrid1.RowHeadersVisible = true; ``` ```xml <DataGrid x:Name="dataGrid1" RowHeadersVisible="True"> <!-- 其他列 --> </DataGrid> ```

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值