Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/blackberry/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 我试图在一个类中创建一个方法,并试图在单击按钮时从另一个类(表单)调用_C#_Winforms_Class - Fatal编程技术网

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语句,因为它可以很快工作,