I have search TextBox, and I want to when I press Arrow Down to navigate through the ListView, and if I press Left/Right Arrow on ListView I want to navigate with Caret through the text, and if I press down again I navigate through the ListView again. Just regular process like Chrome Search suggestions.
I just want to get Focus like when pressing TAB button. With TAB all works great.
On TextBox I use PreviewKeyDown event and detect Key.Down and I set my ListView.Focus() - That works great. ListView is focused and I can Navigate through items.
On ListView I use PreviewKeyDown event and detect any key that is not Key.Down or Key.Up and set focus on TextBox and set selection to the end of text. - That works great. Textbox is focused and I can Navigate through the text with Left/Right arrow.
Problem is now if I press Down arrow. Nothing happens. I can't get focus on ListView again. Don't know why.
I used Keyboard.Focus(), Keyboard.ClearFocus(), FocusManager... Nothing helps, focus remain on TextBox.
I used ItemContainerGenerator with SelectedIndex and that works but Selects second item in ListView. I think it is because I select first index and when I press down ListView gets focus and pass that Arrow Down event. And I ending with second row in ListView.
TextBox on PreviewKeyDown:
private void SearchTermTextBox_OnKeyDown(object sender, KeyEventArgs e) {
if (e.Key == Key.Down) {
SuggestionsListView.Focus();
}
else if (e.Key == Key.Escape)
{
SearchTermTextBox.Clear();
}
}
ListView on PreviewKeyDown:
private void SuggestionsListView_OnPreviewKeyDown(object sender, KeyEventArgs e) {
if (e.Key != Key.Down && e.Key != Key.Up) {
SearchTermTextBox.Focus();
SearchTermTextBox.Select(SearchTermTextBox.Text.Length, 0);
}
}
I used this code with ItemContainerGenerator. But, like I said, it's selecting second row from some reason.
SuggestionsListView.SelectedItem = SuggestionsListView.Items[0];
ListViewItem item = SuggestionsListView.ItemContainerGenerator.ContainerFromItem(SuggestionsListView.SelectedItem) as ListViewItem;
item.Focus();
Related
I created Listbox with property checkboxes == true, but the problem that I had was that I was needed to click twice on the line in order to set it checked. I was needed to change it in such a way that I can click on the line just once and the line set as checked. What I did is added mouseClick event:
private void Cbl_folders_MouseDown(object sender, MouseEventArgs e)
{
SelectedListViewItemCollection selectedItemsList = Cbl_folders.SelectedItems;
if(selectedItemsList.Count > Constants.EMPTY_COUNT)
{
selectedItemsList[0].Checked = !selectedItemsList[0].Checked;
}
}
And everything works fine, first, click on the line set the line as checked the second click on the line set the line as unchecked. But then I found out that if you clicked on the line and set this line as checked and then you click on the checkbox on the other line, so your first line that was checked changes the state to unchecked. Why? Because I am tracking mouseDown event and even when I click on the checkbox on the other line mouse down event looks on selected items and the obviously selected item is the first line that was clicked.
I understand that it is possible to add some flags and look where was a click and so on, but it seems overcomplicated, I feel like there is should be a simpler solution.
Handle the MouseDown event to switch the ListViewItem.Checked property when you click over the label area. To get info about the clicked area, call the ListView.HitTest method which returns a ListViewHitTestInfo object and check the Location property, the property returns one of the ListViewHitTestLocations values.
private void Cbl_folders_MouseDown(object sender, MouseEventArgs e)
{
if (Cbl_folders.CheckBoxes)
{
var ht = Cbl_folders.HitTest(e.Location);
if (ht.Item != null && ht.Location == ListViewHitTestLocations.Label)
ht.Item.Checked = !ht.Item.Checked;
}
}
This way, the items are checked/unchecked by the mouse also when you click outside their check boxes areas (determined by the ListViewHitTestLocations.StateImage value).
I have a DataGrid and one of my columns is a DataGridTextColumn. When the user presses enter, the DataGrid takes them to the next row, in which the user can immediately start typing, and the DataGridTextColumn takes the input just fine, yay!
The problem is, after they fill out one row, and hit enter to goto the next to fill it out, THEY MUST TYPE to activate the column. It's very important that the user can just paste with CTRL+V right after they are brought to the new column, and that the pasted info will automatically activate the text column without them having to type.
How can I go about this?
Idea is similar to Dimitris Batsougiannis suggested, but check Ctrl instead.
<DataGrid KeyDown="DataGrid_KeyDown"...
private void DataGrid_KeyDown(object sender, KeyEventArgs e)
{
if (e.Key == Key.LeftCtrl || e.Key == Key.RightCtrl)
{
var dataGrid = (DataGrid)sender;
if (dataGrid.CurrentCell != null)
{
dataGrid.BeginEdit();
}
}
}
Pressing Tab key on Button Refresh is setting focus on the dropdown list but I need to set focus on Checkbox column and first row of grid when the grid datasource is not null else the next control, however it is selecting the given cell only. I have set tabIndex property in sequence, please tell me where i am wrong, here is my code:
private void btnRefresh_PreviewKeyDown(object sender, PreviewKeyDownEventArgs e)
{
if (e.KeyCode == Keys.Tab)
{
if (grid.DataSource != null)
{
grid.Focus();
grid.CurrentCell = this.grid[1, 0];
grid.CurrentCell.Selected = true;
grid.BeginEdit(false);
}
else
{
btnCancel.Focus();
}
}
}
Have you seen this post?
Seems like your use of the index is of Grid[x,y].
Try
grid.Rows[1].Cells[0]
However, this wil select only the cell (first cell, second row by the way).
If you want to select the entire row, try
grid.Rows.First().Selected = True
Hope it helps.
Currently in my application it is impossible to deselect a textbox. The only way is to select another textbox. My users and I agree that clicking anywhere else on the form should deselect the current textbox. I tried overriding the MouseDown on many controls and having the focus set to a random label but it doesn't work for some controls like the MenuStrip or scrollbars. Any ideas?
Assuming you have no other controls on your forum, try adding a Panel control that can receive focus.
Set the TabIndex on the Panel control to something less than your TextBox or NumericUpDown control has.
Now, when your main form receives focus, the Panel should receive the focus instead of the TextBox area.
I had a similar issue recently. My interface is very complex with lots of panels and tab pages, so none of the simpler answers I found had worked.
My solution was to programatically add a mouse click handler to every non-focusable control in my form, which would try to focus any labels on the form. Focusing a specific label wouldn't work when on a different tab page, so I ended up looping through and focusing all labels.
Code to accomplish is as follows:
private void HookControl(Control controlToHook)
{
// Add any extra "unfocusable" control types as needed
if (controlToHook.GetType() == typeof(Panel)
|| controlToHook.GetType() == typeof(GroupBox)
|| controlToHook.GetType() == typeof(Label)
|| controlToHook.GetType() == typeof(TableLayoutPanel)
|| controlToHook.GetType() == typeof(FlowLayoutPanel)
|| controlToHook.GetType() == typeof(TabControl)
|| controlToHook.GetType() == typeof(TabPage)
|| controlToHook.GetType() == typeof(PictureBox))
{
controlToHook.MouseClick += AllControlsMouseClick;
}
foreach (Control ctl in controlToHook.Controls)
{
HookControl(ctl);
}
}
void AllControlsMouseClick(object sender, MouseEventArgs e)
{
FocusLabels(this);
}
private void FocusLabels(Control control)
{
if (control.GetType() == typeof(Label))
{
control.Focus();
}
foreach (Control ctl in control.Controls)
{
FocusLabels(ctl);
}
}
And then add this to your Form_Load event:
HookControl(this);
Since you probably have a label, or any other control on your winform, I would go with the solution recommended here and just give the focus to a label when the Form gets clicked.
Worst case, you can even add a label situated at the -100, -100 position, set him as the first in the tab order and Focus() it on form click.
I have some kind of "workaround" for you. Just but another control (that can get the focus) in the background. I tested this for a GridView (which will paint your control grey) - but you should be able to do it with a custom control in the color you want or just set the backgroundcolor of the gridview (doh).
This way everytime the user clicks the background this backgroundcontrol will get the focus.
This is generic answer: To deselect TextBoxes when user clicks anywhere else on the form, first make controls to lose focus. For this subscribe to Click Event of the form:
private void Form1_Click(object sender, EventArgs e)
{
this.ActiveControl = null;
}
Next subscribe your TextBoxes to Focus Leave event and set SelectionLength to 0 (to deselect text, somehow it is not deselected although textbox does not show selection when loses focus):
private void textBoxes_Leave(object sender, EventArgs e)
{
TextBox txbox = sender as TextBox;
txbox.SelectionLength = 0;
}
If you have your TexBoxes nested in custom user control, you have to add events within that user control in a similar manner. Hope that helps to anyone else.
I have a combobox with four items that correspond to tabs in a tabcontrol. When the user selects an item from the combobox (by left clicking and left clicking again to select an item) the corresponding tabpage in the tabcontrol is selected. The tabpage is set to autoscroll but when the tabpage is selected in this way mousewheel scrolling does not work. (If I click a control inside that tabpage manually I can then mousewheel scroll..)
If the user mousewheels to select an item from the same combobox (and successfully passes control to the corresponding tabpage) mousewheel scrolling works fine on that tabpage and I cant figure out why.
private void comboBox1_SelectedIndexChanged(object sender, EventArgs e)
{
switch (comboBox1.SelectedIndex)
{
case 0:
tabControl1.SelectedTab = tabPage3;
tabPage3.Focus();
break;
}
...
}
I can't get a repro of this problem. Something that might help is to set the focus to the first control of the page instead, just like what happens when you fix the problem by clicking a control. And to do so later, after the combobox event is completed. Use this:
private void setFocusToPage(TabPage page) {
var ctl = page.Controls.Count > 0 ? page.Controls[0] : page;
this.BeginInvoke((MethodInvoker)delegate { ctl.Focus(); });
}
Call setFocusToPage instead of the Focus() method in your SelectedIndexChanged event handler.