我有一个包含这些控件的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;
}
}
输出文件是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的
这是错误的。
答案 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();
}
}