C# 我试图在一个类中创建一个方法,并试图在单击按钮时从另一个类(表单)调用
这是我的第一节课:C# 我试图在一个类中创建一个方法,并试图在单击按钮时从另一个类(表单)调用,c#,winforms,class,C#,Winforms,Class,这是我的第一节课: namespace WindowsFormsApplication2 { public partial class Form1 : Form { public Form1() { InitializeComponent(); /*_enemy = new Class1(this); int y = Class1.MyMethod(0);
namespace WindowsFormsApplication2
{
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
/*_enemy = new Class1(this);
int y = Class1.MyMethod(0);
textBox1.Text = Convert.ToString (y);*/
}
private Class1 _enemy;
private void button1_Click(object sender, EventArgs e)
{
_enemy = new Class1(this);
int y = Class1.MyMethod();
textBox1.Text = Convert.ToString(y);
}
}
}
这是我的第二节课:
namespace WindowsFormsApplication2
{
public class Class1
{
public Class1( Form1 form )
{
_form1 = form;
}
public static int MyMethod()
{
int i = 0;
for (int j = 1; j <= 20; j++)
{
i = j;
//Thread.Sleep(100);
}
return i;
}
}
// DON'T initialize this with new Form1();
private Form1 _form1;
}
和class1.cpp
namespace WindowsFormsApplication2
{
public class Class1
{
public delegate void Counter(int c); // this delegate allows you to transmit an integer
public event Counter CountEvent;
public Class1()
{
}
public void MyCountMethod(int interval_msec, int start, int end)
{
System.Threading.Thread t = new System.Threading.Thread(() =>
{
for (int i = start; i <= end; i++)
{
// Check whether some other class has registered to the event
if (CountEvent != null)
{
// fire the event to transmit the counting data
CountEvent(i);
System.Threading.Thread.Sleep(interval_msec);
}
}
});
// start the thread
t.Start();
}
// DON'T initialize this with new Form1();
private Form1 _form1;
}
}
命名空间窗口窗体应用程序2
{
公共班级1
{
公共委托无效计数器(int c);//此委托允许您传输整数
公共事件计数器事件;
公共类别1()
{
}
public void MyCountMethod(int interval_msec,int start,int end)
{
System.Threading.Thread t=新的System.Threading.Thread(()=>
{
对于(int i=start;i问题是您只将最后一个值传递给GUI。您可以做的是将要用于显示的文本框传递到您的计数方法MyMethod
。您可以在其中分配值。您需要做的最后一件事是告诉应用程序使用application.do更新其事件事件();
因此,您的方法如下所示:
public static int MyMethod(TextBox t)
{
int i = 0;
for (int j = 1; j <= 20; j++)
{
i = j;
t.Text = j.ToString();
Application.DoEvents();
Thread.Sleep(200);
}
return i;
}
private void button1_Click(object sender, EventArgs e)
{
_enemy = new Class1(this);
int y = Class1.MyMethod(textBox1);
}
public partial class Form1 : Form
{
private async void button1_Click(object sender, EventArgs e)
{
Progress<int> reporter = new Progress<int>(number =>
{
textBox1.Text = number.ToString();
});
await Task.Run(() => MyClass1.MyMethod(reporter));
}
}
public class Class1
{
public static int MyMethod(IProgress<int> reporter)
{
for (int i = 1; i <= 20; ++i)
{
reporter.Report(i);
//Thread.Sleep(100);
}
return i;
}
}
在你的课堂上
Form1
中的调用如下所示:
public static int MyMethod(TextBox t)
{
int i = 0;
for (int j = 1; j <= 20; j++)
{
i = j;
t.Text = j.ToString();
Application.DoEvents();
Thread.Sleep(200);
}
return i;
}
private void button1_Click(object sender, EventArgs e)
{
_enemy = new Class1(this);
int y = Class1.MyMethod(textBox1);
}
public partial class Form1 : Form
{
private async void button1_Click(object sender, EventArgs e)
{
Progress<int> reporter = new Progress<int>(number =>
{
textBox1.Text = number.ToString();
});
await Task.Run(() => MyClass1.MyMethod(reporter));
}
}
public class Class1
{
public static int MyMethod(IProgress<int> reporter)
{
for (int i = 1; i <= 20; ++i)
{
reporter.Report(i);
//Thread.Sleep(100);
}
return i;
}
}
免责声明:正如@Default所指出的。
因此,另一种方法(可能是更好的方法)是使用计时器。它有一个勾选
事件,可以像for循环一样工作。这是System.Windows.Forms.timer
。您可以在Form1
类中使用它:
public partial class Form1 : Form
{
Timer t = new Timer();
public Form1()
{
InitializeComponent();
t.Interval = 200; // set the interval
t.Tick += T_Tick; // register to the event
}
int i = 0; // this is your counting variable
private void T_Tick(object sender, EventArgs e)
{
if (i<=20) // this takes care of the end
{
this.textBox1.Text = i.ToString();
i++; // count up
}
else
{
t.Stop(); // stop the timer if finished
i = 0; // for the next time if you want to restart the timer
}
}
private void button1_Click(object sender, EventArgs e)
{
t.Start(); // now just start your timer
}
}
我从Class1
中删除了Form1\u form
的实例,因为任务不需要它。这也使得Class1
独立于GUI的实现。(如果您决定明天更改文本框的名称
或选择标签
来显示计数器,则类别1
中不会有任何更改,仅在表格1
!)现在,您可以在表单1
中注册/订阅事件,并创建事件处理程序,在触发事件时将调用该事件处理程序:
表格1
Class1 MyCounterClass;
private void Form1_Load(object sender, EventArgs e)
{
MyCounterClass = new Class1();
// register the event. The method on the right hand side
// will be called when the event is fired
MyCounterClass.CountEvent += MyCounterClass_CountEvent;
}
private void MyCounterClass_CountEvent(int c)
{
if (textBox1.InvokeRequired)
{
textBox1.BeginInvoke(new Action(() => textBox1.Text = c.ToString()));
}
else
{
textBox1.Text = c.ToString();
}
}
由于我们不希望GUI在计数时冻结,我们将使用a在后台计数并通过事件传输数据。现在这将导致问题,因为textBox1
是由主线程创建的,如果您尝试通过另一个线程访问它,它将崩溃。因此,您需要使用该方法来显示计数器通过事件传输的ting变量
剩下的唯一一件事就是实现计数方法。正如您所看到的,我删除了static
关键字。因为这将需要将事件声明为static
,这意味着它只存在一次。如果您试图从第二个cla订阅此事件,这将导致困难党卫军
我们不会将您的循环放入线程中并让线程运行。在每次迭代中,它将触发事件并传输您的计数数据:
public void MyCountMethod(int interval_msec, int start, int end)
{
System.Threading.Thread t = new System.Threading.Thread(() =>
{
for (int i = start; i <= end; i++)
{
// Check whether some other class has registered to the event
if (CountEvent != null)
{
// fire the event to transmit the counting data
CountEvent(i);
System.Threading.Thread.Sleep(interval_msec);
}
}
});
// start the thread
t.Start();
}
等等,你有一个类可以计数并显示计数进度。它独立于图形用户界面。它必须依赖于Form1
。每个类仍然负责自己的职责。
希望它有帮助。问题是,您只将最后一个值传递给GUI。您可以做的是将要用于显示的文本框传递到您的计数方法MyMethod
。在这里您可以分配值。您需要做的最后一件事是告诉应用程序使用application.DoE更新其事件通风口();
因此,您的方法如下所示:
public static int MyMethod(TextBox t)
{
int i = 0;
for (int j = 1; j <= 20; j++)
{
i = j;
t.Text = j.ToString();
Application.DoEvents();
Thread.Sleep(200);
}
return i;
}
private void button1_Click(object sender, EventArgs e)
{
_enemy = new Class1(this);
int y = Class1.MyMethod(textBox1);
}
public partial class Form1 : Form
{
private async void button1_Click(object sender, EventArgs e)
{
Progress<int> reporter = new Progress<int>(number =>
{
textBox1.Text = number.ToString();
});
await Task.Run(() => MyClass1.MyMethod(reporter));
}
}
public class Class1
{
public static int MyMethod(IProgress<int> reporter)
{
for (int i = 1; i <= 20; ++i)
{
reporter.Report(i);
//Thread.Sleep(100);
}
return i;
}
}
在你的课堂上
Form1
中的调用如下所示:
public static int MyMethod(TextBox t)
{
int i = 0;
for (int j = 1; j <= 20; j++)
{
i = j;
t.Text = j.ToString();
Application.DoEvents();
Thread.Sleep(200);
}
return i;
}
private void button1_Click(object sender, EventArgs e)
{
_enemy = new Class1(this);
int y = Class1.MyMethod(textBox1);
}
public partial class Form1 : Form
{
private async void button1_Click(object sender, EventArgs e)
{
Progress<int> reporter = new Progress<int>(number =>
{
textBox1.Text = number.ToString();
});
await Task.Run(() => MyClass1.MyMethod(reporter));
}
}
public class Class1
{
public static int MyMethod(IProgress<int> reporter)
{
for (int i = 1; i <= 20; ++i)
{
reporter.Report(i);
//Thread.Sleep(100);
}
return i;
}
}
免责声明:正如@Default所指出的。
因此,另一种方法(可能是更好的方法)是使用计时器。它有一个勾选
事件,可以像for循环一样工作。这是System.Windows.Forms.timer
。您可以在Form1
类中使用它:
public partial class Form1 : Form
{
Timer t = new Timer();
public Form1()
{
InitializeComponent();
t.Interval = 200; // set the interval
t.Tick += T_Tick; // register to the event
}
int i = 0; // this is your counting variable
private void T_Tick(object sender, EventArgs e)
{
if (i<=20) // this takes care of the end
{
this.textBox1.Text = i.ToString();
i++; // count up
}
else
{
t.Stop(); // stop the timer if finished
i = 0; // for the next time if you want to restart the timer
}
}
private void button1_Click(object sender, EventArgs e)
{
t.Start(); // now just start your timer
}
}
我从Class1
中删除了Form1\u form
的实例,因为任务不需要它。这也使得Class1
独立于GUI的实现。(如果您决定明天更改文本框的名称
或选择标签
来显示计数器,则类别1
中不会有任何更改,仅在表格1
!)现在,您可以在表单1
中注册/订阅事件,并创建事件处理程序,在触发事件时将调用该事件处理程序:
表格1
Class1 MyCounterClass;
private void Form1_Load(object sender, EventArgs e)
{
MyCounterClass = new Class1();
// register the event. The method on the right hand side
// will be called when the event is fired
MyCounterClass.CountEvent += MyCounterClass_CountEvent;
}
private void MyCounterClass_CountEvent(int c)
{
if (textBox1.InvokeRequired)
{
textBox1.BeginInvoke(new Action(() => textBox1.Text = c.ToString()));
}
else
{
textBox1.Text = c.ToString();
}
}
由于我们不希望GUI在计数时冻结,我们将使用a在后台计数并通过事件传输数据。现在这将导致问题,因为textBox1
是由主线程创建的,如果您尝试通过另一个线程访问它,它将崩溃。因此,您需要使用该方法来显示计数器通过事件传输的ting变量
剩下的唯一一件事就是实现计数方法。正如您所看到的,我删除了static
关键字。因为这将需要将事件声明为static
,这意味着它只存在一次。如果您试图从第二个cla订阅此事件,这将导致困难党卫军
我们不会将您的循环放入线程中并让线程运行。在每次迭代中,它将触发事件并传输您的计数数据:
public void MyCountMethod(int interval_msec, int start, int end)
{
System.Threading.Thread t = new System.Threading.Thread(() =>
{
for (int i = start; i <= end; i++)
{
// Check whether some other class has registered to the event
if (CountEvent != null)
{
// fire the event to transmit the counting data
CountEvent(i);
System.Threading.Thread.Sleep(interval_msec);
}
}
});
// start the thread
t.Start();
}
等等,你有一个类可以计数并显示计数进度。它独立于图形用户界面。它必须依赖于Form1
。每个类仍然负责自己的职责。
希望对你有所帮助也许想想某个事件
namespace WindowsFormsApplication2 {
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
/*_enemy = new Class1(this);
int y = Class1.MyMethod(0);
textBox1.Text = Convert.ToString (y);*/
}
private Class1 _enemy;
private void button1_Click(object sender, EventArgs e)
{
_enemy = new Class1(this);
_enemy.LoopInteration += OnLoopInteration;
_enemy.MyMethod();
_enemy.LoopInteration -= OnLoopInteration;
}
private void OnLoopInteration(object sender, LoopCounterArgs e)
{
textBox1.Text = Convert.ToString(e.Iteration);
}
}
}
第二种形式:
namespace WindowsFormsApplication2
{
public class Class1
{
public event EventHandler<LoopCounterArgs> LoopInteration;
public Class1( Form1 form )
{
_form1 = form;
}
public void MyMethod()
{
for (int j = 1; j <= 20; j++)
{
LoopInteration?.Invoke(this, new LoopCounterArgs(j));
//Thread.Sleep(100);
}
}
}
// DON'T initialize this with new Form1();
private Form1 _form1;
}
我还没有测试过这个,所以可能包含一些错误,但应该有很多
您可能需要重新考虑textBox1.Text语句,因为它可以很快工作,