【问题标题】:access form's text box value from another class in c# in timer在计时器中从 c# 中的另一个类访问表单的文本框值
【发布时间】:2016-07-13 22:04:30
【问题描述】:

我想在表单“Form1”的文本框中显示 DateTime。我创建了一个类“schedule”来创建一个间隔为 1 秒的计时器。但无法访问和更新 Form1 的文本框字段“xdatetxt”。我不明白为什么它没有访问 Form1 中的控件 xdatetxt。

Schedule.cs

class Schedule{

System.Timers.Timer oTimer = null;
    int interval = 1000;
    public Form anytext_Form;

    public Schedule(Form anytext_form)
    {
        this.anytext_Form = anytext_form;
    }

    public void Start()
    {           
        oTimer = new System.Timers.Timer(interval);
        oTimer.Enabled = true;
        oTimer.AutoReset = true;
        oTimer.Start();
        oTimer.Elapsed += new System.Timers.ElapsedEventHandler(oTimer_Elapsed);
    }

    private void oTimer_Elapsed(object sender, System.Timers.ElapsedEventArgs e)
    {//i want to put here a line like             "anytext_Form.xdatetxt.Text = System.DateTime.Now.ToString();"
    }
}

在form1.cs中:

public partial class Form1 : Form{

    public Form1()
    {
        InitializeComponent();
        InitializeScheduler();
    }
    void InitializeScheduler()
    {
        Schedule objschedule = new Schedule(this);
        objschedule.Start();
    }


    private void Form1_Load(object sender, EventArgs e)
    {

    }
}

【问题讨论】:

    标签: c# winforms timer


    【解决方案1】:

    检查这个 SO 线程 - How to access Winform textbox control from another class?

    1. 基本上公开一个更新Textbox的公共属性

    2. 公开文本框

    另外请注意,您需要在 UI 线程中更新表单控件

    【讨论】:

      【解决方案2】:

      所以你需要获取你想要修改文本的表单实例。您可以通过传递对 objschedule 的引用或使用 Application.openforms 来实现。

      如果您已经引用了表单,则第一种方法是完美的,但如果您没有,只需:

      private void oTimer_Elapsed(object sender, System.Timers.ElapsedEventArgs e)
      {
          dynamic f = System.Windows.Forms.Application.OpenForms["anytext_Form"];
          f.xdatetxt.Text=System.DateTime.Now.ToString();
      }
      

      【讨论】:

        【解决方案3】:

        这里有一些问题,但都可以直接解决。

        问题一:通过基类引用表单

        您的Schedule 类的构造函数采用Form 的实例。那是 Form1 类的基类,它没有 xdatetxt 字段。将 Schedule 构造函数更改为接受并存储 Form1 的实例:

        public Form1 anytext_Form;
        
        public Schedule(Form1 anytext_form)
        {
            this.anytext_Form = anytext_form;
        }
        

        问题 2:从非 ​​UI 线程更新控件

        一旦您修复了编译器错误,您将遇到运行时错误。原因是Timer 类在后台线程上执行其回调。您的回调方法尝试从该后台线程访问 UI 控件,这是不允许的。

        我可以在这里提供一个内联解决方案,但我会向您指出另一个 StackOverflow 帖子,其中包含有关该问题以及如何解决它的更多详细信息:Cross-thread operation not valid

        【讨论】:

        • 老大,我在为 schedule 类创建对象时引用 Form1 类.. Schedule objschedule = new Schedule(this);我不能写 public Sc​​hedule(Form1 anytext_form) 因为 Form2 也可能被引用而不是 Form1
        • xdatetxt 字段在 form1.designer.cs private System.Windows.Forms.Timer timer1 中可用; public System.Windows.Forms.TextBox xdatetxt;
        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2012-09-07
        • 2023-04-04
        • 2016-05-06
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多