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

时间:2016-05-24 08:55:09

标签: c# winforms

我有一个包含这些控件的winform:

winform controls

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

这是我的代码[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;

        }
    }


输出文件是2个文本文件:panel0.txt,panel1.txt

和panel0.txt包含:
PanelName =&GT; PANEL1
BUTTONNAME =&GT; BUTTON0

和panel1.txt包含:
BUTTONNAME =&GT; button1的

这就是我想要的,但问题是当面板中子控件的顺序发生变化时,这些输出会显示错误的信息:

如果我改变了panel0子控件的顺序:

        this.panel0.Controls.Add(this.panel1);
        this.panel0.Controls.Add(this.button0);
        this.panel0.Controls.Add(this.label2);

到:

           this.panel0.Controls.Add(this.button0);
           this.panel0.Controls.Add(this.panel1);
           this.panel0.Controls.Add(this.label2);         

所以输出将是:
panel0.txt包含:
PanelName =&gt; panel1

和panel1.txt包含:
BUTTONNAME =&GT; button1的

这是错误的。
为什么会发生这种情况,我该如何解决这个问题呢? 感谢。

[UPDATE1]:
由于D. Petrov的回答,如果我删除_sbtmp.Clear();从enumerate_panel_child_contols的第一行开始,它将是:

             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 =&gt; panel1

和panel1.txt包含:
BUTTONNAME =&GT; BUTTON0
BUTTONNAME =&GT; button1的

这是错误的。

1 个答案:

答案 0 :(得分:0)

问题主要出在private void enumerate_panel_child_contols(Panel pnl)

开头的这一行
_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();
        }

您实际上已经将按钮信息写入了一个编写器一次(因为它在面板之前),然后,当您到达面板时,您再次清除StringBuilder并写入信息小组的。这就是为什么如果你把它上面的按钮放在列表中,你只有面板的信息。

出现问题主要是因为您使用具有两组不同数据的相同StringBuilder(对于两个不同的文件)。你应该重新考虑一下你的算法,它并不难达到。

<强> [UPDATE1]

这个问题的一个简单的解决方案就是为void的每个单独执行创建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();
    }
}