The TreeView in Windows Forms always seems to want a node selected when it regains focus. If I have no nodes selected, and that treeview gains focus, I'll get an AfterSelect
event with the first node selected, even though I didn't select it using the keyboard, mouse, or programmatically. The only workaround I can find is to check if the TreeViewCancelEventArgs.Action
equals TreeViewAction.Unknown
and then canceling the selection. This seems really hacky, so I'm wondering if there's another way to fix this.
views:
1788answers:
2I agree that using TreeViewAction.Unknown
in this case is less than desirable. Consider using the BeforeSelect
event, which provides an opportunity to prevent the AfterSelect
event.
Create a GotFocus
event handler that sets a flag. Then, create a BeforeSelect
event handler that, if the flag is set, cancels the event and clears the flag. For example:
private bool treeViewWasNewlyFocused = false;
private void TreeView1_BeforeSelect(object sender, TreeViewCancelEventArgs e)
{
if(treeViewWasNewlyFocused)
{
e.Cancel = true;
treeViewWasNewlyFocused = false;
}
}
private void TreeView1_GotFocus(object sender, EventArgs e)
{
treeViewWasNewlyFocused = true;
}
I had to over come this same exact problem (but on the compact framework) where the BeforeSelect event isn't exposed ( I was bummed).
But think got a fairly elegent solution and hope might help others!!
I made a derived TreeView control (so could select multiple items at once), but will also corrects the "auto" selection of the first node on getting FOCUS.
- public class TreeView_MultSel : System.Windows.Forms.TreeView
I then overrode the event handlers as such:
/// <summary>
/// //This actually occurs AFTER actual Treeview control:
/// - Got Focus in reality
/// - Executed the "innate" behaviour (like a button showing "depressed")
/// - The "innate and UNWANTED behaviour of the Treeview is to selected the first Node
/// when gets the focus.
///The key here is the Treeview executes in this order (when Tree Selected and didn't have focus):
/// - First the Node is selected (before OnGotFocus is executed)
/// Since when LostFocus "treeHasFocus" = false the OnAfterSelect handler isn't called!!
///
/// - Then the OnGotFocus is called:
/// This will set treeHasFocus to True and will not react to selections
/// </summary>
/// <param name="e"></param>
protected override void OnGotFocus(EventArgs e)
{
treeHasFocus = true;
//base.OnGotFocus(e);
}
/// <summary>
/// Alot easier to handle here (in Derived TreeView control then using all kinds of
/// -= events to try to prevent.
///
/// This was the cleanest way I could find (prevent firing of AfterSelect)
/// </summary>
/// <param name="e"></param>
protected override void OnLostFocus(EventArgs e)
{
treeHasFocus = false;
//base.OnLostFocus(e);
}
/// <summary>
/// - Treeview Control defaults to selecting the first node (when gets focus)
/// - We do NOT want this - since would automatically Highlight the first node (select)
/// - treeHasFocus is NOT true for the first unwanted "automatic" selection of the first item
/// - Upon loosing Focus, the AfterSelect handler is never called.
/// </summary>
/// <param name="e"></param>
protected override void OnAfterSelect(TreeViewEventArgs e)
{
if (treeHasFocus)
base.OnAfterSelect(e);
this.SelectedNode = null;
}