【问题标题】:TreeView in Winforms and focus problemWinforms中的TreeView和焦点问题
【发布时间】:2023-03-08 00:32:02
【问题描述】:

谁能解释一下为什么在选择树中的树节点时,下面代码中的表单会失去焦点?应该发生的是,当树像列表视图示例一样消失时,表单/按钮应该获得焦点,但事实并非如此。

代码示例:

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

【问题讨论】:

    标签: winforms treeview focus


    【解决方案1】:

    我无法解释为什么表单失去焦点,但问题似乎出在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 在触发AfterSelect 事件后正在调用this.Focus。 (这只是一个猜测,也许其他人更了解我的内部结构:))

    这与 ListView 一起工作的原因是它在 listView1_SelectedIndexChanged 之后没有将焦点设置为自身。

    【讨论】:

      【解决方案2】:

      这是问题和解决方法。

      TreeView re-grabs focus on Ctrl+Click

      【讨论】:

        猜你喜欢
        • 2011-03-11
        • 2012-02-28
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多