關於DataGrid的動態排序問題

來源:互聯網
上載者:User
datagrid|動態|排序|問題 我有這麼一個設計介面的設計習慣:我喜歡把資料庫的”Comment”欄位從任何顯示資料庫列表的控制項中過濾掉,然後通過跟蹤使用者滑鼠的單擊,動態地將它的內容顯示在旁邊另一塊我覺得更適合顯示它的地方,比如說一個EditBox(Multiline = true)。以前這個方法動作得很好,因為我沒有採用DataGrid,而是用的像ListBox一樣的控制項,但DataGrid強大的功能反而給我出了一道難題。因為在DataGrid的介面上使用者可以通過點擊ColumnHeader來改變資料顯示的排列順序。而在My Code裡頭,剛開始只能通過重寫MouseDown的事件,利用DataGrid的當前行的行號或者叫索引來安排從本地DataView中讀取資料並顯示在其它地方。後來我發現,當使用者點擊ColumnHeader以後資料在DataGrid中的排列順序改變了,在旁邊顯示出來的資訊,比如Comment,就對不上號了。



後來我發現,每次點擊GataGrid的ColumnHeader後,它上面的小箭頭都會改變方向,但每個ColumnHeader的箭頭方向是獨立的。說它們是獨立的是因為每列的箭頭都只有被點擊後才會改變方向,如果點擊的是另一個列,那麼這將對本列沒有影響。舉個列子,有如下兩個列,從箭頭的方向來看,資料是按Id列升序排列的:



Id∧ Name



現在使用者點擊了第一個ColumnHeader,結果將變成下面這種情況:



Id∨ Name



這個時候如果使用者繼續點擊第一列,那麼它的箭頭方向將變為向上,而點擊後者,其箭頭方向會變成設下,而不是向上,因為它預設的就是升序排列。



如果有一個方法讓這些箭頭都統一起來,我就可以通過動態地改變DataView的Sort屬性來對應新的排列順序,因為通過捕獲DataGrid的MouseDown事件我可以擷取被點擊的ColumnHeader的HeaderText。



那麼怎樣使這些箭頭都統一起來呢?



用一個布爾變數!



是的,就這個簡單,但想到可不容易。於是我在當前表單類中設定了一個布爾變數,取名為bSortDESC並將之初始為了false,因為這是預設的。那麼接下來,當使用者點擊“列頭”時,我就在DataGrid的MouseDown事件中通過代碼得到當前列的列名。將布爾變數作一個逆變換後判斷它的值,以決定將DataView的Sort屬性改成什麼。這樣一來,背景資料檢視就會動態地跟隨前台的變數而改變順序。於是乎,顯示在旁邊的其它資料也就可以對上號了。



下面用一段代碼再作一翻解釋:

//在Form1類的定義中聲明一個受保護的布爾變數

private bool bSortDESC = false;

//在Form1_Load中初始化

SqlCommand cmd = Global.cnn.CreateCommand();
cmd.CommandText = "spGetEmpInfo";
cmd.CommandType = CommandType.StoredProcedure;
this.da = new SqlDataAdapter(cmd);
this.ds = new DataSet();
this.dv = new DataView();
this.da.FillSchema(this.ds, SchemaType.Source);
this.da.Fill(this.ds, "tblEmpInfo");
this.dv.Table = this.ds.Tables["tblEmpInfo"];
this.dv.Sort = "Id";

this.dg.DataSource = this.dv
DataGridTableStyle ts = new DataGridTableStyle();
ts.MappingName = "tblEmpInfo";

this.dg.TableStyles.Add(ts);
this.dg.TableStyles[0].GridColumnStyles["Comment"].Width = 0;

//下面是DataGrid的MouseDown事件

private void dgDoc_MouseDown(object sender, System.Windows.Forms.MouseEventArgs e)
{
DataGrid tmpDg = (DataGrid)sender;
DataGrid.HitTestInfo hti = tmpDg.HitTest(e.X, e.Y);

switch(hti.Type)
{
case DataGrid.HitTestType.ColumnHeader:
{
try
{
int nColumnIndex = hti.Column;
string strColumnHeader = this.dg.TableStyles[0].GridColumnStyles[nColumnIndex].HeaderText;

this.bSortDESC = !this.bSortDESC;
if (this.bSortDESC)
{
this.dv.Sort = strColumnHeader + " ASC";
}
else
{
this.dv.Sort = strColumnHeader + " DESC";
}
}
catch(Exception ex)
{
MessageBox.Show(ex.Message);
}
}break;
}
}

//如果您選擇將某些欄位在DataGrid之外顯示並將它們與資料來源綁定在一起時,請加入以下的CurrentCellChanged事件處理代碼

private void dgDoc_CurrentCellChanged(object sender, System.EventArgs e)
{
// now the dg row index can be treated as the row index of the data in
// dv since dv has been re-sorted
BindingContext[this.].Position = this.dg.CurrentRowIndex;
this.UpdateScreen();
}

//最後是更新介面的方法(rtb代表RichTextBox)

private void UpdateScreen()
{
this.rtbComment.Clear();
this.rtbComment.Text = this.dv[BindingContext[this.dv].Position]["Comment"].ToString();


這樣,當你點擊DataGrid的ColumnHeader時,上面箭頭的方向總是一上一下,即使你點擊在不同的列上.而至於背景視圖,已經動態地重新排列了.

這是我自己想出來的方法,可能有不足之處,如果誰有更好的方法,希望能和大家分享d:)




相關文章

E-Commerce Solutions

Leverage the same tools powering the Alibaba Ecosystem

Learn more >

Apsara Conference 2019

The Rise of Data Intelligence, September 25th - 27th, Hangzhou, China

Learn more >

Alibaba Cloud Free Trial

Learn and experience the power of Alibaba Cloud with a free trial worth $300-1200 USD

Learn more >

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。