Tab Stops in DataGrid

  • Thread starter Thread starter Guest
  • Start date Start date
G

Guest

Hi
How do you keep selected columns in a datagrid from being tab stops
Appreciate any help
JT
 
One way to do TAB processing is to create a custom DataGrid that derives
from "System.Windows.Forms.DataGrid" and override the "ProcessCmdKey"
method. The following code will cause a TAB in the DataGrid to jump to the
another control, forward or backward, depending on the state of SHIFT. If
you are planning on processing TAB's depending on actual columns then you
just need to incorporate the appropriate check to determine the current
column.

public class CustomDataGrid : System.Windows.Forms.DataGrid
{
protected override bool ProcessCmdKey(ref Message msg, Keys keyData)
{
if ((keyData & Keys.Tab) > 0)
{
this.TopLevelControl.SelectNextControl(this, (!((keyData & Keys.Shift)
0)), true, true, true);
return true;
}
return base.ProcessCmdKey(ref msg, keyData);
}
}
 
Tim's post is similar to what I was going to suggest (before my session
timed out and I lost everything I had typed) only I'm not sure that what
Tim is suggesting would perform correctly if you have two read only
columns in a row. I am assuming that not all columns will be read only.
I would suggest changing Tim's code to do a sendkey and send another Tab
instead of selecting next control. Down side is you will have to do an
&& on keyData & Keys.Tab and keyData & Keys.Shift and sendkey the
appropriate combination of these keys if needed. Technically the
selectNextControl is a better design but I'm not sure it will function
properly on two read only columns in a row. I'm going to do some code
this afternoon to test this cause I'm not sure of the behavior.
 
public class CustomDataGrid : System.Windows.Forms.DataGri

protected override bool ProcessCmdKey(ref Message msg, Keys keyData

if ((keyData & Keys.Tab) > 0

this.TopLevelControl.SelectNextControl(this, (!((keyData & Keys.Shift
0)), true, true, true)
return true

return base.ProcessCmdKey(ref msg, keyData)



My replies don't seem to be going through so I'm posting through another server. Sorry for the delay. Tim's code from above is similar to the method I was going to suggest. I'm assuming you have mixed columns (read only sometimes). I would suggest using a send key for the tabs instead of the selectnextcontrol because I don't believe that will invoke the ProcessCmdKey method on the next column and if the next column is readonly then you still have a problem. This adds some work to the situation though since you have to determine which direction you are going (SHIFT+TAB or TAB). Also, neither of these solutions provide any help if the user simply clicks on the cell. Below is some code I used to select the entire row of a datagrid when a user clicks on a cell and the datasource is a dataview. There is some additional logic in it that allows/disallows editing/deleting based upon the current state of the dataview but that's not as important. I believe you could modify this to do what you are looking to do

<code
public class ControlledDeleteDataGrid : System.Windows.Forms.DataGrid

private int currentRow = -1
protected override bool ProcessKeyPreview( ref Message msg )
{
// unselect the currently selected row/cell/..
if(currentRow > -1 && currentRow < this.ListManager.List.Count + 1)
this.UnSelect(currentRow);

// select the row from abov
this.Select( (currentRow=this.CurrentRowIndex) )

Keys keyCode = (Keys)(int)msg.WParam & Keys.KeyCode;

// if the keydown was delete and deletes are allowe
if(msg.Msg == WM_KEYDOWN
&& keyCode == Keys.Delete
&& this.DataSource is DataVie
&& ((DataView) this.DataSource).AllowDelete)
{
if(MessageBox.Show("Are you sure you want this row deleted?", "Confirm Delete", MessageBoxButtons.YesNo) == DialogResult.No)

return true

}
// if the keydown was anything else and edits are allowe
else if (msg.Msg == WM_KEYDOWN
&& this.DataSource is DataVie
&& ((DataView) this.DataSource).AllowEdit)

return true


// if none of the other conditions are met pass message on to base pre processin
return base.PreProcessMessage(ref msg);
}

// win32 message id const
private const int WM_KEYDOWN = 0x100
private const int WM_KEYUP = 0x101
</code>
 
Hi JT,

Tim and Michael have given some sample code to skip the column when you
press "tab" key.
If it is a text column and you want to prevent this column from selected
(by keyboard or by mouse) you may also try this way:
1. define a table style for your table
2. add an event handler to the inner TextBox of the DataGridTextBoxColumn
you want to skip.
3. In the event handler, move the CurrentCell to the next cell in the grid.
the code skeleton is like below:
<code>
private void Form1_Load(object sender, System.EventArgs e)
{
// assume you had defined the table style for the table.
DataGridTextBoxColumn tbc =
dataGrid1.TableStyles["TableName"].GridColumnStyles["CategoryName"] as
DataGridTextBoxColumn;
tbc.TextBox.Enter +=new EventHandler(TextBox_Enter);
}
private void TextBox_Enter(object sender, EventArgs e)
{
DataGridTextBox textBox = (DataGridTextBox)sender;
DataGrid dataGrid = (DataGrid)textBox.Parent;

textBox.Visible = false;

if (dataGrid1.CurrentCell.ColumnNumber+1 <
dataGrid.TableStyles[0].GridColumnStyles.Count)
{
dataGrid1.CurrentCell = new DataGridCell(dataGrid1.CurrentCell.RowNumber,
dataGrid1.CurrentCell.ColumnNumber+1);
}
else
{
dataGrid1.CurrentCell = new
DataGridCell(dataGrid1.CurrentCell.RowNumber+1,0);
}
}
</code>

Does this way work for you?

Thanks.

Best regards,

Ying-Shen Yu [MSFT]
Microsoft community Support
Get Secure! - www.microsoft.com/security

This posting is provided "AS IS" with no warranties and confers no rights.
This mail should not be replied directly, please remove the word "online"
before sending mail.
 
Thank you to everybody. I especially appreciate your persistence in the face of the time-out. These message boards are a great resource
JT
 
Back
Top