Hi,
I need a big help to resolve this problem.
I need to put a usercontrol in a datagrid: this control check if the code
inserted is present in a archive and if not return a error message.
(In the example I have changed this check with a easy "if string is empty" )
Everything would be easy if the datagrid had a predictable behaviour.
I explain my problem.
If you try to compile and use the example, you can see that if I press the
return key, the validating event isn't called .......
else
if I press the key tab, the validation event is called, but the grid takes
the focus on the next object without waiting for the result of the
validation.
The result is a three times error message and the grid blocked ( with mouse
you can't change the cell ): only a shift-tab permit to return on the cell
with the blank code.
Where do I make a mistake?
Thanks
Mauro
To respond leave NOSPAM to my e-mail address.
ma******@NOSPAMLibero.it
using System;
using System.Drawing;
using System.Collections;
using System.ComponentModel;
using System.Windows.Forms;
using System.Data;
namespace HelpMe
{
/// <summary>
/// Summary description for Form1.
/// </summary>
public class Form1 : System.Windows.Forms.Form
{
private System.Windows.Forms.DataGrid dataGrid1;
/// <summary>
/// Required designer variable.
/// </summary>
private System.ComponentModel.Container components = null;
private DataTable myTable = null;
private DataColumn myCol1, myCol2 = null;
private MyTextBox myTextBox = null;
private System.Windows.Forms.DataGridTableStyle dataGridTableStyle1;
private System.Windows.Forms.DataGridTextBoxColumn dataGridTextBoxColumn1;
private DataGridControlColumn dataGridTextBoxColumn2;
public Form1()
{
//
// Required for Windows Form Designer support
//
InitializeTable();
InitializeComponent();
//
// TODO: Add any constructor code after InitializeComponent call
//
}
/// <summary>
/// Clean up any resources being used.
/// </summary>
protected override void Dispose( bool disposing )
{
if( disposing )
{
if (components != null)
{
components.Dispose();
}
}
base.Dispose( disposing );
}
#region Windows Form Designer generated code
/// <summary>
/// Required method for Designer support - do not modify
/// the contents of this method with the code editor.
/// </summary>
private void InitializeComponent()
{
this.myTextBox = new MyTextBox();
this.dataGrid1 = new System.Windows.Forms.DataGrid();
this.dataGridTableStyle1 = new System.Windows.Forms.DataGridTableStyle();
this.dataGridTextBoxColumn1 = new
System.Windows.Forms.DataGridTextBoxColumn();
this.dataGridTextBoxColumn2 = new DataGridControlColumn(myTextBox);
((System.ComponentModel.ISupportInitialize)(this.d ataGrid1)).BeginInit();
this.SuspendLayout();
//
// dataGrid1
//
this.dataGrid1.DataSource = myTable;
this.dataGrid1.DataMember = "";
this.dataGrid1.HeaderForeColor = System.Drawing.SystemColors.ControlText;
this.dataGrid1.Location = new System.Drawing.Point(8, 16);
this.dataGrid1.Name = "dataGrid1";
this.dataGrid1.Size = new System.Drawing.Size(272, 128);
this.dataGrid1.TabIndex = 0;
this.dataGrid1.TableStyles.AddRange(new
System.Windows.Forms.DataGridTableStyle[] {
this.dataGridTableStyle1});
//
// dataGridTableStyle1
//
this.dataGridTableStyle1.DataGrid = this.dataGrid1;
this.dataGridTableStyle1.GridColumnStyles.AddRange (new
System.Windows.Forms.DataGridColumnStyle[] {
this.dataGridTextBoxColumn1,
this.dataGridTextBoxColumn2});
this.dataGridTableStyle1.HeaderForeColor =
System.Drawing.SystemColors.ControlText;
this.dataGridTableStyle1.MappingName = "myTable";
//
// dataGridTextBoxColumn1
//
this.dataGridTextBoxColumn1.Format = "";
this.dataGridTextBoxColumn1.FormatInfo = null;
this.dataGridTextBoxColumn1.HeaderText = "First";
this.dataGridTextBoxColumn1.MappingName = "Col1";
this.dataGridTextBoxColumn1.Width = 75;
//
// dataGridTextBoxColumn2
//
this.dataGridTextBoxColumn2.HeaderText = "Second";
this.dataGridTextBoxColumn2.MappingName = "Col2";
this.dataGridTextBoxColumn2.Width = 75;
//
// myTextBox
//
this.myTextBox.Validating+=new CancelEventHandler(myTextBox_Validating);
//
// Form1
//
this.AutoScaleBaseSize = new System.Drawing.Size(5, 13);
this.ClientSize = new System.Drawing.Size(292, 266);
this.Controls.Add(this.dataGrid1);
this.Name = "Form1";
this.Text = "Form1";
((System.ComponentModel.ISupportInitialize)(this.d ataGrid1)).EndInit();
this.ResumeLayout(false);
}
#endregion
/// <summary>
/// The main entry point for the application.
/// </summary>
[STAThread]
static void Main()
{
Application.Run(new Form1());
}
private void InitializeTable()
{
myTable = new DataTable("MyTable");
myCol1 = new DataColumn("Col1", typeof(System.String));
myCol2 = new DataColumn("Col2", typeof(System.String));
myTable.Columns.Add(myCol1);
myTable.Columns.Add(myCol2);
DataRow myRow = myTable.NewRow();
myRow["Col1"] = "a";
myRow["Col2"] = "b";
myTable.Rows.Add(myRow);
}
private void myTextBox_Validating(object sender, CancelEventArgs e)
{
if (myTextBox.Text == string.Empty)
{
MessageBox.Show("Empty not valid");
e.Cancel = true;
}
}
}
#region DataGridControlColumn
/// <summary>
/// Summary description for DataGridControlBoxColumn.
/// </summary>
// This example shows how to create your own column style that
// hosts a control, in this case, a DateTimePicker.
public class DataGridControlColumn : DataGridColumnStyle
{
private MyTextBox myControl = null;
private bool isEditing;
public DataGridControlColumn(MyTextBox mycontrol) : base()
{
myControl = mycontrol;
mycontrol.Visible = false;
mycontrol.BorderStyle = BorderStyle.None;
myControl.TextChanged+=new EventHandler(myControl_TextChanged);
// myControl.Validating+=new
System.ComponentModel.CancelEventHandler(myControl _Validating);
}
protected override void Abort(int rowNum)
{
isEditing = false;
Invalidate();
}
protected override bool Commit(CurrencyManager dataSource, int rowNum)
{
myControl.Bounds = Rectangle.Empty;
if (!isEditing)
return true;
isEditing = false;
try
{
object value = myControl.Text;
SetColumnValueAtRow(dataSource, rowNum, value);
}
catch (Exception exc)
{
MessageBox.Show(exc.Message);
Abort(rowNum);
return false;
}
try
{
Invalidate();
return true;
}
catch (Exception exc)
{
MessageBox.Show(exc.Message);
return false;
}
}
protected override void Edit(
CurrencyManager source,
int rowNum,
Rectangle bounds,
bool readOnly,
string instantText,
bool cellIsVisible)
{
object value = GetColumnValueAtRow(source, rowNum);
if (cellIsVisible)
{
myControl.Bounds = new Rectangle
(bounds.X + 2, bounds.Y + 2,
bounds.Width - 4, bounds.Height - 4);
myControl.Text = (value == System.Convert.DBNull) ? string.Empty :
(string)value;
myControl.Visible = true;
myControl.TextChanged+=new EventHandler(myControl_TextChanged);
myControl.Enabled = !this.DataGridTableStyle.ReadOnly;
myControl.Focus();
}
else
{
myControl.Text = (value == System.Convert.DBNull) ? string.Empty :
(string)value;
myControl.Visible = false;
}
if (myControl.Visible)
DataGridTableStyle.DataGrid.Invalidate(bounds);
}
protected override Size GetPreferredSize(
Graphics g,
object value)
{
return new Size(100, myControl.Height - 4);
}
protected override int GetMinimumHeight()
{
return myControl.Height - 4;
}
protected override int GetPreferredHeight(Graphics g,
object value)
{
return myControl.Height - 4;
}
protected override void Paint(Graphics g,
Rectangle bounds,
CurrencyManager source,
int rowNum)
{
Paint(g, bounds, source, rowNum, false);
}
protected override void Paint(
Graphics g,
Rectangle bounds,
CurrencyManager source,
int rowNum,
bool alignToRight)
{
Paint(
g,bounds,
source,
rowNum,
Brushes.Red,
Brushes.Blue,
alignToRight);
}
protected override void Paint(
Graphics g,
Rectangle bounds,
CurrencyManager source,
int rowNum,
Brush backBrush,
Brush foreBrush,
bool alignToRight)
{
object value =
GetColumnValueAtRow(source, rowNum);
string text = (value == System.Convert.DBNull) ? string.Empty :
(string)value;
Rectangle rect = bounds;
g.FillRectangle(backBrush,rect);
rect.Offset(0, 2);
rect.Height -= 2;
g.DrawString(text,
this.DataGridTableStyle.DataGrid.Font,
foreBrush, rect);
}
protected override void SetDataGridInColumn(DataGrid value)
{
base.SetDataGridInColumn(value);
if (myControl.Parent != null)
{
myControl.Parent.Controls.Remove
(myControl);
}
if (value != null)
{
value.Controls.Add(myControl);
}
}
private void myControl_TextChanged(object sender, EventArgs e)
{
if (myControl.Parent != null)
if (((DataGrid) myControl.Parent).ReadOnly) return;
this.isEditing = true;
base.ColumnStartedEditing(myControl);
}
// private void myControl_Validating(object sender,
System.ComponentModel.CancelEventArgs e)
// {
// if (myControl.Text == string.Empty)
// {
// MessageBox.Show("Not valid");
// e.Cancel = true;
// }
// }
}
#endregion
#region MyTextBox
/// <summary>
/// MyTextBox inherited from TextBox to
/// remove the Tab KEYUP message to avoid
/// focus problem
/// </summary>
public class MyTextBox : System.Windows.Forms.TextBox
{
const int WM_KEYDOWN=0x100;
const int WM_KEYUP=0x101;
public override bool PreProcessMessage(
ref System.Windows.Forms.Message msg)
{
Keys keyCode=(Keys)(int)msg.WParam & Keys.KeyCode;
if(msg.Msg==WM_KEYUP && keyCode==Keys.Tab)
{
msg.WParam=(System.IntPtr)0;
return true;
}
if (msg.Msg == WM_KEYDOWN)
{
// if (keyCode == Keys.Return || keyCode == Keys.Down)
// msg.WParam = (IntPtr)Keys.Tab;
if (keyCode == Keys.Up)
msg.WParam = (IntPtr)((int) Keys.Tab | (int)Keys.Shift);
}
return base.PreProcessMessage(ref msg);
}
}
#endregion
}