2009-04-28 11 views
4

Die TreeView in Windows Forms scheint immer einen Knoten ausgewählt zu haben, wenn der Fokus wiederhergestellt wird. Wenn ich keine Knoten ausgewählt habe und diese Baumansicht den Fokus erhält, erhalte ich ein AfterSelect Ereignis mit dem ersten ausgewählten Knoten, obwohl ich es nicht mit der Tastatur, der Maus oder programmgesteuert ausgewählt habe. Die einzige Problemumgehung, die ich finden kann, ist zu überprüfen, ob TreeViewCancelEventArgs.Action gleich TreeViewAction.Unknown ist, und dann die Auswahl abzubrechen. Das scheint wirklich hacky zu sein, also frage ich mich, ob es noch eine andere Möglichkeit gibt, das zu beheben.Windows Forms TreeView wählt immer einen Knoten im Fokus aus

Antwort

6

Ich stimme zu, dass TreeViewAction.Unknown in diesem Fall weniger als wünschenswert ist. Erwägen Sie die Verwendung des Ereignisses BeforeSelect, das eine Möglichkeit bietet, das Ereignis AfterSelect zu verhindern.

Erstellen Sie einen GotFocus Event-Handler, der ein Flag setzt. Erstellen Sie dann einen BeforeSelect-Event-Handler, der das Flag löscht, wenn das Flag gesetzt ist. Zum Beispiel:

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; 
} 
+0

Was mit diesem Code geschieht sendet, wenn ein Knoten, wenn die Baumansicht des Fokus erhält, ist. Wenn "BeforeSelect" nicht ausgelöst wird, bleibt treeViewHasNewlyFocused True. Meine Vermutung ist, dass dies dazu führen würde, dass die nächste absichtliche Knotenauswahl vom Benutzer abgebrochen wird. –

+0

Ich verwende das BeforeSelect-Ereignis, um abzubrechen. Ich verwende ein Flag, aber ich verwende ein Flag, um anzugeben, ob die Baumansichtsauswahl programmgesteuert erfolgt, da die für eine programmgesteuerte Auswahl gemeldete Aktion als "Unbekannt" gemeldet wird. Das scheint zu funktionieren, aber es scheint, dass dieses Verhalten ein Fehler im TreeView-Steuerelement ist, da das Verhalten keinen Sinn ergibt und ich es nirgends dokumentiert sehe. –

2

Ich hatte das gleiche Problem genau über kommen (aber auf der Compact Framework), wo das Ereignis Before nicht ausgesetzt ist (ich war bummed).

Aber denken Sie, eine ziemlich elegent Lösung bekommen und Hoffnung könnte anderen helfen !!

Ich machte eine abgeleitete TreeView-Steuerelement (so könnte mehrere Elemente auf einmal auswählen), sondern auch korrigiert die "automatische" Auswahl des ersten Knoten beim Abrufen von FOCUS.

  • public class TreeView_MultSel: System.Windows.Forms.TreeView

ich überwog dann die Event-Handler als solche:

/// <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;         
} 
4

ich meine Version dieses Problem gelöst, indem TabStop aus für die Baumansicht.

0

Meine Version des gleichen Problems mit folgendem Code behoben.

private TreeNode _selectedNode; 

public FormMain() 
{ 
    InitializeComponent(); 
    myTreeView.LostFocus += (sender, args) => _selectedNode = myTreeView.SelectedNode; 
    myTreeView.GotFocus += (sender, args) => myTreeView.SelectedNode = _selectedNode; 
} 
0

das Problem gelöst durch TVM_SELECTITEM mit lparam von 0.