C# 获取控件信息在c中无法正常工作#
我有一个winform,其中包含以下控件: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
我想提取有关控件的信息,如面板中的面板和按钮以及面板中的面板等,获取有关嵌套控件的信息非常重要 这是我的代码[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();
}
}