Winforms中的TreeView和焦点问题

时间:2009-12-10 13:42:41

标签: winforms treeview focus

任何人都可以解释为什么在树中选择treenode时,下面代码中的表单会失焦?应该发生的是,当树像listview示例消失时,表单/按钮应该得到焦点,但它不会。

代码示例:

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Text;
using System.Windows.Forms;

namespace FocusTest
{
  public partial class Form1 : Form
  {
    #region Generated

    /// <summary>
    /// Required designer variable.
    /// </summary>
    private System.ComponentModel.IContainer components = null;

    /// <summary>
    /// Clean up any resources being used.
    /// </summary>
    /// <param name="disposing">true if managed resources should be disposed; otherwise, false.</param>
    protected override void Dispose(bool disposing)
    {
      if (disposing && (components != null))
      {
        components.Dispose();
      }
      base.Dispose(disposing);
    }

    #region Windows Form Designer generated code

    /// <summary>
    /// Required method for Designer support - do not modify
    /// the contents of this method with the code editor.
    /// </summary>
    private void InitializeComponent()
    {
      System.Windows.Forms.ListViewItem listViewItem1 = new System.Windows.Forms.ListViewItem("Item1");
      System.Windows.Forms.ListViewItem listViewItem2 = new System.Windows.Forms.ListViewItem("Item2");
      System.Windows.Forms.ListViewItem listViewItem3 = new System.Windows.Forms.ListViewItem("Item3");
      System.Windows.Forms.TreeNode treeNode1 = new System.Windows.Forms.TreeNode("Node0");
      System.Windows.Forms.TreeNode treeNode2 = new System.Windows.Forms.TreeNode("Node1");
      System.Windows.Forms.TreeNode treeNode3 = new System.Windows.Forms.TreeNode("Node2");
      this.button1 = new System.Windows.Forms.Button();
      this.listView1 = new System.Windows.Forms.ListView();
      this.button2 = new System.Windows.Forms.Button();
      this.treeView1 = new System.Windows.Forms.TreeView();
      this.SuspendLayout();
      // 
      // button1
      // 
      this.button1.Location = new System.Drawing.Point(12, 12);
      this.button1.Name = "button1";
      this.button1.Size = new System.Drawing.Size(75, 23);
      this.button1.TabIndex = 0;
      this.button1.Text = "button1";
      this.button1.UseVisualStyleBackColor = true;
      this.button1.Click += new System.EventHandler(this.button1_Click);
      // 
      // listView1
      // 
      this.listView1.Items.AddRange(new System.Windows.Forms.ListViewItem[] {
            listViewItem1,
            listViewItem2,
            listViewItem3            
            });
      this.listView1.Location = new System.Drawing.Point(12, 41);
      this.listView1.Name = "listView1";
      this.listView1.Size = new System.Drawing.Size(121, 97);
      this.listView1.TabIndex = 1;
      this.listView1.UseCompatibleStateImageBehavior = false;
      this.listView1.Visible = false;
      this.listView1.SelectedIndexChanged += new System.EventHandler(this.listView1_SelectedIndexChanged);
      this.listView1.View = View.List;
      // 
      // button2
      // 
      this.button2.Location = new System.Drawing.Point(310, 11);
      this.button2.Name = "button2";
      this.button2.Size = new System.Drawing.Size(75, 23);
      this.button2.TabIndex = 2;
      this.button2.Text = "button2";
      this.button2.UseVisualStyleBackColor = true;
      this.button2.Click += new System.EventHandler(this.button2_Click);
      // 
      // treeView1
      // 
      this.treeView1.Location = new System.Drawing.Point(310, 41);
      this.treeView1.Name = "treeView1";
      treeNode1.Name = "Node0";
      treeNode1.Text = "Node0";
      treeNode2.Name = "Node1";
      treeNode2.Text = "Node1";
      treeNode3.Name = "Node2";
      treeNode3.Text = "Node2";
      this.treeView1.Nodes.AddRange(new System.Windows.Forms.TreeNode[] {
            treeNode1,
            treeNode2,
            treeNode3});
      this.treeView1.Size = new System.Drawing.Size(121, 97);
      this.treeView1.TabIndex = 3;
      this.treeView1.Visible = false;
      this.treeView1.AfterSelect += new System.Windows.Forms.TreeViewEventHandler(this.treeView1_AfterSelect);
      // 
      // Form1
      // 
      this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F);
      this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
      this.ClientSize = new System.Drawing.Size(760, 409);
      this.Controls.Add(this.treeView1);
      this.Controls.Add(this.button2);
      this.Controls.Add(this.listView1);
      this.Controls.Add(this.button1);
      this.Name = "Form1";
      this.Text = "Form1";
      this.ResumeLayout(false);

    }

    #endregion

    private System.Windows.Forms.Button button1;
    private System.Windows.Forms.ListView listView1;
    private System.Windows.Forms.Button button2;
    private System.Windows.Forms.TreeView treeView1;

    #endregion


    public Form1()
    {
      InitializeComponent();
    }

    #region TreeView

    private void button2_Click(object sender, EventArgs e)
    {
      ToggleTreeView();
    }

    private void ToggleTreeView()
    {
      if (treeView1.Visible)
      {
        Controls.Remove(treeView1);
        treeView1.Visible = false;
      }
      else
      {
        Controls.Add(treeView1);
        treeView1.Size = new Size(300, 400);
        treeView1.Location = PointToClient(PointToScreen(new   System.Drawing.Point(button2.Location.X, button2.Location.Y + button2.Height)));
        this.treeView1.BringToFront();
        treeView1.Visible = true;
        treeView1.Select();

      }
    }

    private void treeView1_AfterSelect(object sender, TreeViewEventArgs e)
    {
      ToggleTreeView();
    }

    #endregion

    #region ListView

    private void button1_Click(object sender, EventArgs e)
    {
      ToggleListView();
    }

    private void ToggleListView()
    {
      if (listView1.Visible)
      {
        Controls.Remove(listView1);
        listView1.Visible = false;
      }
      else
      {
        Controls.Add(listView1);
        listView1.Size = new Size(300, 400);
        listView1.Location = PointToClient(PointToScreen(new System.Drawing.Point(button1.Location.X, button1.Location.Y + button1.Height)));
        this.listView1.BringToFront();
        listView1.Visible = true;
        listView1.Select();
      }
    }

    private void listView1_SelectedIndexChanged(object sender, EventArgs e)
    {
      if (listView1.Visible)
        ToggleListView();
    }

    #endregion        
  }
}

2 个答案:

答案 0 :(得分:0)

我无法解释为什么表单失去焦点,但问题似乎是Controls.Remove(treeView1);行。如果您删除了Controls.RemoveControls.Add行,那么它似乎表现得更好。

您是否有理由从控件列表中删除treeView?只是将可见性标志设置为false将导致treeView在用户进行选择后消失。

编辑:

回应你的评论: 我的猜测是,在调用treeView1_AfterSelect之后,TreeView将焦点设置为自身。您的代码中的哪一个是不可能的,因为您已从表单中删除了控件。

为了测试这个理论,我添加了一个计时器,用以下代码替换了代码:

private void treeView1_AfterSelect(object sender, TreeViewEventArgs e)
{
    timer1.Enabled = true;
    timer1.Start();
}
private void timer1_Tick(object sender, EventArgs e)
{
    ToggleTreeView();
    timer1.Stop();
    timer1.Enabled = false;

}

现在它运作正常。所以我猜测TreeView在触发this.Focus事件后调用AfterSelect。 (这只是一个猜测,也许其他人更了解他们内部他们:))

这就是使用ListView的原因是它在listView1_SelectedIndexChanged之后没有将焦点设置为自身。

答案 1 :(得分:0)

以下是问题和解决方法。

TreeView re-grabs focus on Ctrl+Click