How to focus on a ToolStripTextBox (one of the items in a ToolStripDropDownButton.DropDownItems collection) when the drop down opens - winforms

I'm building the DropDownItems of a ToolStripDropDownButton programmatically. The first field is always a ToolStripTextBox (which users can type into to filter the following items). I want the ToolStripTextBox to have focus as soon as the drop down opens so that user can:
Click on the ToolStripDropDownButton
Begin typing (to filter the items)
However, when I try to focus on the ToolStripTextBox (within the DropDownOpened event handler):
Dim v As ToolStripTextBox = DirectCast(tsbForms.DropDownItems(0), ToolStripTextBox)
Me.ActiveControl = v.Control
I get an exception:
System.ArgumentException: 'Invisible or disabled control cannot be activated'
Here's a screen shot of the dropdown so you can see what I'm talking about:
Currently the textbox at the top doesn't have focus and you have to click in it before you can start typing in the filter.
FYI I've tried testing the Visibility of the ToolStripTextBox before setting ActiveControl and it is True in this event. I've tried performing the operation a few other events and got the same result.

Just setting focus worked for me:
Dim v As ToolStripTextBox = DirectCast(tsbForms.DropDownItems(0), ToolStripTextBox)
v.Focus()
I used the DropDownOpened event of the parent ToolStripDropDownButton.

Related

Combobox List passing string

I have a VB6 application that has been running for quite sometime. Currently I'm trying to update one of the form that has a combobox 2.0. Because the combobox is populated with hundreds of items - I'm trying to update it so that users are able to click on a look up button next to it, where another window opens up with all the items from the combobox. User will be able to search by keyword and/or select an item and double click on it and have it appear in the combobox. The issue I'm having is with trying to pass no value or "" when CANCEL is clicked. I'm able to pass the value if I in the properties window my STYLE Is set to COMBO rather than list. However, the issue I come across is that with COMBO the value (text) in the combobox sometimes is not aligned properly. Is there a way to pass a "" value to a combobox 2.0 without changing the style to COMBO?
If they hit cancel set the ListIndex of your combo to -1 rather than setting the text property. This is the value for no item being selected.

Where is the Visual Basic 6 Combo Box Click Event?

I'm new to Visual Basic, I have scoured the net to look for the event handler for the combo box click event but I cannot locate it. I am trying to make an event happens if a certain index is selected with the combo box1 then another combo box2 will populate the selected the index.
i have looked at links like these but it does not explain how or what the person did to access the _ click event VB6 Combo box events
In the code window for the form, select the desired control from the left drop down, then the event you want from the list of all events in the right drop down:
It will create the procedure for you and make it the active one. This is the same as VB.NET assuming you have the selectors on.
I haven't been using VB6 for ages, but i think what you need is covered here: http://www.vb6.us/tutorials/visual-basic-combo-box-tutorial
I cannot recall having to do anything special when using click events in VB6 at all.
In the first combobox click event, you should be able to have an if statement checking if a certain item is selected using .ListIndex and if so, populate the other.

Have TreeView update its SelectedItem when programmatically changed

In WPF I have a TreeView control where a particular item can be selected either by the user selecting the item directly in the tree view or by clicking on a screen control. The tree view is displaying a list of elements that are being displayed on a user defined form, basically a form designer application.
Here is my problem. When the user clicks on a screen control it calls a method that returns the TreeViewItem that represents the element. It then sets the IsSelected property to true for this element. It correctly changes the visual indicator in the TreeView and it raised the SelectedItemChanged event in the TreeView. This is all good.
However, it appears that somewhere behind the scenes the TreeView still thinks the previous item is selected. Here is why I have come to this conclusion. If I select ElementA by clicking on it in the TreeView is it correctly selected. If I then select ElementB by clicking on the screen control and programmatically setting the IsSelected property for the ElementB TreeViewItem it appears to have selected it correctly. Now if I select ElementA again by clicking on it in the TreeView it does nothing. The SelectedItemChanged event is not raised and the reverse selection box that indicates the selected item stays on ElementB. If I click on ElementB in the TreeView it also does not raise the SelectedItemChanged event, however it does not appear to update the internal flag since if I then click on ElementA on the TreeView it processes it correctly and raises the event.
The only workaround that I have found for this is in the SelectedItemChanged event handler to call the Focus method for the now selected TreeViewItem. If I do this I get the expected behaviour when I select screen controls and programmatically change the selected TreeViewItem.
This is not an acceptable solution though as it creates focus change flicker. When I select items on my form window the focus goes to the TreeView control and then back to the form, causing flicker and slight delay.
Anyone have any indeas.
Update
As requested here is some code. Here is my method of my Explorer window which is the manager of the TreeView in question.
public bool SelectItemByName(String controlName)
{
bool fReturn = false;
TreeViewItem tviToSelect = FindItemByName(_tviMaster, controlName);
if (tviToSelect != null && _tviSelectedItem != tviToSelect)
{
tviToSelect.IsSelected = true;
// Make sure the selected item is visible in the TreeView by expanding all of the parent nodes
ExpandAllParents(tviToSelect);
tviToSelect.BringIntoView();
fReturn = true;
}
return fReturn;
}
Every element has a unique identifier that I use as a cross reference between different areas of the interface. When you click a screen control it uses its identifier to find the cooresponding TreeViewItem in the TreeView. Then this code sets it as selected.
Then in my SelectedItemChanged event handler I had to include the following line.
_tviSelectedItem.Focus();
This fixes my initial issue but introducing the unwant screen flicker.
To recap, I select ElementA in the TreeView directly, then select one or more other elements in the form designer which in turn calls SelectItemByName to programatically set the selected item. All visual indicators show that this worked. In the TreeView the highlighted item changes to the new item that is selected. After selecting any number of elements through the form designer interface if you select ElementA by clicking on it directly in the TreeView it does nothing. It does not get highlighted and it does not fire the SelectedItemChanged event. If you inspect the SelectedItem and SelectedValue properties of the TreeView they all correctly coorespond to the item that was programmatically selected. However, the control somewhere appears to think that ElementA is still selected and doesn't recognize that the selection is changing.
I cannot believe that other people haven't run into this. It appears to be a significant flaw in the TreeView contol in WPF. Not sure if WinForms has the same issue or not.
Each TreeViewItem has an IsSelected property, and I suspect the old one isn't getting set to false. Try setting it to false whenever you set the new item to true.
var currentItem = treeView.ItemContainerGenerator
.ContainerFromItem(treeView.SelectedItem) as TreeViewItem;
currentItem.IsSelected = false;
If that doesn't work, try setting focus on the newly selected item at the same time as when you select it. Don't forget that WPF also has two focus scopes: Logical Focus and Keyboard Focus. You may need to set both.
treeViewItem.Focus(); // Sets Logical Focus
Keyboard.Focus(treeViewItem); // Sets Keyboard Focus

Control.Leave Triggered by MouseDown, not MouseUp

I have a C# .NET WinForm. In the form, I allow a user to add an item to a ListView by double-clicking in the ListView. This adds a TextBox control to the ListView and places the key cursor in the TextBox so a user can type.
I detect that a user is done with an item in a couple of ways (e.g. pressing Enter, Esc, Tab...), but also when they Leave (TextBox.Leave) the TextBox.
The problem is this set of steps:
User triggers TextBox.Leave by mousing down outside of the TextBox.
I add the new item to the ListView.
I select the the new item in the ListView.
Mouse up occurs and the new item that I just selected, loses focus and is unselected.
What I would like is for TextBox.Leave to be triggered by MouseUp, not MouseDown. How can I accomplish this?
Edit: Cody suggests using the ListView.LabelEdit property. Here are my results trying that:
listView_DoubleClick(...) {
listView.LabelEdit = true;
if(double clicked on existing listViewItem) {
listViewItem.BeginEdit(); //this works as expected
} else {
var newItem = listView.Items.Add("");
newItem.BeginEdit(); //this doesn't work, see below
}
}
The call to newItem.BeginEdit() only works when the user double clicks where the new item will show up. If they double click on any other blank area in the listview the new item is added, but it does not enter edit mode. What's going on here?
Pressing the mouse down on another control is causing that other control to request the focus and so the focus moving causes the TextBox.Leave event to occur. Preventing ever other possible control from requesting the focus is not a very viable option. But luckly you only need to prevent the ListView from using the MouseDown to shift focus. So you need to override the WndProc of your ListView and when the MouseDown windows message occurs and you are currently showing a TextBox you eat the message. In order words you do not allow the base class to process it.

DevExpress XtraGrid checkbox check not registered unless focus changes

We have a databound XtraGrid on our Windows form. One of the columns is a check box. The problem is as follows: when users check the checkbox and click OK button, the checkbox, while visibly checked, is not considered checked by the grid. When I do this (while looping through rows):
isAllowed = Convert.ToBoolean(viewMain.GetRowCellValue(nRowCtr, "IsAllowed"))
I get back False. BUT, if the user checks the box, and then clicks somewhere else on the form or on another row in this grid, thus taking away focus from the checked checkbox, the same code above will return True.
Any insight on how to fix this behavior would be greatly appreciated.
Workaround found:
With default settings, when users click on a cell to edit it, the cell goes into edit mode, loads the editor control (in this case I have a CheckEdit repository control) and changes control's value (in this case checked state). If I click on another row, or another control, the cell then gets out of edit mode, committing the change to data item. But if I click on a button, then my change is lost. The workaround is to use the CheckEdit's CheckedChanged event to close editor:
Private Sub edCheck_CheckedChanged(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles edCheck.CheckedChanged
gridYears.FocusedView.CloseEditor()
End Sub
There's actually a cleaner way of doing this (it works for all RepositoryItems), detailed on the DevExpress site. The idea is to call the GridView.PostEditor method from a repository item's EditValueChanged event handler to immediately save the edited value to the grid's cell and the underlying column.
This code in the view's CellValueChanging event handler solved the problem:
private void OnCellValueChanging(object sender, CellValueChangedEventArgs e)
{
_gridView.SetFocusedRowCellValue(_gridView.FocusedColumn, e.Value);
}

Resources