日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

(转)使用DataGridView控件常见问题解答

發(fā)布時間:2023/12/19 编程问答 23 豆豆
生活随笔 收集整理的這篇文章主要介紹了 (转)使用DataGridView控件常见问题解答 小編覺得挺不錯的,現(xiàn)在分享給大家,幫大家做個參考.

1.??? 如何使指定的單元格不可編輯?

ReadOnly屬性決定了單元格中的數(shù)據(jù)是否可以編輯,可以設(shè)置單元格的ReadOnly 屬性,也可以設(shè)置DataGridViewRow.ReadOnly DataGridViewColumn.ReadOnly使得一行或一列所包含的單元格都是只讀的。 默認情況下,如果一行或一列是只讀的,那么其包含的單元格也會使只讀的。

?

不過你仍可以操作一個只讀的單元格,比如選中它,將其設(shè)置為當前單元格,但用戶不能修改單元格的內(nèi)容。注意,即使單元格通過ReadOnly屬性設(shè)置為只讀,仍然可以通過編程的方式修改它,另外ReadOnly也不會影響用戶是否可以刪除行。

2.??? 如何讓一個單元格不可用(disable)?

單元格可以設(shè)置為只讀而不可編輯,但DataGridView卻沒提供使單元格不可用的支持。一般意義上,不可用意味著用戶不能進行操作,通常會帶有外觀的暗示,如灰色。沒有一種簡單的方法來創(chuàng)建那種不可操作的單元格,但提供一個暗示性的外觀告訴用戶某單元格不可用還是可行的。內(nèi)置的單元格類型沒有進行不可用設(shè)置的屬性,下面的例子擴展了DataGridViewButtonCell ,參照常見控件的Enabled屬性,為其添加了Enabled屬性,如果該屬性設(shè)置為false,那么其外觀狀態(tài)將類似于普通按鈕的不可用狀態(tài)。

?

public class DataGridViewDisableButtonColumn : DataGridViewButtonColumn

{

??? public DataGridViewDisableButtonColumn()

??? {

??????? this.CellTemplate = new DataGridViewDisableButtonCell();

??? }

}

?

public class DataGridViewDisableButtonCell : DataGridViewButtonCell

{

??? private bool enabledValue;

??? public bool Enabled

??? {

??????? get {

??????????? return enabledValue;

??????? }

??????? set {

??????????? enabledValue = value;

??????? }

??? }

?

??? // Override the Clone method so that the Enabled property is copied.

??? public override object Clone()

{

DataGridViewDisableButtonCell cell =

??????????? (DataGridViewDisableButtonCell)base.Clone();

??????? cell.Enabled = this.Enabled;

??????? return cell;

??? }

?

??? // By default, enable the button cell.

??? public DataGridViewDisableButtonCell()

??? {

??????? this.enabledValue = true;

??? }

?

??? protected override void Paint(Graphics graphics,

??????? Rectangle clipBounds, Rectangle cellBounds, int rowIndex,

??????? DataGridViewElementStates elementState, object value,

??????? object formattedValue, string errorText,

??????? DataGridViewCellStyle cellStyle,

??????? DataGridViewAdvancedBorderStyle advancedBorderStyle,

??????? DataGridViewPaintParts paintParts)

??? {

??????? // The button cell is disabled, so paint the border,?

??????? // background, and disabled button for the cell.

??????? if (!this.enabledValue)

??????? {

??????????? // Draw the cell background, if specified.

??????????? if ((paintParts & DataGridViewPaintParts.Background) ==

??????????????? DataGridViewPaintParts.Background)

??????????? {

SolidBrush cellBackground =

??????????????????? new SolidBrush(cellStyle.BackColor);

??????????????? graphics.FillRectangle(cellBackground, cellBounds);

??????????????? cellBackground.Dispose();

??????????? }

?

??????????? // Draw the cell borders, if specified.

??????????? if ((paintParts & DataGridViewPaintParts.Border) ==

??????????????? DataGridViewPaintParts.Border)

??????????? {

??????????????? PaintBorder(graphics, clipBounds, cellBounds, cellStyle,

??????????????????? advancedBorderStyle);

??????????? }

?

??????????? // Calculate the area in which to draw the button.

??????????? Rectangle buttonArea = cellBounds;

??????????? Rectangle buttonAdjustment =

??????????????? this.BorderWidths(advancedBorderStyle);

??????????? buttonArea.X += buttonAdjustment.X;

??????????? buttonArea.Y += buttonAdjustment.Y;

??????????? buttonArea.Height -= buttonAdjustment.Height;

??????????? buttonArea.Width -= buttonAdjustment.Width;

?

??????????? // Draw the disabled button.???????????????

??????????? ButtonRenderer.DrawButton(graphics, buttonArea,

??????????????? PushButtonState.Disabled);

?

??????????? // Draw the disabled button text.

??????????? if (this.FormattedValue is String)

??????????? {

???????? ???????TextRenderer.DrawText(graphics,

??????????????????? (string)this.FormattedValue,

??????????????????? this.DataGridView.Font,

??????????????????? buttonArea, SystemColors.GrayText);

??????????? }

??????? }

??????? else

??????? {

??????????? // The button cell is enabled, so let the base class

??????????? // handle the painting.

??????????? base.Paint(graphics, clipBounds, cellBounds, rowIndex,

??????????????? elementState, value, formattedValue, errorText,

??????????????? cellStyle, advancedBorderStyle, paintParts);

??????? }

??? }

}

3.??? 如何避免用戶將焦點設(shè)置到指定的單元格?

默認情況下DataGridView的操作(navigation)模型在限制用戶將焦點置于指定的單元格方面沒有提供任何支持。你可以實現(xiàn)自己的操作邏輯,這需要重寫合適的鍵盤、導(dǎo)航、鼠標方法,如DataGridView.OnKeyDown DataGridView.ProcessDataGridViewKey DataGridView.SetCurrentCellAddressCore ?DataGridView.SetSelectedCellCore DataGridView.OnMouseDown。

4.??? 如何使所有單元格總是顯示控件(不論它是否處于編輯狀態(tài))

DataGridView 控件只支持在單元格處于編輯狀態(tài)時顯示真實的控件(TextBox)DataGridView 沒有被設(shè)計為顯示多控件或為每行重復(fù)顯示控件。DataGridView 在單元格不被編輯時為其繪制對應(yīng)控件的外觀,該外觀可能是你想要的。例如,DataGridViewButtonCell 類型的單元格,不管它是否處于編輯狀態(tài),總是表現(xiàn)為一個按鈕。

5.??? Why does the cell text show up with “square” characters where they should be new lines(TODO,未能實現(xiàn)該效果)?

By default, text in a DataGridViewTextBoxCell does not wrap. This can be controlled via the WrapMode property on the cell style (e.g. DataGridView.DefaultCellStyle.WrapMode). Because text doesn’t wrap, new line characters in the text do not apply and so they are displayed as a “non-printable” character. This is similar to setting a TextBox’s Text property to the same text when the TextBox’s MultiLine property is false.

6.??? 如何在單元格內(nèi)同時顯示圖標和文本?

DataGridView控件沒有對在同一單元格內(nèi)同時顯示圖標和文本提供支持。但通過實現(xiàn)自定義的繪制事件,如CellPaint 事件,你可以輕松實現(xiàn)這個效果。

?

下面這段代碼擴展了DataGridViewTextBoxColumn DataGridViewTextBoxCell類,將一個圖片顯示在文本旁邊。這個示例使用了DataGridViewCellStyle.Padding 屬性來調(diào)整文本的位置,重寫了Paint 方法來繪制圖片。該示例可以得到簡化,方法是處理CellPainting 事件,在這里實現(xiàn)類似的功能。

?

??? public class TextAndImageColumn:DataGridViewTextBoxColumn

??? {

??????? private Image imageValue;

??????? private Size imageSize;

?

??????? public TextAndImageColumn()

??????? {

??????????? this.CellTemplate = new TextAndImageCell();

??????? }

?

??????? public override object Clone()

??????? {

??????????? TextAndImageColumn c = base.Clone() as TextAndImageColumn;

??????????? c.imageValue = this.imageValue;

??????????? c.imageSize = this.imageSize;

??????????? return c;

??????? }

?

??????? public Image Image

??????? {

??????????? get { return this.imageValue; }

??????????? set

??????????? {

??????????????? if (this.Image != value) {

??????????????????? this.imageValue = value;

??????????????????? this.imageSize = value.Size;

?

????? ??????????????if (this.InheritedStyle != null) {

??????????????????????? Padding inheritedPadding = this.InheritedStyle.Padding;

??????????????????????? this.DefaultCellStyle.Padding = new Padding(imageSize.Width,
?????????????????? ?inheritedPadding.Top, inheritedPadding.Right,
?????????????????? ?inheritedPadding.Bottom);

??????????????????? }

??????????????? }

??????????? }

??????? }

??????? private TextAndImageCell TextAndImageCellTemplate

??????? {

??????????? get { return this.CellTemplate as TextAndImageCell; }

??????? }

???? ???internal Size ImageSize

??????? {

??????????? get { return imageSize; }

??????? }

??? }

?

??? public class TextAndImageCell : DataGridViewTextBoxCell

??? {

??????? private Image imageValue;

??????? private Size imageSize;

???????

??????? public override object Clone()

??????? {

??????????? TextAndImageCell c = base.Clone() as TextAndImageCell;

??????????? c.imageValue= this.imageValue;

??????????? c.imageSize = this.imageSize;

??????????? return c;

??????? }

?

??????? public Image Image

??????? {

??????? ????get {

??????????????? if (this.OwningColumn == null ||
?????????? this.OwningTextAndImageColumn == null) {

?

??????????????????? return imageValue;

??????????????? }

??????????????? else if (this.imageValue != null) {

??????????????????? return this.imageValue;

??????????????? }

??????????????? else {

??????????????????? return this.OwningTextAndImageColumn.Image;

??????????????? }

??????????? }

??????????? set {

??????????????? if (this.imageValue != value) {

??????????????????? this.imageValue = value;

????? ??????????????this.imageSize = value.Size;

?

??????????????????? Padding inheritedPadding = this.InheritedStyle.Padding;

??????????????????? this.Style.Padding = new Padding(imageSize.Width,
?????????????????? inheritedPadding.Top, inheritedPadding.Right,
?????????????????? inheritedPadding.Bottom);

??????????????? }

??????????? }

??????? }

??????? protected override void Paint(Graphics graphics, Rectangle clipBounds,
?????? Rectangle cellBounds, int rowIndex, DataGridViewElementStates cellState,
?????? object value, object formattedValue, string errorText,
?????? DataGridViewCellStyle cellStyle,
?????? DataGridViewAdvancedBorderStyle advancedBorderStyle,
?????? DataGridViewPaintParts paintParts)

??????? {

??????????? // Paint the base content

??????????? base.Paint(graphics, clipBounds, cellBounds, rowIndex, cellState,
?????????? ?? value, formattedValue, errorText, cellStyle,
?????????? ?? advancedBorderStyle, paintParts);

?

??????????? if (this.Image != null) {

??????????????? // Draw the image clipped to the cell.

??????????????? System.Drawing.Drawing2D.GraphicsContainer container =
?????????????? graphics.BeginContainer();

???????????????

??????????????? graphics.SetClip(cellBounds);

??????????????? graphics.DrawImageUnscaled(this.Image, cellBounds.Location);

?

??????????????? graphics.EndContainer(container);

??????????? }

??? ????}

?

??????? private TextAndImageColumn OwningTextAndImageColumn

??????? {

??????????? get { return this.OwningColumn as TextAndImageColumn; }

??????? }

??? }

7.??? 如何隱藏一列?

有時希望僅顯示DataGridView的部分列,將其它列隱藏。比如DataGridView含有一列包含員工薪水信息,你可能希望僅將這些信息顯示給具有一定信用級別的人,其他人則隱藏。

?

通過編程方式隱藏

DataGridViewColumn類的Visible 屬性決定了是否顯示該列。

?

通過設(shè)計器隱藏

1)?????? 右擊DataGridView控件,選擇Edit Columns

2)?????? 在列列表中選擇一列;

3)?????? 在列屬性網(wǎng)格中,將Visible屬性設(shè)置為false

8.??? 如何避免用戶對列排序?

對于DataGridView 控件,默認情況下,TextBox類型的列會自動排序,而其它類型的列則不會自動排序。這種自動排序有時會把數(shù)據(jù)變得比較亂,這時你會想更改這些默認設(shè)置。

?

DataGridViewColumn的屬性SortMode決定了列的排序方式,將其設(shè)置為DataGridViewColumnSortMode.NotSortable就可以避免默認的排序行為。

9.??? 如何針對多個列排序?

默認情況下DataGridView不支持針對多列排序。下面針對是否將數(shù)據(jù)綁定到DataGridView來分別演示如何為其添加多列排序功能。

9.1 將數(shù)據(jù)綁定到DataGridView

DataGridView進行數(shù)據(jù)綁定的時候,數(shù)據(jù)源(DataView)可對多個列排序。DataGridView會保留這種排序,但只有第一個排序列會顯示排序符號(向上或向下的箭頭),此外SortedColumn屬性也只會返回第一個排序列。

?

一些數(shù)據(jù)源內(nèi)置了對多列排序的支持。如果你的數(shù)據(jù)源實現(xiàn)了IBindingListView接口,提供了對Sort屬性的支持,那么該數(shù)據(jù)源就支持多列排序。為了明確指出DataGridView對多列排序,手動為已排序列設(shè)置正確的SortGlyphDirection屬性,指示該列已經(jīng)排序。

?

下面這個示例使用DataTable作為數(shù)據(jù)源,使用其DefaultView Sort 屬性對第二列和第三列排序;該示例同時演示了如何設(shè)置列的SortGlyphDirection屬性。該示例假定在你的窗體上有一個DataGridView控件和一個BindingSource組件:

?

DataTable dt = new DataTable();

dt.Columns.Add("C1", typeof(int));

dt.Columns.Add("C2", typeof(string));

dt.Columns.Add("C3", typeof(string));

?

dt.Rows.Add(1, "1", "Test1");

dt.Rows.Add(2, "2", "Test2");

dt.Rows.Add(2, "2", "Test1");

dt.Rows.Add(3, "3", "Test3");

dt.Rows.Add(4, "4", "Test4");

dt.Rows.Add(4, "4", "Test3");

?

DataView view = dt.DefaultView;

view.Sort = "C2 ASC, C3 ASC";

bindingSource.DataSource = view;

?

DataGridViewTextBoxColumn col0 = new DataGridViewTextBoxColumn();

col0.DataPropertyName = "C1";

dataGridView1.Columns.Add(col0);

col0.SortMode = DataGridViewColumnSortMode.Programmatic;

col0.HeaderCell.SortGlyphDirection = SortOrder.None;

?

DataGridViewTextBoxColumn col1 = new DataGridViewTextBoxColumn();

col1.DataPropertyName = "C2";

dataGridView1.Columns.Add(col1);

col1.SortMode = DataGridViewColumnSortMode.Programmatic;

col1.HeaderCell.SortGlyphDirection = SortOrder.Ascending;

?

DataGridViewTextBoxColumn col2 = new DataGridViewTextBoxColumn();

col2.DataPropertyName = "C3";

dataGridView1.Columns.Add(col2);

col2.SortMode = DataGridViewColumnSortMode.Programmatic;

col2.HeaderCell.SortGlyphDirection = SortOrder.Ascending;

?

9.2 Unbound DataGridView

To provide support for sorting on multiple columns you can handle the SortCompare event or call the Sort(IComparer) overload of the Sort method for greater sorting flexibility.

?

9.2.1 Custom Sorting Using the SortCompare Event

The following code example demonstrates custom sorting using a SortCompare event handler. The selected DataGridViewColumn is sorted and, if there are duplicate values in the column, the ID column is used to determine the final order.

?

using System;

using System.Collections.Generic;

using System.ComponentModel;

using System.Data;

using System.Drawing;

using System.Windows.Forms;

?

class Form1 : Form

{

??? private DataGridView dataGridView1 = new DataGridView();

?

??? // Establish the main entry point for the application.

??? [STAThreadAttribute()]

??? static void Main()

??? {

??????? Application.EnableVisualStyles();

??????? Application.Run(new Form1());

??? }

?

??? public Form1()

??? {

??????? // Initialize the form.

??????? // This code can be replaced with designer generated code.

??????? dataGridView1.AllowUserToAddRows = false;

??????? dataGridView1.Dock = DockStyle.Fill;

??????? dataGridView1.SortCompare += new DataGridViewSortCompareEventHandler(

??????????? this.dataGridView1_SortCompare);

??????? Controls.Add(this.dataGridView1);

??????? this.Text = "DataGridView.SortCompare demo";

?

??????? PopulateDataGridView();

??? }

?

??? // Replace this with your own population code.

??? public void PopulateDataGridView()

?? ?{

??????? // Add columns to the DataGridView.

??????? dataGridView1.ColumnCount = 3;

?

??????? // Set the properties of the DataGridView columns.

??????? dataGridView1.Columns[0].Name = "ID";

??????? dataGridView1.Columns[1].Name = "Name";

??????? dataGridView1.Columns[2].Name = "City";

??????? dataGridView1.Columns["ID"].HeaderText = "ID";

??????? dataGridView1.Columns["Name"].HeaderText = "Name";

??????? dataGridView1.Columns["City"].HeaderText = "City";

?

??????? // Add rows of data to the DataGridView.

??????? dataGridView1.Rows.Add(new string[] { "1", "Parker", "Seattle" });

??????? dataGridView1.Rows.Add(new string[] { "2", "Parker", "New York" });

??????? dataGridView1.Rows.Add(new string[] { "3", "Watson", "Seattle" });

??????? dataGridView1.Rows.Add(new string[] { "4", "Jameson", "New Jersey" });

??????? dataGridView1.Rows.Add(new string[] { "5", "Brock", "New York" });

??????? dataGridView1.Rows.Add(new string[] { "6", "Conner", "Portland" });

?

??????? // Autosize the columns.

??????? dataGridView1.AutoResizeColumns();

??? }

?

??? private void dataGridView1_SortCompare(object sender,

??????? DataGridViewSortCompareEventArgs e)

??? {

??????? // Try to sort based on the cells in the current column.

??????? e.SortResult = System.String.Compare(

????????? ??e.CellValue1.ToString(), e.CellValue2.ToString());

?

??????? // If the cells are equal, sort based on the ID column.

??????? if (e.SortResult == 0 && e.Column.Name != "ID")

??????? {

??????????? e.SortResult = System.String.Compare(

??????????????? dataGridView1.Rows[e.RowIndex1].Cells["ID"].Value.ToString(),

??????????????? dataGridView1.Rows[e.RowIndex2].Cells["ID"].Value.ToString());

??????? }

??????? e.Handled = true;

??? }

}

?

9.2.2 Custom Sorting Using the IComparer Interface

The following code example demonstrates custom sorting using the Sort(IComparer) overload of the Sort method, which takes an implementation of the IComparer interface to perform a multiple-column sort.

?

using System;

using System.Drawing;

using System.Windows.Forms;

?

class Form1 : Form

{

??? private DataGridView DataGridView1 = new DataGridView();

??? private FlowLayoutPanel FlowLayoutPanel1 = new FlowLayoutPanel();

??? private Button Button1 = new Button();

??? private RadioButton RadioButton1 = new RadioButton();

??? private RadioButton RadioButton2 = new RadioButton();

?

??? // Establish the main entry point for the application.

??? [STAThreadAttribute()]

??? public static void Main()

??? {

??????? Application.Run(new Form1());

??? }

?

??? public Form1()

??? {

??????? // Initialize the form.

??????? // This code can be replaced with designer generated code.

??????? AutoSize = true;

??????? Text = "DataGridView IComparer sort demo";

?

??????? FlowLayoutPanel1.FlowDirection = FlowDirection.TopDown;

??????? FlowLayoutPanel1.Location = new System.Drawing.Point(304, 0);

??????? FlowLayoutPanel1.AutoSize = true;

?

??????? FlowLayoutPanel1.Controls.Add(RadioButton1);

??????? FlowLayoutPanel1.Controls.Add(RadioButton2);

??????? FlowLayoutPanel1.Controls.Add(Button1);

?

??????? Button1.Text = "Sort";

??????? RadioButton1.Text = "Ascending";

??????? RadioButton2.Text = "Descending";

??????? RadioButton1.Checked = true;

?

??????? Controls.Add(FlowLayoutPanel1);

??????? Controls.Add(DataGridView1);

??? }

?

??? protected override void OnLoad(EventArgs e)

??? {

??????? PopulateDataGridView();

??????? Button1.Click += new EventHandler(Button1_Click);

?

??????? base.OnLoad(e);

??? }

?

??? // Replace this with your own code to populate the DataGridView.

??? private void PopulateDataGridView()

{

??? DataGridView1.Size = new Size(300, 300);

?

??????? // Add columns to the DataGridView.

??????? DataGridView1.ColumnCount = 2;

?

??????? // Set the properties of the DataGridView columns.

??????? DataGridView1.Columns[0].Name = "First";

??????? DataGridView1.Columns[1].Name = "Last";

??????? DataGridView1.Columns["First"].HeaderText = "First Name";

??????? DataGridView1.Columns["Last"].HeaderText = "Last Name";

??????? DataGridView1.Columns["First"].SortMode =

??????????? DataGridViewColumnSortMode.Programmatic;

?????? ?DataGridView1.Columns["Last"].SortMode =

??????????? DataGridViewColumnSortMode.Programmatic;

?

??????? // Add rows of data to the DataGridView.

??????? DataGridView1.Rows.Add(new string[] { "Peter", "Parker" });

??????? DataGridView1.Rows.Add(new string[] { "James", "Jameson" });

??????? DataGridView1.Rows.Add(new string[] { "May", "Parker" });

??????? DataGridView1.Rows.Add(new string[] { "Mary", "Watson" });

??????? DataGridView1.Rows.Add(new string[] { "Eddie", "Brock" });

??? }

?

??? private void Button1_Click(object sender, EventArgs e)

??? {

??????? if (RadioButton1.Checked == true)

??????? {

??????????? DataGridView1.Sort(new RowComparer(SortOrder.Ascending));

??????? }

??????? else if (RadioButton2.Checked == true)

??????? {

??????????? DataGridView1.Sort(new RowComparer(SortOrder.Descending));

??????? }

??? }

?

??? private class RowComparer : System.Collections.IComparer

??? {

??????? private static int sortOrderModifier = 1;

?

??????? public RowComparer(SortOrder sortOrder)

??????? {

??????????? if (sortOrder == SortOrder.Descending)

??????????? {

??????????????? sortOrderModifier = -1;

??????????? }

??????????? else if (sortOrder == SortOrder.Ascending)

??????????? {

??????????????? sortOrderModifier = 1;

??????????? }

??????? }

?

??????? public int Compare(object x, object y)

??????? {

??????????? DataGridViewRow DataGridViewRow1 = (DataGridViewRow)x;

??????????? DataGridViewRow DataGridViewRow2 = (DataGridViewRow)y;

?

??????????? // Try to sort based on the Last Name column.

??????????? int CompareResult = System.String.Compare(

??????????????? DataGridViewRow1.Cells[1].Value.ToString(),

??????????????? DataGridViewRow2.Cells[1].Value.ToString());

?

??????????? // If the Last Names are equal, sort based on the First Name.

??????????? if (CompareResult == 0)

??????????? {

CompareResult = System.String.Compare(

??????????????????? DataGridViewRow1.Cells[0].Value.ToString(),

??????????????????? DataGridViewRow2.Cells[0].Value.ToString());

??????????? }

??????????? return CompareResult * sortOrderModifier;

???????}

??? }

}

10. 如何為編輯控件添加事件處理函數(shù)?

有時候你需要處理單元格包含的編輯控件的特定事件。你需要處理DataGridView.EditingControlShowing 事件,它的第二個參數(shù)的Control屬性能讓你訪問該單元格包含的編輯控件。如果你要處理的事件不屬于它的基類Control,還需要將該控件轉(zhuǎn)換為特定的控件(一般為ComboBox控件或TextBox控件)。

?

注意:如果類型相同,DataGridView會重用該編輯控件,因此,你應(yīng)該確保不會添加已存在的事件處理函數(shù),否則會調(diào)用相同的函數(shù)多次(可以在添加前先將其移除,請參考我的示例代碼)。

11. 應(yīng)在何時移除編輯控件的事件處理函數(shù)?

如果你只是想臨時為編輯控件添加事件處理函數(shù)(可能是針對特定列的特定單元格),你可以在CellEndEdit事件中移除該處理函數(shù)。你也可以在添加之前移除任何已存在的事件處理函數(shù)。

?

12. 如何處理ComboBox列中控件的SelectIndexChanged事件?

有時知道用戶何時選擇了ComboBox編輯控件的項(item)會比較有用。對于窗體上的ComboBox 控件,你通常會處理它的SelectedIndexChanged事件,對于DataGridViewComboBox,通過處理DataGridView.EditingControlShowing事件你可以完成相同的事情。下面這段示例代碼演示了這一點。注意:它同時也演示了如何避免添加多個相同的事件處理函數(shù)(即在添加前先移除已存在的事件處理函數(shù),可以參考問題11)。

?

private void dataGridView1_EditingControlShowing(object sender,

??????????????????? DataGridViewEditingControlShowingEventArgs e)

{

??? ComboBox cb = e.Control as ComboBox;

??? if (cb != null)

??? {

??????? // first remove event handler to keep from attaching multiple:

??????? cb.SelectedIndexChanged -= new
??????
EventHandler(cb_SelectedIndexChanged);

?

??????? // now attach the event handler

??????? cb.SelectedIndexChanged += new
?????? EventHandler(cb_SelectedIndexChanged);

??? }

}

?

void cb_SelectedIndexChanged(object sender, EventArgs e)

{

??? MessageBox.Show("Selected index changed");
}

?

13. 如何通過拖放調(diào)整行的順序?

通過拖放調(diào)整行的順序不是DataGridView的內(nèi)置功能,但使用標準的拖放處理代碼,你可以很容易的實現(xiàn)這個功能。下面這個代碼片斷演示了這個過程,假定你的窗體上有一個namedataGridView1DataGridView,它的AllowDrop屬性為true,還要為它添加必要的事件處理方法。(我試運行了這段代碼,如果通過數(shù)據(jù)綁定為DataGridView添加數(shù)據(jù),那么下面的代碼將不會生效,因為它只能為非綁定方式添加的行排序,如果要以綁定方式添加數(shù)據(jù),請參看我的示例程序)

?

private Rectangle dragBoxFromMouseDown;

private int rowIndexFromMouseDown;

private int rowIndexOfItemUnderMouseToDrop;

private void dataGridView1_MouseMove(object sender, MouseEventArgs e)

{

??? if ((e.Button & MouseButtons.Left) == MouseButtons.Left)

?? ?{

??????? // If the mouse moves outside the rectangle, start the drag.

??????? if (dragBoxFromMouseDown != Rectangle.Empty &&

??????????? !dragBoxFromMouseDown.Contains(e.X, e.Y))

??????? {

?

??????????? // Proceed with the drag and drop, passing in the list item.???????????????????

??????????? DragDropEffects dropEffect = dataGridView1.DoDragDrop(
?????????? dataGridView1.Rows[rowIndexFromMouseDown],
?????????? DragDropEffects.Move);

??????? }

??? }

}

?

private void dataGridView1_MouseDown(object sender, MouseEventArgs e)

{

??? // Get the index of the item the mouse is below.

??? rowIndexFromMouseDown = dataGridView1.HitTest(e.X, e.Y).RowIndex;

?

??? if (rowIndexFromMouseDown != -1)

??? {

??????? // Remember the point where the mouse down occurred.
?? ?// The DragSize indicates the size that the mouse can move
?? ?// before a drag event should be started.???????????????

??????? Size dragSize = SystemInformation.DragSize;

?

??????? // Create a rectangle using the DragSize, with the mouse position being

??????? // at the center of the rectangle.

??????? dragBoxFromMouseDown = new Rectangle(new Point(e.X - (dragSize.Width / 2),

?????????????????????????????????????????????????????? e.Y - (dragSize.Height / 2)),
?????????????????????????? dragSize);

??? }

??? else

??????? // Reset the rectangle if the mouse is not over an item in the ListBox.

??????? dragBoxFromMouseDown = Rectangle.Empty;

}

?

private void dataGridView1_DragOver(object sender, DragEventArgs e)

{

??? e.Effect = DragDropEffects.Move;

}

?

private void dataGridView1_DragDrop(object sender, DragEventArgs e)

{

??? // The mouse locations are relative to the screen, so they must be

??? // converted to client coordinates.

??? Point clientPoint = dataGridView1.PointToClient(new Point(e.X, e.Y));

?

??? // Get the row index of the item the mouse is below.

??? rowIndexOfItemUnderMouseToDrop =

??????? dataGridView1.HitTest(clientPoint.X, clientPoint.Y).RowIndex;

?

??? // If the drag operation was a move then remove and insert the row.

??? if (e.Effect== DragDropEffects.Move)

??? {

??????? DataGridViewRow rowToMove = e.Data.GetData(
?????????? typeof(DataGridViewRow)) as DataGridViewRow;

??????? dataGridView1.Rows.RemoveAt(rowIndexFromMouseDown);

??????? dataGridView1.Rows.Insert(rowIndexOfItemUnderMouseToDrop, rowToMove);

?

??? }

}

14. 如何調(diào)整最后一列的寬度使其占據(jù)網(wǎng)格的剩余客戶區(qū)?

以默認方式填充DataGridView時,可能會發(fā)生因列的寬度不夠,而暴露出控件的灰色背景的情況,很不美觀。將最后一列的AutoSizeMode屬性設(shè)置為Fill會使該列調(diào)整大小來填充網(wǎng)格的剩余客戶區(qū)(client area)。作為一個可選的方式,你可以設(shè)置最后一列MinimumWidth屬性,以保持該列的寬度不至于太小。

15. 如何讓TextBox類型的單元格支持換行?

默認情況下,DataGridViewTextBoxCell不支持換行,這個可以由DataGridViewCellStyleWrapMode屬性來控制。 (DataGridView.DefaultCellStyle.WrapMode)。將WrapMode 屬性DataGridViewTriState枚舉的三個取值之一。

?

下面的代碼示例使用DataGridView.DefaultCellStyle屬性設(shè)置整個控件所包含的單元格的WrapMode屬性(即設(shè)置所有單元格的換行模式)

?

this.dataGridView1.DefaultCellStyle.WrapMode = DataGridViewTriState.True;

?

?

?

16. 如何使Image列不顯示任何圖像(字段值為null)?

默認情況下Image類型的列和單元格將null值轉(zhuǎn)換為標準的“X”圖像( ),將Image列的NullValue屬性設(shè)置為null可使該列不顯示任何圖像。下面這行代碼演示了如何設(shè)置Image列的NullValue屬性。

?

this.dataGridViewImageColumn1.DefaultCellStyle.NullValue = null;

?

17. 如何能夠在ComboBox類型的單元格中輸入數(shù)據(jù)?

默認情況下,DataGridViewComboBoxCell不接受用戶的輸入值。但有時確實有向ComboxBox輸入數(shù)據(jù)的需要。實現(xiàn)這個功能,你需要做兩件事。一是將ComboBox編輯控件的DropDownStyle屬性設(shè)置為DropDown,使用戶可以進行輸入(否則只能進行選擇);二是確保用戶輸入的值能夠添加到ComboBoxItems集合。這是因為ComboBoxCell的值必須在Items集合中,否則會觸發(fā)DataError事件(參看3.5.1節(jié)),而適合添加新值到Items集合的地方是CellValidating事件處理函數(shù):

?

private void dataGridView1_CellValidating(object sender,
?????? ?DataGridViewCellValidatingEventArgs e)

{

??? if (e.ColumnIndex == comboBoxColumn.DisplayIndex)

??? {

??????? if (!this.comboBoxColumn.Items.Contains(e.FormattedValue))

??????? {

?? ?????????this.comboBoxColumn.Items.Add(e.FormattedValue);

??????? }

??? }

}

?

private void dataGridView1_EditingControlShowing(object sender,
?????? DataGridViewEditingControlShowingEventArgs e)

{

??? if (this.dataGridView1.CurrentCellAddress.X == comboBoxColumn.DisplayIndex)

??? {

??????? ComboBox cb = e.Control as ComboBox;

??????? if (cb != null)

??????? {

??????????? cb.DropDownStyle = ComboBoxStyle.DropDown;

???????? }

??? }

}

18. How do I have a combo box column display a sub set of data based upon the value of a different combo box column(TODO)?

Sometimes data that you want to display in the DataGridView has a relationship between two tables such as a category and subcategory. You want to let the user select the category and then choose between a subcategory based upon the category. This is possible with the DataGridView by using two combo box columns. To enable this, two versions of the filtered list (subcategory) needs to be created. One list has no filter applied while the other one will be filtered only when the user is editing a subcategory cell. Two lists are required due to the requirement described in 3.5.1 section that a combo box cells value must be in the items collection or else a DataError event is raised. In this case, since all combo box cells in the column use the same datasource if you filter the datasource for one row then a combo box cell in another row might not have its value visible in the datasource, thus causing a DataError event.

?

The below example uses the Northwind database to display related data from the Territory and Region tables (a territory is in a specific region.) Using the category and subcategory concept, the Region is the category and the Territory is the subcategory.

?

private void Form1_Load(object sender, EventArgs e)

{

??? this.territoriesTableAdapter.Fill(this.northwindDataSet.Territories);

??? this.regionTableAdapter.Fill(this.northwindDataSet.Region);

?

??? // Setup BindingSource for filtered view.

??? filteredTerritoriesBS = new BindingSource();

??? DataView dv = new DataView(northwindDataSet.Tables["Territories"]);

??? filteredTerritoriesBS.DataSource = dv;

?

}

?

private void dataGridView1_CellBeginEdit(object sender,
?????? ?DataGridViewCellCancelEventArgs e)

{

??? if (e.ColumnIndex == territoryComboBoxColumn.Index)

??? {

??????? // Set the combobox cell datasource to the filtered BindingSource

??????? DataGridViewComboBoxCell dgcb = (DataGridViewComboBoxCell)dataGridView1
?????????????????????? [e.ColumnIndex, e.RowIndex];

??????? dgcb.DataSource = filteredTerritoriesBS;

?

??????? // Filter the BindingSource based upon the region selected

??????? this.filteredTerritoriesBS.Filter = "RegionID = " +

??????????? this.dataGridView1[e.ColumnIndex - 1, e.RowIndex].Value.ToString();

??? }

}

?

private void dataGridView1_CellEndEdit(object sender, DataGridViewCellEventArgs e)

{

??? if (e.ColumnIndex == this.territoryComboBoxColumn.Index)

??? {

??????? // Reset combobox cell to the unfiltered BindingSource

??????? DataGridViewComboBoxCell dgcb = (DataGridViewComboBoxCell)dataGridView1
?????????????????????? [e.ColumnIndex, e.RowIndex];

??????? dgcb.DataSource = territoriesBindingSource; //unfiltered

?

??????? this.filteredTerritoriesBS.RemoveFilter();

??? }

}

19. 如何在用戶編輯控件的時候(而不是在驗證時)就顯示錯誤圖標?

在使用錯誤文本和圖標時,有時你希望為用戶提供一個即時反饋,以提示當前的輸入不正確。默認情況下,即使設(shè)置了ErrorText屬性,如果單元格仍處于編輯模式下,那么錯誤圖標也不會顯示,比如TextBoxComboBox。

?

下面的示例演示了如何在CellValidating事件中填充(padding)一個單元格為錯誤圖標提供空間。因為默認情況下填充行為會影響錯誤圖標的位置,該示例(TODO)。The below sample demonstrates how you can set a cell’s padding in the CellValidating event to provide spacing for the error icon. Since padding by default affects the location of the error icon the sample uses the CellPainting to move the position of the icon for painting. Lastly, the sample uses the tooltip control to display a custom tooltip when the mouse is over the cell to indicate what the problem is. This sample could also be written as a custom cell that overrides GetErrorIconBounds method to provide a location for the error icon that was independent of the padding.??

?

private ToolTip errorTooltip;

private Point cellInError = new Point(-2, -2);

public Form1()

{

??? InitializeComponent();

??? dataGridView1.ColumnCount = 3;

??? dataGridView1.RowCount = 10;

}

?

private void dataGridView1_CellValidating(object sender, DataGridViewCellValidatingEventArgs e)

{

??? if (dataGridView1.IsCurrentCellDirty)

??? {

??????? if (e.FormattedValue.ToString() == "BAD")

??????? {

??????????? DataGridViewCell cell = dataGridView1[e.ColumnIndex, e.RowIndex];

??????????? cell.ErrorText = "Invalid data entered in cell";

?

??????????? // increase padding for icon. This moves the editing control

??????????? if (cell.Tag == null)

??????????? {

??????????????? cell.Tag = cell.Style.Padding;

??????????????? cell.Style.Padding = new Padding(0, 0, 18, 0);

?????????????? ?cellInError = new Point(e.ColumnIndex, e.RowIndex);

??????????? }

??????????? if (errorTooltip == null)

??????????? {

??????????????? errorTooltip = new ToolTip();

??????????????? errorTooltip.InitialDelay = 0;

??????????????? errorTooltip.ReshowDelay = 0;

??????????????? errorTooltip.Active = false;

??????????? }

?

??????????? e.Cancel = true;

??????? }

??? }

}

?

private void dataGridView1_CellPainting(object sender, DataGridViewCellPaintingEventArgs e)

{

??? if (dataGridView1.IsCurrentCellDirty && !String.IsNullOrEmpty(e.ErrorText))

??? {

??????? // paint everything except error icon

??????? e.Paint(e.ClipBounds, DataGridViewPaintParts.All &
?????????? ~(DataGridViewPaintParts.ErrorIcon));

?

??????? // now move error icon over to fill in the padding space

??????? GraphicsContainer container = e.Graphics.BeginContainer();

??????? e.Graphics.TranslateTransform(18, 0);

??????? e.Paint(this.ClientRectangle, DataGridViewPaintParts.ErrorIcon);

??????? e.Graphics.EndContainer(container);

?

??????? e.Handled = true;

??? }

}

?

private void dataGridView1_CellEndEdit(object sender, DataGridViewCellEventArgs e)

{

??? if (dataGridView1[e.ColumnIndex, e.RowIndex].ErrorText != String.Empty)

??? {

??????? DataGridViewCell cell = dataGridView1[e.ColumnIndex, e.RowIndex];

??????? cell.ErrorText = String.Empty;

??????? cellInError = new Point(-2,-2);

?

??????? // restore padding for cell. This moves the editing control

??????? cell.Style.Padding = (Padding)cell.Tag;

?

??????? // hide and dispose tooltip

??????? if (errorTooltip != null)

???????{

??????????? errorTooltip.Hide(dataGridView1);

??????????? errorTooltip.Dispose();

??????????? errorTooltip = null;

??????? }

??? }

}

?

// show and hide the tooltip for error

private void dataGridView1_CellMouseMove(object sender,
?????????? DataGridViewCellMouseEventArgs e)

{

??? if (cellInError.X == e.ColumnIndex &&

??????? cellInError.Y == e.RowIndex)

{

DataGridViewCell cell = dataGridView1[e.ColumnIndex, e.RowIndex];

?

??????? if (cell.ErrorText != String.Empty)

??????? {

??????????? if (!errorTooltip.Active)

??????????? {

??????????????? errorTooltip.Show(cell.ErrorText, dataGridView1, 1000);

??????????? }

??????????? errorTooltip.Active = true;

??????? }

??? }

}

?

private void dataGridView1_CellMouseLeave(object sender, DataGridViewCellEventArgs e)

{

??? if (cellInError.X == e.ColumnIndex &&

??????? cellInError.Y == e.RowIndex)

??? {

??????? if (errorTooltip.Active)

??????? {

??????????? errorTooltip.Hide(dataGridView1);

??????????? errorTooltip.Active = false;

??????? }

??? }

}

20. 如何同時顯示綁定數(shù)據(jù)和非綁定數(shù)據(jù)?

The data you display in the DataGridView control will normally come from a data source of some kind, but you might want to display a column of data that does not come from the data source. This kind of column is called an unbound column. Unbound columns can take many forms. ???As discussed in the data section above, you can use virtual mode to display additional data along with bound data.

?

The following code example demonstrates how to create an unbound column of check box cells to enable the user to select database records to process. The grid is put into virtual mode and responds to the necessary events. The selected records are kept by ID in a dictionary to allow the user to sort the content but not lose the checked rows.

?

private System.Collections.Generic.Dictionary<int, bool> checkState;

private void Form1_Load(object sender, EventArgs e)

{

??? dataGridView1.AutoGenerateColumns = false;

??? dataGridView1.DataSource = customerOrdersBindingSource;

?

??? // The check box column will be virtual.

??? dataGridView1.VirtualMode = true;

??? dataGridView1.Columns.Insert(0, new DataGridViewCheckBoxColumn());

?

??? // Initialize the dictionary that contains the boolean check state.

??? checkState = new Dictionary<int, bool>();

}

private void dataGridView1_CellValueChanged(object sender, DataGridViewCellEventArgs e)

{

??? // Update the status bar when the cell value changes.

??? if (e.ColumnIndex == 0 && e.RowIndex != -1)

??? {

??????? // Get the orderID from the OrderID column.

??????? int orderID = (int)dataGridView1.Rows[e.RowIndex].Cells["OrderID"].Value;

??????? checkState[orderID] = (bool)dataGridView1.Rows[e.RowIndex].Cells[0].Value;

?

}

?

private void dataGridView1_CellValueNeeded(object sender, DataGridViewCellValueEventArgs e)

{

??? // Handle the notification that the value for a cell in the virtual column

??? // is needed. Get the value from the dictionary if the key exists.

?

??? if (e.ColumnIndex == 0)

??? {

??????? int orderID = (int)dataGridView1.Rows[e.RowIndex].Cells["OrderID"].Value;

??????? if (checkState.ContainsKey(orderID))

??????? {

??????????? e.Value = checkState[orderID];

??????? }

??????? else

??????????? e.Value = false;

??? }

?

}

?

private void dataGridView1_CellValuePushed(object sender, DataGridViewCellValueEventArgs e)

{

??? // Handle the notification that the value for a cell in the virtual column

??? // needs to be pushed back to the dictionary.

?

??? if (e.ColumnIndex == 0)

??? {

??????? // Get the orderID from the OrderID column.

??????? int orderID = (int)dataGridView1.Rows[e.RowIndex].Cells["OrderID"].Value;

?

??????? // Add or update the checked value to the dictionary depending on if the

??????? // key (orderID) already exists.

??????? if (!checkState.ContainsKey(orderID))

??????? {

??????????? checkState.Add(orderID, (bool)e.Value);

??????? }

??? ????else

??????????? checkState[orderID] = (bool)e.Value;

??? }

}

21. How do I show data that comes from two tables(TODO)?

The DataGridView does not provide any new features apart from virtual mode to enable this. What you can do is use the JoinView class described in the following article http://support.microsoft.com/default.aspx?scid=kb;en-us;325682. Using this class you can join two or more DataTables together. This JoinView can then be databound to the DataGridView.

22. 如何顯示主從表?

使用DataGridView時最常見的情況之一就是主從表單,這時要顯示具有主從關(guān)系的兩個數(shù)據(jù)表。在主表中選擇一行記錄,從表中也會隨之變化,顯示相應(yīng)的記錄。

?

通過DataGridView控件和BindingSource 組件的交互作用來實現(xiàn)主從表單是非常簡單的。下面的示例演示的是SQL Server的范例數(shù)據(jù)庫Northwind 中的兩個表:Customers Orders。在主DataGridView中選擇一個顧客,那么該顧客的所有訂單會顯示在從DataGridView 中。

?

?

using System;

using System.Data;

using System.Data.SqlClient;

using System.Windows.Forms;

?

public class Form1 : System.Windows.Forms.Form

{

??? private DataGridView masterDataGridView = new DataGridView();

??? private BindingSource masterBindingSource = new BindingSource();

??? private DataGridView detailsDataGridView = new DataGridView();

??? private BindingSource detailsBindingSource = new BindingSource();

?

??? [STAThreadAttribute()]

??? public static void Main()

??? {

??????? Application.Run(new Form1());

??? }

?

??? // Initializes the form.

??? public Form1()

??? {

??????? masterDataGridView.Dock = DockStyle.Fill;

??????? detailsDataGridView.Dock = DockStyle.Fill;

?

??????? SplitContainer splitContainer1 = new SplitContainer();

??????? splitContainer1.Dock = DockStyle.Fill;

??????? splitContainer1.Orientation = Orientation.Horizontal;

??????? splitContainer1.Panel1.Controls.Add(masterDataGridView);

??????? splitContainer1.Panel2.Controls.Add(detailsDataGridView);

?

??????? this.Controls.Add(splitContainer1);

??????? this.Load += new System.EventHandler(Form1_Load);

??????? this.Text = "DataGridView master/detail demo";

??? }

?

??? private void Form1_Load(object sender, System.EventArgs e)

??? {

??????? // Bind the DataGridView controls to the BindingSource

???? ???// components and load the data from the database.

??????? masterDataGridView.DataSource = masterBindingSource;

??????? detailsDataGridView.DataSource = detailsBindingSource;

??????? GetData();

?

??????? // Resize the master DataGridView columns to fit the newly loaded data.

??????? masterDataGridView.AutoResizeColumns();

?

??????? // Configure the details DataGridView so that its columns automatically

??????? // adjust their widths when the data changes.

??????? detailsDataGridView.AutoSizeColumnsMode =

??????????? DataGridViewAutoSizeColumnsMode.AllCells;

??? }

?

??? private void GetData()

??? {

??????? try

??????? {

??????????? // Specify a connection string. Replace the given value with a

??????????? // valid connection string for a Northwind SQL Server sample

??????????? // database accessible to your system.

??????????? String connectionString =

??????????????? "Integrated Security=SSPI;Persist Security Info=False;" +

??????????????? "Initial Catalog=Northwind;Data Source=localhost";

??????????? SqlConnection connection = new SqlConnection(connectionString);

?

??????????? // Create a DataSet.

??????????? DataSet data = new DataSet();

??????????? data.Locale = System.Globalization.CultureInfo.InvariantCulture;

?

??????????? // Add data from the Customers table to the DataSet.

??????????? SqlDataAdapter masterDataAdapter = new

??????????????? SqlDataAdapter("select * from Customers", connection);

??????????? masterDataAdapter.Fill(data, "Customers");

?

??????????? // Add data from the Orders table to the DataSet.

??????????? SqlDataAdapter detailsDataAdapter = new

??????????????? SqlDataAdapter("select * from Orders", connection);

??????????? detailsDataAdapter.Fill(data, "Orders");

?

??????????? // Establish a relationship between the two tables.

??????????? DataRelation relation = new DataRelation("CustomersOrders",

??????????????? data.Tables["Customers"].Columns["CustomerID"],

??????????????? data.Tables["Orders"].Columns["CustomerID"]);

??????????? data.Relations.Add(relation);

?

??????????? // Bind the master data connector to the Customers table.

??????????? masterBindingSource.DataSource = data;

??????????? masterBindingSource.DataMember = "Customers";

?

??????????? // Bind the details data connector to the master data connector,

??????????? // using the DataRelation name to filter the information in the

??????????? // details table based on the current row in the master table.

??????????? detailsBindingSource.DataSource = masterBindingSource;

??????????? detailsBindingSource.DataMember = "CustomersOrders";

??????? }

??????? catch (SqlException)

??????? {

MessageBox.Show("To run this example, replace the value of the " +

??????????????? "connectionString variable with a connection string that is " +

??????????????? "valid for your system.");

??????? }

??? }

}

23. 如何在同一DataGridView中顯示主從表?

DataGridView 不支持在同一DataGridView 中顯示主從表。Windows Forms的先前版本中的DataGrid控件或許是你需要的一個解決方案。

24. 如何避免用戶對列排序?

對于DataGridView 控件,默認情況下,TextBox類型的列會自動排序,而其它類型的列則不會自動排序。這種自動排序有時會把數(shù)據(jù)變得比較亂,這時你會想更改這些默認設(shè)置。

?

DataGridViewColumn的屬性SortMode決定了列的排序方式,將其設(shè)置為DataGridViewColumnSortMode.NotSortable就可以避免默認的排序行為。

25. 如何在點擊工具欄按鈕的時候?qū)?shù)據(jù)提交到數(shù)據(jù)庫?

默認情況下,操作工具欄或菜單不會導(dǎo)致對控件的驗證。但對于綁定控件來說,提交數(shù)據(jù)前進行驗證是必要的。而一旦窗體和其中的所有控件得到驗證,當前編輯過的數(shù)據(jù)就需要提交。最后,數(shù)據(jù)適配器(SqlDataAdapter)需要將數(shù)據(jù)的修改寫入數(shù)據(jù)庫。要達到這個效果,將下面三行代碼加到相應(yīng)的事件處理函數(shù)(指工具欄按鈕或菜單項的事件)內(nèi):

?

this.Validate();

this.customersBindingSource.EndEdit();??????????? this.customersTableAdapter.Update(this.northwindDataSet.Customers);

26. 如何在用戶刪除記錄時顯示確認對話框?

當用戶選擇DataGridView的一行,按下Delete鍵時就會觸發(fā)UserDeletingRow 事件。你可以提示用戶是否確定要刪除該行記錄,建議僅在用戶要刪除已存在的記錄(而不是用戶添加的新行)時才進行這種提示。將下面這些代碼添加到UserDeletingRow事件的處理方法中就可以實現(xiàn)這種功能:

?

if (!e.Row.IsNewRow)

{

??? DialogResult response = MessageBox.Show("Are you sure?", "Delete row?",
?????????? ?MessageBoxButtons.YesNo,
?????????? ?MessageBoxIcon.Question,
?????????? ?MessageBoxDefaultButton.Button2);

??? if (response == DialogResult.No)

??????? e.Cancel = true;

}

?

?

轉(zhuǎn)載于:https://www.cnblogs.com/zoupeiyang/archive/2009/07/07/1518174.html

總結(jié)

以上是生活随笔為你收集整理的(转)使用DataGridView控件常见问题解答的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網(wǎng)站內(nèi)容還不錯,歡迎將生活随笔推薦給好友。

主站蜘蛛池模板: 欧美黄色特级视频 | 91免费影片| www.色播.com | 亚洲天堂男人天堂 | 少妇太紧太爽又黄又硬又爽 | 午夜亚洲精品 | 手机在线看片国产 | 久久无码人妻一区二区三区 | 狠狠操网站 | 久色电影 | 国产精品久久久久高潮 | 丰满人妻一区二区三区免费视频棣 | 毛片综合 | 日本一级黄| 麻豆高清| 国产高中女学生第一次 | 成人3d动漫一区二区三区91 | 久久国产精品久久 | 视频网站在线观看18 | 国产第一页在线播放 | 韩日av| 在线视频精品一区 | 国产精品片 | 无码人妻aⅴ一区二区三区 国产高清一区二区三区四区 | 免费观看av网址 | 就去色av | 欧美三级大片 | 天天搞夜夜爽 | 乱日视频| 中文字幕网站在线观看 | 毛片内射 | 中日韩精品视频在线观看 | 中文字字幕第183页 欧美特级一级片 | 射射射综合网 | 91视频看看 | 亚洲第一在线视频 | 天堂一区在线观看 | 欧美一级做a爰片久久高潮 久热国产精品视频 | 欧美在线视频一区二区 | 亚洲欧美在线一区二区 | 五月激情网站 | 山村大伦淫第1部分阅读小说 | 91九色论坛 | 鬼灭之刃柱训练篇在线观看 | 国产精品乱码久久久久 | www.色人阁| 欧美自拍一区 | 在线观看中文字幕一区二区 | jizz国产在线观看 | 国产精品香蕉国产 | 国产精品久久久久久久久久 | 精品久久国产视频 | 久久r视频 | 欧美性受xxx | 黄色免费高清 | 国产午夜片 | 国产手机在线观看 | 国产精品永久久久久久久久久 | a级无遮挡超级高清-在线观看 | 一区二区免费在线视频 | 午夜视 | 福利在线播放 | 综合激情网五月 | 精品一级少妇久久久久久久 | 欧美精品日韩精品 | 亚洲国产97在线精品一区 | 国产免费一区二区三区四区五区 | 久久99一区二区 | 国产农村妇女毛片精品 | 欧美三级一区二区三区 | 日韩污视频| www.199麻豆| 午夜视频在线免费看 | 婷婷爱五月天 | 麻豆国产一区二区三区 | 日韩一区二区三区不卡视频 | www插插插无码免费视频网站 | 中文字幕人妻无码系列第三区 | 日韩在线黄色 | 丁香六月啪啪 | 毛片视频大全 | 特级毛片在线播放 | 超碰人人超碰 | 欧美视频色| 无码国产精品一区二区高潮 | 精品一区二区三区免费视频 | 波多野结衣三级视频 | h视频免费在线观看 | 亚洲欧美日韩偷拍 | 水牛影视av一区二区免费 | 操www| 日韩国产欧美在线观看 | 欧美日韩一区二区在线观看视频 | www.久草.com| 成人影片在线播放 | 男人和女人在床的app | 麻豆一区二区三区在线观看 | 中国一级特黄真人毛片免费观看 | a黄色一级片 |