【问题标题】:Accesing C# Form textbox from another class file从另一个类文件访问 C# Form 文本框
【发布时间】:2012-09-07 20:57:16
【问题描述】:

我想从另一个类文件(例如chartscopier.cs)访问Form1 元素,但我无法从chartcopier.cs 更改textbox1 文本。

我该怎么做?

这是我的代码:

Form1.cs

namespace TEST
{
    public partial class Form1 : Form
    {
        public Form1()
        {
            InitializeComponent();
            var CopyCharts = new System.Threading.Timer(chartscopier.CopyGraph, null, 0, 60000);
        }
    }
}

chartscopier.cs

namespace TEST
{
    class chartscopier
    {
        //var Timer = new Timer(CopyGraph, null, 0, 60000);
        public static void CopyGraph(object data)
        {
            Stopwatch strTimer = new Stopwatch();
            WebClient WC = new WebClient();
            IConfigSource BaseConfig = new IniConfigSource(@"D:\NEWROBOT\CONFIG.ini");
            string LogDir = BaseConfig.Configs["GENERAL"].Get("Log Dir");
            string ImgDir = BaseConfig.Configs["GENERAL"].Get("IMG Dir");
            string[] Clients = BaseConfig.Configs["CLIENTS"].GetKeys();
            foreach (string Client in Clients)
            {
                strTimer.Start();
                //Console.WriteLine(Client);
                IConfigSource ClientConfig = new IniConfigSource(@"D:\NEWROBOT\" + Client + ".ini");
                string[] Services = ClientConfig.Configs["SERVICES"].GetKeys();
                foreach (string Service in Services)
                {
                    string url = BaseConfig.Configs["CLIENTS"].Get(Client);
                    string param = ClientConfig.Configs["SERVICES"].Get(Service);
                    string html = WC.DownloadString(url + param);

                    // Cargar doc en HPACK
                    HtmlDocument doc = new HtmlDocument();
                    doc.LoadHtml(html);

                    // LINQ para generar imagenes
                    var img = doc.DocumentNode.SelectSingleNode("//img[1]");
                    var src = img.Attributes["src"].Value;
                    string uIMG = url + src;
                    WC.DownloadFile(uIMG, @ImgDir + Client + "\\" + Service + ".png");
                }
                strTimer.Stop();
                TimeSpan ts = strTimer.Elapsed;
                string elapsedTime = String.Format("{0:00}:{1:00}:{2:00}.{3:00}", ts.Hours, ts.Minutes, ts.Seconds, ts.Milliseconds / 10);
                strTimer.Reset();
                // WANT TO WRITE HERE Form1.TextBox1.text = "RunTime " + elapsedTime;
            }
        }
    }
}

【问题讨论】:

    标签: c# forms file class controls


    【解决方案1】:

    我认为,更好的方法是通过事件来处理。

    创建一个类来表示您要传递的数据。

    public class ChartCopyProgressEventArgs : EventArgs
    {
      public TimeSpan ElapsedTime { get; set; }
      //you can add more prop.s here
    }
    

    在“chartscopier”中创建一个事件来报告进度。

    class chartscopier
    {
     public static event EventHandler<ChartCopyProgressEventArgs> Changed;
     public static void CopyGraph(object data)
     {
     ...
     if (Changed != null)
     {
       var args = new ChartCopyProgressEventArgs();
       args.ElapsedTime = elapsedTime;
       Changed(null, args);
     }
     }
    }
    

    然后在 Form1 中,为该事件创建一个处理程序。

    public Form1()
    {
     InitializeComponent();
     chartscopier.Changed += UpdateStatus;
     ...
    }
    
    private void UpdateStatus(object sender, ChartCopyProgressEventArgs e)
    { 
        var ts = e.ElapsedTime;
        var elapsedTime = String.Format("{0:00}:{1:00}:{2:00}.{3:00}", ts.Hours, ts.Minutes, ts.Seconds, ts.Milliseconds / 10);
        var str = "RunTime " + elapsedTime;
    
        if (TextBox1.InvokeRequired) {
            TextBox1.Invoke(() => {TextBox1.text = str;});
        } else {
             TextBox1.text = str;
        }
    }
    

    【讨论】:

    • 不错的解决方案。请注意,如果event 的类型是Action&lt;TimeSpan&gt;,它将显着减少代码膨胀。
    • 调用if(Changed != null)时会报错非静态字段、方法或属性“成员”需要对象引用:S
    • 啊..静态的..对不起。请现在检查。还修复了事件引发代码。
    • 谢谢!!这行得通,但我需要将这个 TextBox1.Invoke(() =&gt; {TextBox1.text = str;}); 修复到这个 TextBox1.Invoke((MethodInvoker)delegate { TextBox1.Text = str; }); 以及 text for Text (大写)
    【解决方案2】:

    您需要将表单传递给该函数,以便您可以访问它,然后在表单上编写一个公共函数来修改/获取文本框。确保这两个函数正在检查是否需要调用。

    【讨论】:

      【解决方案3】:

      您需要将您希望chartscopier.CopyGraph 直接操作的引用传递给该方法,以便它可以在范围内。你的CopyGraph(object data) 签名应该更像CopyGraph(object data, TextBox aTextBox)

      然后您可以从 Form1 的实例中调用它,例如

      chartscopier.CopyGraph(data,this.textBox1)
      

      【讨论】:

        【解决方案4】:

        这个例子将向你展示如何从其他类访问表单元素:

        public partial class Form1 : Form
            {       
                private void button1_Click(object sender, EventArgs e)
                {
                    FormCopier fc = new FormCopier();
                    fc.PopulateTest(this.textBox1);
                }
            }  
        

        在其他班级..

        class FormCopier
        {
            public void PopulateTest(TextBox t)
            {
                t.Text = "Demo";
                t.Refresh();
            }
        }
        

        【讨论】:

          猜你喜欢
          • 2023-04-04
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2011-08-04
          • 2017-06-15
          • 2023-03-23
          • 1970-01-01
          相关资源
          最近更新 更多