Kuidas kustutada ridu Windows Forms DataGrid’ist
30.03.2006 | GunnarNagu selgub, siis Windows Forms DataGrid'is on läbi andmeallika sündmuste võimatu vahele sekkuda andmete kustutamisele. Kuigi kustutamisel läbib muutunud rida samasuguse sündmusteahela nagu kõikide muude protseduuride korral, läheb DataGrid andmete kustutamisel pisut sassi, kui kustutamine tühistada.
Kustutamist saab kontrollida ka andmeallika sündmuste kaudu, kuid DataGrid ei saa aru kustutamisest loobumisest. Peale loobumist kaob rida küll ära, kuid kui liikuda viimasele uuele reale ja sealt tab'iga ringi liikuda, siis tulevad nähtavale tegelikult olemasoleva rea andmed. Seega rida kustub DataGrid'ist ainult, kuid jääb alles DataGrid'i andmeallikasse. Selge, et selline käitumine pole normaalne ning vaja on mingisugust head lahendust.
Lahenduseks on DataGrid'i subclassimine. Subclassimisel tuleb tuvastada, kas rida on märgitud rea selektoril klikkimisega. Seejärel kontrollime teadete töötlemise meetodites nupuvajutust. Kui rida oli märgitud ja vajutada Delete'i, siis näitame dialoogi, kus küsime kasutaja kinnitust. Kui kasutaja vastas eitavalt, siis antud teadet me baasklassile edasi ei saada. See on kogu lahendus.
ExtDataGrid.cs
{
private DataGrid.HitTestInfo pHitTestInfo;
public ExtDataGrid() : base() {}
public override bool PreProcessMessage(ref System.Windows.Forms.Message msg)
{
int WM_KEYDOWN = 0x100;
Keys keyCode = (Keys)(msg.WParam.ToInt32() & (int)Keys.KeyCode);
if ((keyCode == Keys.Delete) & (msg.Msg == WM_KEYDOWN))
if (bConfirmDelete)
if (MessageBox.Show(this.sDeleteMessage, this.sDeleteTitle,
MessageBoxButtons.YesNo, MessageBoxIcon.Question,
MessageBoxDefaultButton.Button2) == DialogResult.No)
return true;
return base.PreProcessMessage(ref msg);
}
protected override bool ProcessDialogKey(System.Windows.Forms.Keys KeyData)
{
if (KeyData == Keys.Delete)
if (this.pHitTestInfo.Type==HitTestType.RowHeader)
if (this.bConfirmDelete)
if (MessageBox.Show(this.sDeleteMessage, this.sDeleteTitle,
MessageBoxButtons.YesNo, MessageBoxIcon.Question,
MessageBoxDefaultButton.Button2) == DialogResult.No)
return true;
return false;
}
protected override void OnMouseDown(MouseEventArgs e)
{
this.pHitTestInfo = this.HitTest(new Point(e.X, e.Y));
base.OnMouseDown(e);
}
}
Vormide code behind failides tuleb nüüd DataGrid asendada uue klassiga, mille saime laiendamise tulemusena. Kõik jääb toimima täpselt nii nagu enne. Peale selle, kui kirjutada subclassitud DataGrid'ile avalikke omadusi juurde, siis saab nende väärtusi vaadata ja muuta vormidisaineri omaduste akna kaudu.

30.03.2006 kell 22:06
Nice!
Aga veidi liblikate keeles küll minu jaoks