WPF DataGrid自動生成行號

 

 

在使用WPF進行應用程序的開發時,常常會爲DataGrid生成行號,這裏主要介紹一下生成行號的方法。一般有三種方法,這裏主要介紹其中的兩種,另外一種簡單提一下。post

1. 直接在LoadingRow事件中操做。this

這種方式是在code behind文件中操做。即相應的*.xaml.cs文件。spa

 代碼以下:.net

複製代碼
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文件中也能夠。code

 

2. 正如在第一種方法末尾提到的,爲了適應MVVM的開發模式,不但願把自動生成行號的操做放到code behind文件中去實現,而也是想放到viewmodel中去實現。這時候可使用爲事件綁定command的方法,具體作法見下面代碼:xml

在設計頁面中引入下面命名空間,該dll在安裝blend後會存在,目錄爲C:\Program Files\Microsoft SDKs\Expression\Blend\.NETFramework\v4.0\Libraries,若是沒有,本身能夠到網上下載。blog

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

相關文章
相關標籤/搜索