Suppose I have a DataGrid and a Button. CanUserAddRows is set to True. Let this dataGrid have two DataGridTextColumns namely "Name" and "Age".
Now if user takes the following actions :
He adds name as XYZ and Age as 20. Then he press enter. So a new row will be added to the datagrid.
He adds name as ABC and Age as 12. Then he press enter. So a new row will be added to the datagrid.
He keeps name empty and press Enter or TAB then I want to move focus to Button instead of next cell of datagrid.
I have watched many questions but I don't get the logic of if user left the name empty and how do I move focus to Button instead of next cell.
Use DataGridView.SelectedCells[0] so you can retrieve the value of the selected cell (assuming you can only select one).
To get the actual string inside, you will have to cast the content to a proper WPF object, like TextBlock.
myCell.Column.GetCellContent(cell.Item) as TextBlock
Then in a PreviewKeyDown event handler (KeyDown having known issues in DataGridView), you can use button.Focus(). (more about those issues)
//...
myDataGrid1.PreviewKeyDown += myDataGrid1_KeyDown;
//...
void myDataGrid1_PreviewKeyDown(object sender, System.Windows.Input.KeyEventArgs e)
{
if (e.Key == System.Windows.Input.Key.Enter)
{
var cell = myDataGrid1.SelectedCells[0];
TextBlock cellContent = cell.Column.GetCellContent(cell.Item) as TextBlock;
if (cellContent != null)
{
if (String.IsNullOrWhitespace(cellContent.Text))
button.Focus();
}
}
}
About getting the column's name, it's another question, for which you can find answer here for example.
As a side note, you're not really supposed to interact directly with a DataGridView cells' values, since it's meant to be bound with a data source from which you should retrieve the data you want to test. However, you can search a bit for helper methods that can help you get what you want.
You can define a handler for the DataGrid.KeyDown event, as:
void myDataGrid1_KeyDown(object sender, System.Windows.Input.KeyEventArgs e)
{
if (e.Key == System.Windows.Input.Key.Enter)
{
button.Focus();
}
}
Related
I am having trouble with a databound datagridviewcomboboxcell
I want to remove the blue selection line that appears on a databound comboboxcell.
I noticed that if a comboboxcell is not databound but has a collection of items, the blue line does not appear. however a databound combobox does have it.
item collection
Databound
You will see in the first picture there is no blue selection line however in the next picture(databound comboboxcell) there is...
I need to take this selection line away so that when the databound comboboxcell has only one row of data, a user can through only keyboard inputs can make a selection.
I initially tried to add a keyDown event to set the Items[index] which did change the value, however, when i move off the cell, it displays the Model Name and namespace. Then when going back on to the cell it displays the value.
I used the following code to do this:
I added a keydown event to the combobox, and here is the keydown event
private void dataGridView_KeyDown(object sender, KeyEventArgs e)
{
if (e.KeyCode == Keys.Enter)
{
if (dataGridView1.Columns[dataGridView1.CurrentCell.ColumnIndex].CellType.Name == "DataGridViewComboBoxCell" && dataGridView1.CurrentCell.ReadOnly == false)
{
DataGridViewRow row = dataGridView1.CurrentRow;
try
{
if ((row.Cells[dataGridView1.CurrentCell.ColumnIndex] as DataGridViewComboBoxCell).Items.Count == 1)
{
(dataGridView1.CurrentRow.Cells[dataGridView1.CurrentCell.ColumnIndex] as DataGridViewComboBoxCell).Value = taxcodes[0];
(dataGridView1.CurrentRow.Cells[dataGridView1.CurrentCell.ColumnIndex] as DataGridViewComboBoxCell).DisplayMember = "FullDescription";
(dataGridView1.CurrentRow.Cells[dataGridView1.CurrentCell.ColumnIndex] as DataGridViewComboBoxCell).ValueMember = "TaxID";
}
}
catch
{
}
}
}
Now that I have attempted to change set the value of the combobox without luck, I am on to the next possible solution i can maybe get to work.
If i can make the Combobox have a no selection line when it opnes initially then as soon as that line moves on to the only item in the list it will select give the ability to select that as the value.
NOTE: a databound comboboxcell with more than one items, works well
NOTE: a non-databound comboboxcell with items defined works well, however i need a displaymember as well as value member
The ideal outcome from this query will give me the ability to select a databound combobox item(making use of the ENTER key) when the combobox has only one item.
Final NOTE: when i use the mouse to make the selection on the databound comboboxcell with ony 1 item, it works perfectly.
Thanks for the help if anyone can help
So after consulting a friend, I managed to override the .ToString() method
public override string ToString()
{
return FullDescription;
}
This worked for me in this case and the Keydown route was the correct route to go.
First of all, I know that there are probably better solutions and I am very willing to listen to those solutions. I have searched around the internet looking for a problem like this but am unable to find one that works so far. I have multiple textboxes on a form, when the user clicks on the textbox I run a method that finds out which textbox is focused, gets the tag of that textbox and the name of the textbox both as strings (TextboxX and test). My goal is to mask the textboxes with for example 'Email' and when the user clicks on the textbox the textbox forecolor changes to black and the textbox text is null, with as little code as possible.
Here is the code i have for that.
public void masked()
{
if (textboxX.Text == test)
{
textboxX.ForeColor = Color.Black;
textboxX.Text = "";
}
else
{
textboxX.Select(0, textboxX.Text.Length);
}
}
When the textbox is clicked this is what it does currently.
private void txtSignup_email_Click(object sender, EventArgs e)
{
textboxX = txtSignup_email;
test = "Email";
masked();
}
The reason for this is that I have 7 textboxes, it will save me about 14 lines of code that is actually not necessary. Thanks in advance.
OK there are a few things that can be done better.
First of all you can use Password instead of TextBox which is automatically masked and can't be seen if I understand you requirement correctly.
Second thing is what ainwood said in the comment you can point all clicked or focused events of your textboxes to a single method. Event handler methods have two parameters sender and e. The former is of type object and shows who called this method in your case you can cast is as a TextBox and that will be calling textbox. The cast operation is like this:
var textBox = sender as TextBox;
if (textBox != null)
{
//Do what you want with textBox here
}
Also if you use the new C# 7 you can do (Which is not any different internally just better to read):
if (sender is TextBox textBox)
{
//Do what you want with textBox here
}
I want to use listview to populate it with data and then use mouseclick event to fill some textboxes with data. I looked up an example in msdn:
ListViewItem theClickedOne = listView1.GetItemAt(e.X, e.Y);
ListViewItem theClickedtwo = listView1.FocusedItem;
if (theClickedOne != null)
{
MessageBox.Show(theClickedtwo.ToString());
//do your thing here.
//there is a reference to the listview item we clicked on
//in our theClickedOne variable.
}
but I couldn't think about a way to use it in order to differentiate the listviewitems I use since the fist Column in my program is the same and it will only give me a string with it's name(first Column).I want to have something similar to next example but for treeview.
void treeView1_NodeMouseClick(Object sender, TreeNodeMouseClickEventArgs e)
{
MessageBox.Show(e.Node.Text);
}
When populating you ListView, set the Tag property of the items, e.g.
newItem.Tag = "Item 1";
The Tag property has type object, so you can use anything you want here to identify the item. When handling the mouse click event simply check the Tag value again:
if((string)(clickedItem.Tag) == "Item 1")
{
// do stuff for this specific item.
}
I am using the devexpress TreeList control. In Treelist I have a situation where one of my column is read only. This column may have some text values added when something happens in another cell. I have restricted user entry in the cell by setting a property like this
treeList1.Columns["col3"].OptionsColumn.ReadOnly = true;
Now I want to remove text value from some of the cells and since it is read only the delete buttons does not work. Can you suggest the event/method and the code which will allow user to delete the text?
Any help would be much appreciated.
Edited solution :
You should know that when the cursor is in the cell (in edit mode), and you press a button, it's not the TreeList who send the KeyDown event, but the RepositoryItemButtonEdit. So, you should handle the event also for the RepositoryItemButtonEdit.
To not duplicate code, I've wrote one handler 'onKeyDown', in whitch I verify who is the sender.
treeList1.KeyDown += onKeyDown;
riButtonEdit.KeyDown += onKeyDown;
And here is a code exemple showing you how to handle the KeyDown event for both treeList and repositoryButtonEdit, and set the cell value to null :
private void onKeyDown(object sender, KeyEventArgs e)
{
// Test if the button pressed is the delete button
if (e.KeyCode != Keys.Delete)
return;
// Test if the focused column is colValue
if (treeList1.FocusedColumn != colValue)
return;
// Set the cell value to null
treeList1.FocusedNode.SetValue(colValue, null);
// If it's the ButtonEdit who send the event, make it's EditValue null
var btnEdit = sender as ButtonEdit;
if (btnEdit != null)
{
btnEdit.EditValue = null;
}
}
Currently I am trying to write a method to let user click on any datagrid cell or row in the datagrid view and after clicking information from datagrid view appers in the various textboxes / combo boxes. The thing is after clicking on the item it just doesn't work. Last time I when I wrote something else it was datagrid multiselect option which set to ture and caused problems, this time I have no idea what I did wrong. Method itself:
private void dataGridView3_SelectionChanged(object sender, EventArgs e)
{
foreach (DataGridViewRow row in this.dataGridView3.SelectedRows)
{
Group selectedGrp = row.DataBoundItem as Group;
if (selectedGrp != null)
{
this.textGrpID.Text = selectedGrp.GrpID;
this.textGrpName.Text = selectedGrp.GrpName;
this.comboBoxGrp.SelectedValue = selectedStd.StdGrp;
}
}
}
You want to show the textboxs for enter the the free text while clicking the row on datagrid. do u use the Edit template for showing the textbox and dropdown?
Why use the SelectionChanged event then? You didn't mention anything about changing selections... you said the user would click on a cell to see this information... so why not handle the Click event instead?