2009-04-28 1 views
4

WindowsフォームのTreeViewは、フォーカスを取り戻すときに常にノードを選択するように見えます。ノードが選択されておらず、ツリービューにフォーカスがある場合は、キーボード、マウス、またはプログラムを使用して選択していないのに、最初のノードが選択されたAfterSelectイベントが発生します。唯一の解決策は、TreeViewCancelEventArgs.ActionTreeViewAction.Unknownと等しいかどうかを確認してから、選択をキャンセルすることです。これは本当にハッキーなので、これを修正する別の方法があるのだろうかと思います。WindowsフォームTreeViewは常にフォーカスしているノードを選択します

答えて

6

この場合、TreeViewAction.Unknownを使用することが望ましいとは限りません。 BeforeSelectイベントを使用することを検討してください。AfterSelectイベントを防止する機会があります。

フラグを設定するイベントハンドラGotFocusを作成します。次に、BeforeSelectイベントハンドラを作成します。このハンドラは、フラグが設定されている場合、イベントをキャンセルしてフラグをクリアします。例:

+0

のLPARAMとTVM_SELECTITEMを送信することによって、問題を解決しました。 BeforeSelectは呼び出されず、treeViewHasNewlyFocusedはtrueのままです。私の推測では、これはキャンセルされているユーザーから次の意図的なノード選択につながるだろうということです。 –

+0

キャンセルするBeforeSelectイベントを使用します。私はフラグを使用しますが、フラグを使用して、プログラムによる選択に対して報告されたアクションが「不明」として報告されるため、ツリービュー選択がプログラムによって行われているかどうかを指定します。それはうまくいくようですが、この振る舞いはTreeViewコントロールのバグだと思われます。振る舞いは意味をなさないため、どこにも文書化されていません。 –

2

BeforeSelectイベントが公開されていない(コンパクトなフレームワーク上で)これと同じ正確な問題が起きていました(私はうんざりでした)。

しかし、かなりエレガントな解決策があると思って、他人を助けるかもしれないと思ってください!

派生TreeViewコントロールを作成しました(複数のアイテムを同時に選択できるようになりました)が、FOCUSを取得する際に最初のノードの「自動」選択も修正されます。

  • パブリッククラスTreeView_MultSel:私は、その後のようなイベントハンドラをオーバーライドSystem.Windows.Forms.TreeView

/// <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

私はオフタブストップを回すことにより、この問題の私のバージョンを解決ツリービューのために。

0

同じ問題の私のバージョンを次のコードで修正しました。

private TreeNode _selectedNode; 

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

は、ツリービューがフォーカスを取得したときに選択されたノードがある場合、このコードで何が起こる0

関連する問題