1,增加新行用InitNewRow事件,給新行某字段賦值。后結束編輯。
private void grdView_InitNewRow(object sender, DevExpress.XtraGrid.Views.Grid.InitNewRowEventArgs e)
{
DevExpress.XtraGrid.Views.Grid.GridView view = sender as DevExpress.XtraGrid.Views.Grid.GridView;
view.SetRowCellValue(e.RowHandle, view.Columns["EnterID"], this.dS_MEnterStoreView.MEnterStore[0].ID);
this.grdControl.EmbeddedNavigator.Buttons.EndEdit.DoClick();
this.grdView.UpdateCurrentRow();
}
2,如果進行行驗證,就在換行時時行,用grdView_FocusedRowChanged事件
private void grdView_FocusedRowChanged(object sender, DevExpress.XtraGrid.Views.Base.FocusedRowChangedEventArgs e)
{
WsClient.WS_MEnterStore.DS_MEnterStoreView.MEnterDetailRow row = (WsClient.WS_MEnterStore.DS_MEnterStoreView.MEnterDetailRow)this.grdView.GetDataRow(e.FocusedRowHandle);
if (row != null)
{
if ((this.OperState == Common.Enum.TOperState.UnConfirmNew)
|| (this.OperState == Common.Enum.TOperState.UnConfirmEdit))
{
this.InitComboBoxValue(row, row.IsGoodIDNull()?0:row.GoodID, false);
this.InitBatchComboBoxValue(row, row.IsGoodIDNull()?0:row.GoodID, false);
}
}
}
3,如果需要改變行的某一列的同時改變其它的列用grdView_CellValueChanged事件
private void grdView_CellValueChanged(object sender, DevExpress.XtraGrid.Views.Base.CellValueChangedEventArgs e)
{
if (this.grdView.FocusedColumn == e.Column)
{
if (e.Column == this.colAmount)
{
}
}
}
4,如果需在離開行的時候需要驗證,則用grdView_BeforeLeaveRow事件.
DevExpress XtraGrid的功能實在強大,剛使用的時候看到一大片屬性設置,分不清東南西北,參照demo和使用中的一些經驗,記錄一下使用方法。現在數據庫訪問都使用ORM技術了,對於DataSouce綁定以下是以IList為說明對象。
控件基本定義 DevExpress.XtraGrid.GridControl gridControl1;
1、 數據綁定(IList)
DevExpress.XtraGrid.Views.Grid.GridView gridView1; IList<MyClass> list = new BindingList<MyClass>(); //初始list list.Add(A); list.Add(B); ……….. gridControl1.DataSource = list;
2、 在Grid上編輯數據
修改屬性gridView1.OptionsView.NewItemRowPosition,設為Top或Bottom可以在Grid上添加數據。
(在demo中原文:a record object must be inherited from the IEditableObject class if you need the ability to cancel newly added records via the grid)
譯:如果你需要通過gird取消新建的記錄,你的記錄對象必須實現IEditableObject
(注:在測試中,感覺不需要繼承IEditableObject,在grid編輯后也能實現取消。demo通過實現IEditableObject的BeginEdit、CancelEdit方法,數據編輯后恢復特定數據。不使用grid直接修改數據,可以考慮這種恢復原數據的方法。)
3、 修改列(Column)格式
DevExpress.XtraGrid.Columns.GridColumn col = gridView1.Columns[0];
數據對齊方式 col.AppearanceCell.TextOptions.HAlignment, 默認值Default,可選值Default/Near/Center/Far。
說明:以下情況是基於從左到右的文字排列;若是從右到左,用法相反。
Default:數據默認的對齊方式
Near:左對齊
Center:居中對齊
Far:右對齊
列標題 col.Caption
對應綁定數據的屬性 col.FieldName
排列順序 col.VisibleIndex
格式化顯示數據
Col.DisplayFormat.FormatType
Col.DisplayFormat.Format
Col.DisplayFormat.FormatString
區別:FormatType/FormatString 使用當前系統的語言區域設置,Format使用特定的
4、 使用Grid內置導航欄
gridControl1.UseEmbeddedNativgator=True
設定內置導航欄按鈕其他屬性 gridControl1.EmbeddedNavigator
5、 GridView內置方式編輯數據
禁止編輯數據 gridView1.OptionsBehavior.Editable = False,默認是True 可編輯。
Gridview內置數據編輯器顯示方式 gridView1.OptionsBehavior.EditorShowMode,可選值Default/ MouseDown/MouseUp/ Click。
說明:
Default 多選Cell相當於Click,單選Cell相當於MouseDown
MouseDown 在單元格內按下鼠標鍵時打開內置編輯器
MouseUp 在單元格內釋放鼠標鍵時打開內置編輯器
Click 在不是編輯狀態,但獲得焦點的單元格中點擊時打開編輯器。點擊非焦點單元格時,首先會切換焦點,再點擊時才打開編輯器
6、 設定GrideView單元格的內置編輯器
在Run Designer的Columns選中需要變更編輯方式的Column,在ColumnEdit 屬性的下拉菜單中選擇編輯數據使用的控件。
例1:Person表的CountryID字段的值來自Country表,使用下拉列表顯示CountryName編輯
修改CountryIDColumn.ColumnEdit值,選new->LookupEdit,默認命名為repositoryItemLookUpEdit1。展開ColumnEdit屬性,將DisplayMember 設為CountryName,DropDownRows是下拉列表的行數,ValueMember設為CountryID。
代碼中添加:
//init data
repositoryItemLookUpEdit1.DataSource = ds.Tables[Country];
例2:字段Age是整型,需要使用SpinEdit編輯
修改AgeColumn.ColumnEdit值,選new->SpinEdit。展開ColumnEdit屬性,修改MaxValue、MinValue設定最大、最小值。運行時Age的取值只能在MaxValue至MinValue之間選值。
7、 GridView調節行高顯示大文本
默認情況下gridview已單行方式顯示,過長的文本只能顯示開頭部分,鼠標停留在單元格上方有ToolTip顯示所有文本。在文本單元格的右邊兩個按鈕供切換顯示上下行。若需要在單元格變更行高顯示所有文本。使用
gridView1.OptionsView.RowAutoHeight = True;
gridView1.LayoutChanged();
private void gridView1_CalcRowHeight(object sender,DevExpress.XtraGrid.Views.Grid.RowHeightEventArgs e)
{
if(e.RowHandle >= 0)
e.RowHeight = (int)gridView1.GetDataRow(e.RowHandle)["RowHeight"];
}
8、 數據導出
XtraGrid支持Html、Xml、Txt、Xsl導出,對應的導出器是ExportHtmlProvider、ExportXmlProvider、ExportTxtProvider、ExportXslProvider
例:使用html格式導出數據
IExportProvider provider = new ExprotHtmlProvider(filename);
ExportTo(provider);
……
private void ExportTo(IExportProvider provider) {
Cursor currentCursor = Cursor.Current;
Cursor.Current = Cursors.WaitCursor;
this.FindForm().Refresh();
BaseExportLink link = gridView1.CreateExportLink(provider);
(link as GridViewExportLink).ExpandAll = false;
link.Progress += new DevExpress.XtraGrid.Export.ProgressEventHandler(Export_Progress);//進度條事件
link.ExportTo(true);
provider.Dispose();
link.Progress -= new DevExpress.XtraGrid.Export.ProgressEventHandler(Export_Progress);
Cursor.Current = currentCursor;
}
9、 焦點單元格顯示方式
GrideView默認的焦點單元格顯示方式是整行選中,焦點單元格高亮。可以調整以下屬性進行修改
gridView1.FocusRectStyle :焦點繪畫方式 默認DrawFocusRectStyle.CellFocus(單元格)/ DrawFocusRectStyle.RowFocus(行)/ DrawFocusRectStyle.None(不繪畫)
bool gridView1.OptionsSelection.EnableAppearanceFocusedCell :是否焦點顯示選中的單元格
bool gridView1.OptionsSelection.EnableAppearanceFocusedRow :是否焦點顯示選中的行
bool gridView1.OptionsSelection.InvertSelection :是否反顯示
bool gridView1.OptionsSelection.MultiSelect:是否使用多選
10、
顯示非數據源的數據
可以在GrideView上增加數據源沒有的列,如合計、日期、序號或其他數據源等。
方法一:實現CustomColumnDisplayText事件(只能用於顯示)
以下例子在bandedGridColumn1上顯示 FirstName+LastName
bandedGridColumn1.OptionsColumn.AllowEdit = false;
private void bandedGridView1_CustomColumnDisplayText(object sender, DevExpress.XtraGrid.Views.Base.CustomColumnDisplayTextEventArgs e)
{
if(e.Column.Equals(bandedGridColumn1))
{
DataRow row = bandedGridView1.GetDataRow(e.RowHandle);
e.DisplayText = string.Format("{0} {1}", row["FirstName"], row["LastName"]);
}
}
方法二: 設定列的UnboundType,並實現CustomUnboundColumnData事件(可修改值)
以下例子演示DateTime/Int/String 綁定到數據列上顯示。當修改 GrideView上的值時,將修改同步到原數組中
bandedGridColumn4.UnboundType = DevExpress.Data.UnboundColumnType.DateTime;
bandedGridColumn5.UnboundType = DevExpress.Data.UnboundColumnType.Integer;
bandedGridColumn6.UnboundType = DevExpress.Data.UnboundColumnType.String;
private void bandedGridView1_CustomUnboundColumnData(object sender, DevExpress.XtraGrid.Views.Base.CustomColumnDataEventArgs e) {
if(array == null) return;
if(e.ListSourceRowIndex >= array.Count) return;
Record rec = array[e.ListSourceRowIndex] as Record;
if(rec == null) return;
switch(e.Column.UnboundType) {
case UnboundColumnType.DateTime:
if(e.IsGetData)
e.Value = rec.Date;
else rec.Date = (DateTime)e.Value;
break;
case UnboundColumnType.Integer:
if(e.IsGetData)
e.Value = rec.Count;
else rec.Count = (Int32)e.Value;
break;
case UnboundColumnType.String:
if(e.IsGetData)
e.Value = rec.Comment;
else rec.Comment = e.Value.ToString();
break;
}
}
提交當前行的修改
using DevExpress.XtraGrid;
using DevExpress.XtraGrid.Views.Base;
using System.Data.Common;
//...
public void UpdateDatasource(GridControl grid) {
//Save the latest changes to the bound DataTable
ColumnView view = (ColumnView)grid.FocusedView;
view.CloseEditor();
if(!view.UpdateCurrentRow()) return;
//Update the database's Suppliers table to which oleDBDataAdapter1 is connected
DoUpdate(oleDbDataAdapter1, dataSet11.Tables["Suppliers"]);
//Update the database's Products table to which the oleDbDataAdapter2 is connected
DoUpdate(oleDbDataAdapter2, dataSet11.Tables["Products"]);
}
public void DoUpdate(DbDataAdapter dataAdapter, System.Data.DataTable dataTable) {
try {
dataAdapter.Update(dataTable);
} catch(Exception ex) {
MessageBox.Show(ex.Message);
}
}
接着說,GirdControl如何定位和查找指定列顯示值的行(注意是列的實顯示值,而不是關聯數據源列值)
下面請看代碼:
using DevExpress.XtraGrid.Views.Base;
using DevExpress.XtraGrid.Columns;
// ...
string searchText = "Japan";
// obtaining the focused view
ColumnView view = (ColumnView)gridControl1.FocusedView;
// obtaining the column bound to the Country field
GridColumn column = view.Columns["Country"];
if(column != null) {
// locating the row
//如果用數據源中的列值,請用ColumnView.LocateByValue
int rhFound = view.LocateByDisplayText(view.FocusedRowHandle + 1, column, searchText);
// focusing the cell
if(rhFound != GridControl.InvalidRowHandle) {
view.FocusedRowHandle = rhFound;
view.FocusedColumn = column;
}
}
另一個查找示例
DevExpress.XtraGrid.Views.Base.ColumnView view = gridControl1.MainView as DevExpress.XtraGrid.Views.Base.ColumnView;
view.BeginUpdate();
try {
int rowHandle = 0;
DevExpress.XtraGrid.Columns.GridColumn col = view.Columns["Category"];
while(true) {
// locating the next row
rowHandle = view.LocateByValue(rowHandle, col, "SPORTS");
// exiting the loop if no row is found
if (rowHandle == DevExpress.XtraGrid.GridControl.InvalidRowHandle)
break;
// perform specific operations on the row found here
// ...
rowHandle++;
}
}
finally {
view.EndUpdate();
}
將特定編輯框綁定到列
默認的cell編輯框是不可以改變的,即使是在運行時,因為它們是動態創建和注銷的。
要想定制,就在設計時修改ColumnEdit吧。
using DevExpress.XtraEditors.Repository;
//Create a repository item for a combo box editor
RepositoryItemComboBox riCombo = new RepositoryItemComboBox();
riCombo.Items.AddRange(new string[] {"London", "Berlin", "Paris"});
//Add the item to the internal repository
gridControl1.RepositoryItems.Add(riCombo);
//Now you can define the repository item as an in-place column editor
colCity.ColumnEdit = riCombo;
另一個運行時綁定列編輯框示例
private void gridView1_CustomRowCellEdit(object sender, DevExpress.XtraGrid.Views.Grid.CustomRowCellEditEventArgs e) {
if (e.Column.FieldName == "FieldName") return;
DevExpress.XtraGrid.Views.Grid.GridView gv = sender as DevExpress.XtraGrid.Views.Grid.GridView;
string fieldName = gv.GetRowCellValue(e.RowHandle, gv.Columns["FieldName"]).ToString();
switch (fieldName) {
case "Population":
e.RepositoryItem = repositoryItemSpinEdit1;
break;
case "Country":
e.RepositoryItem = repositoryItemComboBox1;
break;
case "Capital":
e.RepositoryItem = repositoryItemCheckEdit1;
break;
}
}
檢驗錄入數據是否有效
using DevExpress.XtraGrid.Views.Grid; using DevExpress.XtraGrid.Columns; public bool isValidDate(int day, int month, int year) { return (day > 0) && (month > 0) && (month <= 12) && (year > 1980) && (year < 2100) && (day <= DateTime.DaysInMonth(year, month)); } private void gridView1_ValidateRow(object sender, DevExpress.XtraGrid.Views.Base.ValidateRowEventArgs e) { GridView view = sender as GridView; GridColumn colDay = view.Columns["Day"]; GridColumn colMonth = view.Columns["Month"]; GridColumn colYear = view.Columns["Year"]; int day = (int)view.GetRowCellValue(e.RowHandle, colDay); int month = (int)view.GetRowCellValue(e.RowHandle, colMonth); int year = (int)view.GetRowCellValue(e.RowHandle, colYear); e.Valid = isValidDate(day, month, year); if(!e.Valid) { view.SetColumnError(colDay, "Check the day"); view.SetColumnError(colMonth, "Check the month"); view.SetColumnError(colYear, "Check the year"); } }
MouseMove捕捉
private void Grid_MouseMove(object sender, System.Windows.Forms.MouseEventArgs e)
{
ShowHitInfo(this.gridView1.CalcHitInfo(new Point(e.X, e.Y)));
}
private void ShowHitInfo(DevExpress.XtraGrid.Views.Grid.ViewInfo.GridHitInfo hi)
{
DevExpress.XtraGrid.Views.Base.ColumnView cgv =
(DevExpress.XtraGrid.Views.Base.ColumnView)Grid.MainView;
string columnName = hi.Column == null ? "No column" : hi.Column.Caption;
switch(columnName)
{
case "賬號":
txtUserName.Text = cgv.GetRowCellDisplayText(hi.RowHandle,hi.Column);
break;
case "密碼":
txtPassword.Text = cgv.GetRowCellDisplayText(hi.RowHandle,hi.Column);
break;
case "真實姓名":
txtRealName.Text = cgv.GetRowCellDisplayText(hi.RowHandle,hi.Column);
break;
case "電子郵件":
txtEmail.Text = cgv.GetRowCellDisplayText(hi.RowHandle,hi.Column);
break;
case "角色":
cbRole.Text = cgv.GetRowCellDisplayText(hi.RowHandle,hi.Column);
break;
default:
txtUserName.Text = "Null";
txtPassword.Text = "Null";
txtRealName.Text = "Null";
txtEmail.Text = "Null";
cbRole.Text = "Null";
break;
}
主從表的設置
DataTable dt = pb.GetItemInfoList(Port).Copy(); //返回一個TABLE
dt.TableName = "ItemInfo";
ds.Tables.Add(dt);
DataTable dt2 = pb.GetBuildingInfoList(Port).Copy(); //返回一個TABLE
dt2.TableName = "BuildingInfo";
ds.Tables.Add(dt2);
DataColumn keyColumn = ds.Tables["ItemInfo"].Columns["ITEMINFO_ID"];
DataColumn foreignKeyColumn = ds.Tables["BuildingInfo"].Columns["ITEMINFOID"];
ds.Relations.Add("itembuildinginfo", keyColumn, foreignKeyColumn);
gridControl1.DataSource = ds.Tables["ItemInfo"];
獲取從表的當前選擇行的某一列(如ID列)
這個時候再使用獲取主表當前選擇行的某一列的方法是不行的,因為所得到的seletedrowscount=0。使用如下方法得到:
在MASTER表的展開事件中得到detail有的view.然后就可以利用它了。例:
//主表的masterrowexpanded事件
private void gridView1_MasterRowExpanded(object sender, DevExpress.XtraGrid.Views.Grid.CustomMasterRowEventArgs e)
{
detailView = gridView1.GetDetailView(e.RowHandle, e.RelationIndex) as DevExpress.XtraGrid.Views.Grid.GridView;
}
//取得從表的當前行
int[] i = detailView.GetSelectedRows();
DataRowView dt = (DataRowView)detailView.GetRow(i[0]);
//獲得當前行某列的值可以使用
dt["列名"].ToString();
//獲得當那個列的值。
定義焦點行的方法:
gridView_bcode.FocusedRowHandle = focuseRowInt; //通過設置GridView 的FocusedRowHandle屬性
//獲取焦點行任意單元格的數據
ColumnView cv = (ColumnView)gridControl_Gongzi.FocusedView;//重新獲取此ID 否則無法從表頭連刪獲取不到id
int focusedhandle = cv.FocusedRowHandle;
object rowIdObj = gridView1.GetRowCellValue(focusedhandle, "id");
if (DBNull.Value != rowIdObj)
{
FocusedRow_id = Convert.ToInt32(rowIdObj);
}
//獲取焦點行任意單元格的數據
ColumnView cv = (ColumnView)gridControl_Gongzi.FocusedView;//重新獲取此ID 否則無法從表頭連刪獲取不到id
int focusedhandle = cv.FocusedRowHandle;
object rowIdObj = gridView1.GetRowCellValue(focusedhandle, "id");
if (DBNull.Value != rowIdObj)
{
FocusedRow_id = Convert.ToInt32(rowIdObj);
}
view plaincopy to clipboardprint?
//當數據發生變化時執行
private void gridView1_CellValueChanged(object sender, CellValueChangedEventArgs e)
{
int intRowHandle = e.RowHandle;
FocusedRow_bumen = Convert.ToString(gridView1.GetRowCellValue(intRowHandle, "bumen"));
FocusedRow_xingming = Convert.ToString(gridView1.GetRowCellValue(intRowHandle, "xingming"));
//FocusedRow_jibengongzi = Convert.ToDecimal(gridView1.GetRowCellValue(intRowHandle, "jibengongzi"));
object rowJibengongziObj = gridView1.GetRowCellValue(intRowHandle, "jibengongzi");
if (DBNull.Value != rowJibengongziObj)
{
FocusedRow_jibengongzi = Convert.ToDecimal(rowJibengongziObj);
}
}
//當數據發生變化時執行
private void gridView1_CellValueChanged(object sender, CellValueChangedEventArgs e)
{
int intRowHandle = e.RowHandle;
FocusedRow_bumen = Convert.ToString(gridView1.GetRowCellValue(intRowHandle, "bumen"));
FocusedRow_xingming = Convert.ToString(gridView1.GetRowCellValue(intRowHandle, "xingming"));
//FocusedRow_jibengongzi = Convert.ToDecimal(gridView1.GetRowCellValue(intRowHandle, "jibengongzi"));
object rowJibengongziObj = gridView1.GetRowCellValue(intRowHandle, "jibengongzi");
if (DBNull.Value != rowJibengongziObj)
{
FocusedRow_jibengongzi = Convert.ToDecimal(rowJibengongziObj);
}
} view plaincopy to clipboardprint?
//設置焦點行的焦點單元格的位置
ColumnView view = (ColumnView)gridControl_Gongzi.FocusedView;
view.FocusedColumn = view.Columns["bumen"];
//設置焦點行的焦點單元格的位置
ColumnView view = (ColumnView)gridControl_Gongzi.FocusedView;
view.FocusedColumn = view.Columns["bumen"]; view plaincopy to clipboardprint?
//當焦點行發生改變時執行 獲取選中焦點行id
private void gridView1_FocusedRowChanged(object sender, DevExpress.XtraGrid.Views.Base.FocusedRowChangedEventArgs e)
{
int intRowHandle = e.FocusedRowHandle;
object rowIdObj = gridView1.GetRowCellValue(intRowHandle, "id");
if (DBNull.Value != rowIdObj)//做個判斷否則獲取不到id后報錯
{
FocusedRow_id = Convert.ToInt32(rowIdObj);
}
}
//當焦點行發生改變時執行 獲取選中焦點行id
private void gridView1_FocusedRowChanged(object sender, DevExpress.XtraGrid.Views.Base.FocusedRowChangedEventArgs e)
{
int intRowHandle = e.FocusedRowHandle;
object rowIdObj = gridView1.GetRowCellValue(intRowHandle, "id");
if (DBNull.Value != rowIdObj)//做個判斷否則獲取不到id后報錯
{
FocusedRow_id = Convert.ToInt32(rowIdObj);
}
}
view plaincopy to clipboardprint?
//焦點行的FocusedHandle為:
FocuseRow_Handle = -999998;
//獲取焦點行的handle
ColumnView newview = (ColumnView)gridControl_Gongzi.FocusedView;
FocuseRow_Handle = newview.FocusedRowHandle;
//回車添加新行
代碼
private void gridView1_KeyPress(object sender, KeyPressEventArgs e)
{
if (e.KeyChar == 13)
{
ColumnView view = (ColumnView)gridControl_Gongzi.FocusedView;
if(view.IsLastRow)
{
if (FocuseRow_Handle == 0)
{
gridView1.AddNewRow();
ColumnView newview = (ColumnView)gridControl_Gongzi.FocusedView;
newview.FocusedColumn = newview.Columns["bumen"];//定位焦點網格的位置
FocuseRow_Handle = newview.FocusedRowHandle;//獲取新焦點行的FocuseRowHandle 並初始化全局變量FocuseRow_Handle供保存操作時判斷是upd ate還是insert
}