C# 获取控件信息在c中无法正常工作#

C# 获取控件信息在c中无法正常工作#,c#,winforms,C#,Winforms,我有一个winform,其中包含以下控件: 我想提取有关控件的信息,如面板中的面板和按钮以及面板中的面板等,获取有关嵌套控件的信息非常重要 这是我的代码[MainFrm.cs]: using System; using System.IO; using System.Text; using System.Windows.Forms; namespace TestExpoter { public partial class Mai

我有一个winform,其中包含以下控件:


我想提取有关控件的信息,如面板中的面板和按钮以及面板中的面板等,获取有关嵌套控件的信息非常重要

这是我的代码[MainFrm.cs]:

    using System;
    using System.IO;
    using System.Text;
    using System.Windows.Forms;
    namespace TestExpoter
    {
        public partial class MainFrm : Form
        {
            public MainFrm()
            {
                InitializeComponent();
            }

            private StringBuilder _sbtmp = new StringBuilder();
            private void okbtn_Click(object sender, EventArgs e)
            {
                foreach (Control c in Controls)
                {
                    if (c.GetType() == typeof (Panel))
                    {
                       enumerate_panel_child_contols((Panel)c);
                    }

                }

                MessageBox.Show(@"done");
            }
            private void enumerate_panel_child_contols(Panel pnl)
            {
                _sbtmp.Clear();

                foreach (Control c in pnl.Controls)
                {
                    if (c.GetType() == typeof(Button))
                    {
                        _sbtmp.AppendLine("ButtonName=>" + c.Name);
                    }
                    else if (c.GetType() == typeof(Panel))
                    {
                        enumerate_panel_child_contols((Panel)c);
                        _sbtmp.AppendLine("PanelName=>" + c.Name);
                    }
                }
                var sw = new StreamWriter(Path.GetDirectoryName(Application.ExecutablePath) + "\\" + pnl.Name  + ".txt");
                sw.WriteLine(_sbtmp.ToString());
                sw.Close();
                _sbtmp.Clear();
            }
        }
    }
[MainFrm.Designer.cs]:

    namespace TestExpoter
    {
        partial class MainFrm
        {
            /// <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()
            {
                this.okbtn = new System.Windows.Forms.Button();
                this.panel0 = new System.Windows.Forms.Panel();
                this.button0 = new System.Windows.Forms.Button();
                this.panel1 = new System.Windows.Forms.Panel();
                this.button1 = new System.Windows.Forms.Button();
                this.label1 = new System.Windows.Forms.Label();
                this.label2 = new System.Windows.Forms.Label();
                this.panel0.SuspendLayout();
                this.panel1.SuspendLayout();
                this.SuspendLayout();
                // 
                // okbtn
                // 
                this.okbtn.Location = new System.Drawing.Point(335, 67);
                this.okbtn.Margin = new System.Windows.Forms.Padding(0);
                this.okbtn.Name = "okbtn";
                this.okbtn.Size = new System.Drawing.Size(74, 31);
                this.okbtn.TabIndex = 2;
                this.okbtn.Text = "OK";
                this.okbtn.UseVisualStyleBackColor = true;
                this.okbtn.Click += new System.EventHandler(this.okbtn_Click);
                // 
                // panel0
                // 
                this.panel0.BorderStyle = System.Windows.Forms.BorderStyle.Fixed3D;
                this.panel0.Controls.Add(this.panel1);
                this.panel0.Controls.Add(this.button0);
                this.panel0.Controls.Add(this.label2);
                this.panel0.Location = new System.Drawing.Point(24, 33);
                this.panel0.Name = "panel0";
                this.panel0.Size = new System.Drawing.Size(292, 121);
                this.panel0.TabIndex = 0;
                // 
                // button0
                // 
                this.button0.Location = new System.Drawing.Point(16, 49);
                this.button0.Name = "button0";
                this.button0.Size = new System.Drawing.Size(83, 26);
                this.button0.TabIndex = 0;
                this.button0.Text = "button0";
                this.button0.UseVisualStyleBackColor = true;
                // 
                // panel1
                // 
                this.panel1.BorderStyle = System.Windows.Forms.BorderStyle.Fixed3D;
                this.panel1.Controls.Add(this.button1);
                this.panel1.Location = new System.Drawing.Point(146, 32);
                this.panel1.Name = "panel1";
                this.panel1.Size = new System.Drawing.Size(120, 64);
                this.panel1.TabIndex = 3;
                // 
                // button1
                // 
                this.button1.Location = new System.Drawing.Point(14, 18);
                this.button1.Name = "button1";
                this.button1.Size = new System.Drawing.Size(88, 23);
                this.button1.TabIndex = 0;
                this.button1.Text = "button1";
                this.button1.UseVisualStyleBackColor = true;
                // 
                // label1
                // 
                this.label1.AutoSize = true;
                this.label1.Location = new System.Drawing.Point(21, 15);
                this.label1.Name = "label1";
                this.label1.Size = new System.Drawing.Size(45, 15);
                this.label1.TabIndex = 3;
                this.label1.Text = "panel0";
                // 
                // label2
                // 
                this.label2.AutoSize = true;
                this.label2.Location = new System.Drawing.Point(143, 14);
                this.label2.Name = "label2";
                this.label2.Size = new System.Drawing.Size(45, 15);
                this.label2.TabIndex = 4;
                this.label2.Text = "panel1";
                // 
                // MainFrm
                // 
                this.AutoScaleDimensions = new System.Drawing.SizeF(7F, 15F);
                this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
                this.BackColor = System.Drawing.SystemColors.ControlDark;
                this.ClientSize = new System.Drawing.Size(430, 179);
                this.Controls.Add(this.label1);
                this.Controls.Add(this.panel0);
                this.Controls.Add(this.okbtn);
                this.Font = new System.Drawing.Font("Microsoft Sans Serif", 12F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Pixel, ((byte)(178)));
                this.Margin = new System.Windows.Forms.Padding(0);
                this.Name = "MainFrm";
                this.StartPosition = System.Windows.Forms.FormStartPosition.CenterScreen;
                this.Text = "Form1";
                this.panel0.ResumeLayout(false);
                this.panel0.PerformLayout();
                this.panel1.ResumeLayout(false);
                this.ResumeLayout(false);
                this.PerformLayout();

            }

            #endregion

            private System.Windows.Forms.Button okbtn;
            private System.Windows.Forms.Panel panel0;
            private System.Windows.Forms.Panel panel1;
            private System.Windows.Forms.Button button1;
            private System.Windows.Forms.Button button0;
            private System.Windows.Forms.Label label2;
            private System.Windows.Forms.Label label1;

        }
    }
致:

因此,输出将为:
panel0.txt包含:
PanelName=>panel1

panel1.txt包含:
ButtonName=>button1

那是错误的。
为什么会发生这种情况?我应该如何解决 谢谢

[更新1]:
根据D.Petrov的回答,如果我移除_sbtmp.Clear();从enumerate_panel_child_Controls的第一行开始,它将是:

             private void enumerate_panel_child_contols(Panel pnl)
            {
                foreach (Control c in pnl.Controls)
                {
                    if (c.GetType() == typeof(Button))
                    {
                        _sbtmp.AppendLine("ButtonName=>" + c.Name);
                    }
                    else if (c.GetType() == typeof(Panel))
                    {
                        enumerate_panel_child_contols((Panel)c);
                        _sbtmp.AppendLine("PanelName=>" + c.Name);
                    }
                }
                var sw = new StreamWriter(Path.GetDirectoryName(Application.ExecutablePath) + "\\" + pnl.Name  + ".txt");
                sw.WriteLine(_sbtmp.ToString());
                sw.Close();
                _sbtmp.Clear();
            }
但还有一个问题,其结果将是: panel0.txt包含:
PanelName=>panel1

panel1.txt包含:
ButtonName=>button0
ButtonName=>button1


这是错误的。

问题主要在于
私有无效枚举\u面板\u子控件(面板pnl)
开头的这一行:

因为正如你所看到的,在显示第二个顺序的控件时,你的面板前有一个按钮。使用您拥有的代码:

private void enumerate_panel_child_contols(Panel pnl)
        {
            _sbtmp.Clear();

            foreach (Control c in pnl.Controls)
            {
                if (c.GetType() == typeof(Button))
                {
                    _sbtmp.AppendLine("ButtonName=>" + c.Name);
                }
                else if (c.GetType() == typeof(Panel))
                {
                    enumerate_panel_child_contols((Panel)c);
                    _sbtmp.AppendLine("PanelName=>" + c.Name);
                }
            }
            var sw = new StreamWriter(Path.GetDirectoryName(Application.ExecutablePath) + "\\" + pnl.Name  + ".txt");
            sw.WriteLine(_sbtmp.ToString());
            sw.Close();
            _sbtmp.Clear();
        }
实际上,您正在将按钮信息写入streamwriter一次(因为它位于面板之前),然后,当您到达面板时,再次清除StringBuilder并写入面板信息。这就是为什么你只有面板的信息,如果你把按钮上面的列表

出现此问题的主要原因是您使用同一个StringBuilder处理两组不同的数据(用于两个不同的文件)。你应该重新考虑一下你的算法,这并不难达到

[update1]

这个问题的一个足够简单的解决方案就是为void的每个单独执行创建stringbuilder,而不是使其全局化。所有的问题都应该消失,因为不再存在对同一个全局stringbuilder的覆盖

public partial class MainFrm : Form
{
    public MainFrm()
    {
        //
        // The InitializeComponent() call is required for Windows Forms designer support.
        //
        InitializeComponent();

        //
        // TODO: Add constructor code after the InitializeComponent() call.
        //
    }


    void okbtn_Click(object sender, EventArgs e)
    {
        foreach (Control c in Controls)
        {
            if (c.GetType() == typeof (Panel))
            {
                enumerate_panel_child_contols((Panel)c);
            }

        }

        MessageBox.Show(@"done");
    }

    void enumerate_panel_child_contols(Panel pnl)
    {
        StringBuilder _sbtmp = new StringBuilder();

        foreach (Control c in pnl.Controls)
        {
            if (c.GetType() == typeof(Button))
            {
                _sbtmp.AppendLine("ButtonName=>" + c.Name);
            }
            else if (c.GetType() == typeof(Panel))
            {
                enumerate_panel_child_contols((Panel)c);
                _sbtmp.AppendLine("PanelName=>" + c.Name);
            }
        }

        using(var sw = new StreamWriter(Path.GetDirectoryName(Application.ExecutablePath) + "\\" + pnl.Name  + ".txt"))
        {
            sw.WriteLine(_sbtmp);
            sw.Close();
        }

        _sbtmp.Clear();
    }
}

@ChrisWohlert:我更改了在mainform中而不是在designer文件中添加控件的顺序。我正在寻找一个通用的解决方案。是的,我在发表评论后很快意识到了这一点。:)@克里斯沃勒:没问题:)我已经根据你的回答更新了这个问题,因为我不能在评论部分发布所有的问题。谢谢。你的代码逻辑通常是错误的。我建议您重新考虑使用同一个StringBuilder,这就是混淆内容的原因。现在使用代码,只要您到达panel0控件中的panel1,就可以开始使用panel0左侧的按钮将panel1控件分配给stringbuilder。就在最后,当您写下它时,您清除了stringbuilder,然后您打印了panel1在panel0中的信息,因为您已经完成了panel1.txt的编写。我给你举个例子。非常感谢。我正在等待你的例子和你的帮助来解决这个问题。更新我的答案。这个问题一点也不复杂。
_sbtmp.Clear();
private void enumerate_panel_child_contols(Panel pnl)
        {
            _sbtmp.Clear();

            foreach (Control c in pnl.Controls)
            {
                if (c.GetType() == typeof(Button))
                {
                    _sbtmp.AppendLine("ButtonName=>" + c.Name);
                }
                else if (c.GetType() == typeof(Panel))
                {
                    enumerate_panel_child_contols((Panel)c);
                    _sbtmp.AppendLine("PanelName=>" + c.Name);
                }
            }
            var sw = new StreamWriter(Path.GetDirectoryName(Application.ExecutablePath) + "\\" + pnl.Name  + ".txt");
            sw.WriteLine(_sbtmp.ToString());
            sw.Close();
            _sbtmp.Clear();
        }
public partial class MainFrm : Form
{
    public MainFrm()
    {
        //
        // The InitializeComponent() call is required for Windows Forms designer support.
        //
        InitializeComponent();

        //
        // TODO: Add constructor code after the InitializeComponent() call.
        //
    }


    void okbtn_Click(object sender, EventArgs e)
    {
        foreach (Control c in Controls)
        {
            if (c.GetType() == typeof (Panel))
            {
                enumerate_panel_child_contols((Panel)c);
            }

        }

        MessageBox.Show(@"done");
    }

    void enumerate_panel_child_contols(Panel pnl)
    {
        StringBuilder _sbtmp = new StringBuilder();

        foreach (Control c in pnl.Controls)
        {
            if (c.GetType() == typeof(Button))
            {
                _sbtmp.AppendLine("ButtonName=>" + c.Name);
            }
            else if (c.GetType() == typeof(Panel))
            {
                enumerate_panel_child_contols((Panel)c);
                _sbtmp.AppendLine("PanelName=>" + c.Name);
            }
        }

        using(var sw = new StreamWriter(Path.GetDirectoryName(Application.ExecutablePath) + "\\" + pnl.Name  + ".txt"))
        {
            sw.WriteLine(_sbtmp);
            sw.Close();
        }

        _sbtmp.Clear();
    }
}