<output id="qn6qe"></output>

    1. <output id="qn6qe"><tt id="qn6qe"></tt></output>
    2. <strike id="qn6qe"></strike>

      亚洲 日本 欧洲 欧美 视频,日韩中文字幕有码av,一本一道av中文字幕无码,国产线播放免费人成视频播放,人妻少妇偷人无码视频,日夜啪啪一区二区三区,国产尤物精品自在拍视频首页,久热这里只有精品12
      happyhippy

      這個世界的問題在于聰明人充滿疑惑,而傻子們堅信不疑。--羅素

          DataGrid 控件提供了一種靈活的方式來以行和列的形式顯示數據集合。但卻沒有提供增加、刪除行、即時輸入等功能,若要實現類似于Winform下的DataGrid批量錄入功能,還得做一些手腳:
          1. 顯示行號;
          2. 即時輸入;
          3. 增加新行;
          4. 刪除行;
          5. 復制、粘貼行/多行。

          本文針對這幾個問題,提出一些解決思路。

       

      1. 顯示行號

              網上也有一些顯示行號的文章,但都是一個處理思路,就是在LoadingRow事件中做手腳,如這篇文章中所提供的思路《[Silverlight]奇技銀巧系列-4 在DataGrid中顯示行號》:

         1: dataGrid1.LoadingRow += new EventHandler<DataGridRowEventArgs>(dataGrid1_LoadingRow);
         2:  
         3: void dataGrid1_LoadingRow(object sender, DataGridRowEventArgs e) {
         4:     int index = e.Row.GetIndex();
         5:     var cell = dataGrid1.Columns[0].GetCellContent(e.Row) as TextBlock;
         6:     cell.Text = (index + 1).ToString();
         7: }

          SL幫助文檔中對LoadingRow的解釋是:“若要改進性能,DataGrid 控件不針對綁定數據源中的每個數據項實例化 DataGridRow 對象。而是僅當需要時才由數據網格創建 DataGridRow 對象,并盡量重復使用這些對象。例如,數據網格為當前位于視圖中的每個數據項創建一個 DataGridRow 對象,并在行滾出視圖之外時回收它。”

         這個處理思路的一個問題,就是當DataGrid的行比較多,超出可視區域(出現滾動條)后;然后再刪除前面的行,行號就廢了。因為處于可視區域中的現有沒有被刪除的行,不會執行LoadingRow事件,所以顯示的Index不會被更新。

      處理思路:  

          我們一般是將ObservableCollection<Entity>作為DataGrid的數據源。一個變態的處理思路,就是給Entity增加一個Index屬性(修改時引發PropertyChanged事件),然后再DataGrid的LoadingRow/UnloadingRow中,取得DataGrid的數據源ObservableCollection<Entity>,然后更新每個Index的值,囧。。。
          不過這樣也有一個問題,就是在排序后,Index不會重新計算,顯得有點亂。不知道排序會引發啥事件,如果在排序事件中也來更新一次Index,就沒有問題了。哪位知道排序會引發啥事件,請告訴我,謝謝。/:)

       

      2. 即時輸入

          默認情況下,DataGrid的Cell(TextBlock)不是出于編輯狀態,要按F2或者鼠標單擊,才能進入編輯狀態(TextBox)。如果用鼠標點,或者每次都按F2,用起來非常不爽。

      處理思路:

          參考文章《An attempt to make the Silverlight DataGrid similar to Excel》,里面提出的思路就是在KeyDown\GotFocus\CellEditEnded三個事件中進行處理:
      (1) KeyDown事件中,捕捉按鍵,如果是字符鍵,則記錄到DataGrid.Tag中,然后執行dataGrid.BeginEdit(),強制DataGrid進入編輯狀態。
      (2) GotFocus事件中,將DataGrid.Tag中記錄的字符取出來,然后付給輸入框(TextBox);
      (3) CellEditEnded事件中,清理DataGrid.Tag。

          在該文的回復中,有人提出了一個可替代的事件組合:TextInput/PreparingCellForEdit/KeyDown。也是一個處理思路。

          天殺的M$,為啥讓DataGrid可編輯,卻不能即時輸入呢。要用這種變態的方式去處理。。。

       

      3. 增加新行

          貌似新版本的SL,可以支持增加新行了。《微軟發布Silverlight 4新版并更新Silverlight Tools和SDK》,但問題是,找遍了網絡,竟然沒有一個例子,M$的論壇上,也是只有提問沒有答案。。。所以還是得自己動手。

      處理思路:

          快捷鍵:DataGrid的KeyDown事件中,判斷按鍵;
          增加新行:增加新行比較簡單,上面提到,DataGrid的數據源是ObservableCollection<Entity>,因此,只要我們向該集合中增加一個元素,就能達到增加新行的目的。

       

      4. 刪除行

          處理思路同增加新行:

          快捷鍵:KeyDown中判斷按鍵;
          刪除行:取得DataGrid的當前選擇行dataGrid.SelectedItem as Entity,然后從將Entity從ObservableCollection<Entity>中刪除。

       

      5. 復制/粘行

      處理思路1:
         《An attempt to make the Silverlight DataGrid similar to Excel》一文中,也提供了一個復制/粘貼的思路:

      image

      主要分三個步驟:
      (1). 獲取DataGrid選擇行,然后將每個cell(TextBlock)的中的文本數據,用“\t”分割,得到文本值;(如果Cell不在可視區域內,則調用dataGrid.ScrollIntoView,讓Cell顯示出來,然后才能取到TextBlock/TextBox)
      (2). 將數據保存到系統的粘貼板:

         1: var clipboardData = (ScriptObject)HtmlPage.Window.GetProperty("clipboardData");
         2: clipboardData.Invoke("setData", "text", "格式化的自定義格式的數據");

      (3). 從粘貼板上將數據取回來,再賦值給目標行中的Cell(TextBox):

         1: var clipboardData = (ScriptObject)HtmlPage.Window.GetProperty("clipboardData");
         2: string textData = clipboardData.Invoke("getData", "text").ToString();

          但該文章中,只提供了單行復制/粘貼的功能;而且這段代碼有很大局限性,只能在IE中運行

      處理思路2:
          上面的復制/粘貼功能,只局限在IE中運行。另一個處理思路,可以做兩點改進:

      (1)  上面提到,DataGrid的數據源是ObservableCollection<T>,只要改變該集合中的值,SL就會自動刷新DataGrid。因此我們可以不用去操作DataGrid中的Cell,而是直接操作ObservableCollection<T>。拷貝的時候,對選中的一個或多個元素(Entity)執行xml序列化得到文本值;粘貼的時候,將文本值反序列化回來,然后對掉選中的元素(Entity)逐個屬性賦值。

          從ObservableCollection<T>得到文本值由兩個處理思路:可以按上面描述的序列化來處理;也可以按處理思路1種的文本拼接思路,按照csv格式來進行拼接:屬性值之間以“\t”分隔,元素(Entity)之間以“\r\n”分隔。

          按csv格式拼接的好處,就是拷貝的數據,可以直接粘貼到Excel中。而序列化的好處,就是可以保證兼容性;譬如批量錄入過程耗時可能比較長,中途可能需要跳轉到其他頁面、或者離開很久、或者下班關機,那前面錄入的相當于白干了;因此需要在客戶端提供了一個臨時保存的功能:把當前數據保存到文件(SL4支持將數據保存獨立存儲區中),下次再從文件中把數據加載出來;但如果中途系統升級了,增加或者減少了一個字段/列,則序列化可以忽略增加/減少的列,繼續正常工作。但CSV格式拼接出來的文本,缺少列描述信息,就掛了。。。

      (2) 用一個TextBox做中轉。將文本值賦值給中轉的TextBox,然后對TextBox按Ctrl+C,從而將數據拷貝到系統的粘貼板;粘貼的過程正好反過來,先將系統粘貼板的數據,粘貼到中轉用的TextBox,然后再取得TextBox中的值。

          整個處理過程如下圖所示:

      image

          在復制/粘貼的過程中,可能還會遇到一種情況,即選擇了DataGrid中的N行,然后復制;但粘貼的時候,可能會選擇M行,有三種情況需要考慮:
      (1) M=N:這種情況下,正好元素可以一一匹配上;逐個元素按屬性賦值就行;
      (2) M>N:雖然粘貼時,選擇的行數更多,但我們可以忽略多出的行(M-N),只處理前面的N行;
      (3) M<N:此時,需要考慮多出的復制行(N-M)要怎么處理了;有三種處理辦法:(1) 忽略多出的復制行;(2) 按照Excel的處理思路,只允許粘貼到連續的N行中;(3) 我的處理思路是,可以跨行粘貼,對于多出的行,可以插入到ObservableCollection<T>中。

       

      6. 類圖結構

      ClassDiagram1

      7. 使用方法

         1: dataGrid.UseExtender<Employee>();

          這是最簡單的情況,只提供基本的即時輸入、增加、刪除、復制、粘貼功能等;一個稍微復雜點的調用方式如下:

         1: //happyhippy.cnblogs.com
         2: //方法定義原型
         3: public static void UseExtender<T>(this DataGrid dataGrid, string autoIncreaseField = "",
         4:     bool useXmlCopy = true, Action<DataGrid, EntityChangedEventArgs> rowsChanged = null,
         5:     bool addable = true, bool deleteable = true)
         6:     where T : class, new()
         7:  
         8: //調用:
         9: dataGrid.UseExtender<Employee>("Index", true, 
        10:                 (s, eventArg) =>
        11:                 {
        12:                     //取得剛操作(插入/刪除)的元素集合,可以干一些后續的事情。。。
        13:                     IList<Employee> changedEntities = eventArg.ChangedEntities as IList<Employee>;
        14:                 }, true, true);

      運行效果:
       image

       

      8. 上代碼

       

       

       

       

      DataGridLikeExcel.rar

      posted on 2010-12-26 21:40  Silent Void  閱讀(4541)  評論(6)    收藏  舉報

      主站蜘蛛池模板: 国产高清吹潮免费视频| 国产在线不卡精品网站| 国产日韩综合av在线| 男男车车的车车网站w98免费| 中文字幕免费不卡二区| 亚洲第一综合天堂另类专| 色又黄又爽18禁免费视频| 国产亚洲一区二区三不卡| 四虎国产精品永久在线| 亚洲欧美日韩人成在线播放| 日韩精品毛片无码一区到三区| 无码av岛国片在线播放| 国产精品最新免费视频| 乱色老熟妇一区二区三区| 日韩无人区码卡1卡2卡| 国产亚洲欧美另类一区二区| 亚洲日本精品国产第一区| 2021亚洲va在线va天堂va国产 | 亚洲第一二三区日韩国产| 无码福利写真片视频在线播放| 老妇xxxxx性开放| 亚洲免费观看一区二区三区| 性夜夜春夜夜爽夜夜免费视频| 精品一区二区三区女性色| 国产中文字幕精品喷潮| 欧美日本精品一本二本三区| 国产成人高清亚洲综合| 国产精品麻豆成人av网| 国产一级片内射在线视频| 97碰碰碰免费公开在线视频| 日韩日韩日韩日韩日韩| 精品国精品国产自在久国产应用男| 免费大片黄国产在线观看| 在线中文字幕国产精品| 内射无套内射国产精品视频| 亚洲国产精品综合久久网络| 国产午夜福利免费入口| 精品女同一区二区三区在线 | 欧美极品色午夜在线视频| 中文字幕一区二区精品区| 亚洲人成线无码7777|