更改另一个命名空间中另一个类的按钮文本

时间:2015-10-14 19:07:18

标签: c# .net button

我在另一个名称空间中从另一个类更改文本时遇到问题。我有第一个Form1课程:

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
using System.Runtime.InteropServices;

namespace WindowsFormsApplication1
{  
    public partial class Form1 : Form
    {
        static Form1 mainForm;

        [DllImport("kernel32.dll", SetLastError = true)]
        [return: MarshalAs(UnmanagedType.Bool)]
        static extern bool AllocConsole();

        public static String LinkToApi = "http://google.com/api/";
        public static Comunicator comunicator;
        public static int debug = 5;

        public Form1()
        {
            InitializeComponent();
            AllocConsole(); // allow console

            if(Form1.debug >= 3) Console.WriteLine("Application started");

            comunicator = new Comunicator();

            mainForm = this;
        }

        private void TestButton_Click(object sender, EventArgs e)
        {
            TestButton.Text = "Loading";
            comunicator.TestConnection();
        }
    }
}

和此Comunicator

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Net;
using System.Collections.Specialized;
using System.Windows.Forms;
using System.Runtime.InteropServices;

using System.IO;
using System.Threading;

namespace WindowsFormsApplication1
{
    public class Comunicator
    {
        private String action = "idle";

        public static Thread Start(Action action)
        {
            Thread thread = new Thread(() => { action(); });
            thread.Start();
            return thread;
        }

        public Comunicator()
        {
        }

        public void TestConnection()
        {
            if (Form1.debug >= 3) Console.WriteLine("Testing connection");

            // thread test
            Start(new Action(ApiTest));
        }

        public void ApiTest()
        {
            if (Form1.debug >= 3) Console.WriteLine("API test begin");

            // Create a request for the URL.        
            WebRequest request = WebRequest.Create("http://www.bogotobogo.com/index.php");

            // If required by the server, set the credentials.
            request.Credentials = CredentialCache.DefaultCredentials;

            // Get the response.
            HttpWebResponse response = (HttpWebResponse)request.GetResponse();

            // Display the status.
            Console.WriteLine(response.StatusDescription);

            // Get the stream containing content returned by the server.
            Stream dataStream = response.GetResponseStream();

            // Open the stream using a StreamReader for easy access.
            StreamReader reader = new StreamReader(dataStream);

            // Read the content.
            string responseFromServer = reader.ReadToEnd();

            // Display the content.
            Console.WriteLine(responseFromServer);

            // Cleanup the streams and the response.
            reader.Close();
            dataStream.Close();
            response.Close();

            // Console.Read();

            if (Form1.debug >= 3) Console.WriteLine("API test end");
            // Form1.StaticTestButton.Text = "Loaded";   <---- CHANGE HERE
        }
    }
}

甚至不是表格类(我想保持一切都很好和干净)。我想将TestButton文本更改为“已加载”,但在尝试执行此操作时出现错误,就像Form1.TestButton类中不存在Comunicator一样。

我试图实例化这个类,我做了几个变量静态...没有,仍然出错。

有什么问题?我怎么解决这个问题?

请求必须是异步的,这就是我使用线程的原因。

2 个答案:

答案 0 :(得分:1)

您应该分开关注点,并且您不应该在课堂上与UI进行通信,这与UI无关。 你应该重写你的代码。 但作为快速解决方案,您应该执行以下操作。

在课程Comunicator中,您可以执行此类字段。

private readonly Action<string> _notifySimpleMessageAction;

然后添加到Communicator构造函数参数notifyFunction。构造函数中的代码:

_notifySimpleMessageAction = notifyFunction

之后,您应该按照以下方式创建Communicator:

communicator = new Communicator((notification)=>
    {
                StaticTestButton.BeginInvoke((MethodInvoker)(() => StaticTestButton.AppendText(notification)));
            });

然后在你的方法结束时你应该

_notifySimpleMessageAction("Loaded")    

答案 1 :(得分:0)

控制器类:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;

namespace ControllerDemonstrator
{
    public class Controller
    {
        public event EventHandler CommunicatorDataLoaded;
        public event EventHandler FormTestConnection;

        private Form1 _form;
        private Communicator _communicator;

        public Form1 MainForm
        {
            get { return _form; }
        }

        public Controller()
        {
            _form = new Form1(this);
            _form.TestConnection += _form_TestConnection;
            _form.FormClosed += _form_FormClosed;
            _communicator = new Communicator(this);
            _communicator.DataLoaded += _communicator_DataLoaded;
        }

        public void Start()
        {
            _form.Show();
        }

        void _form_FormClosed(object sender, System.Windows.Forms.FormClosedEventArgs e)
        {
            //  put any code to clean up the communicator resources (if needed) here
            //  --------------------------------------------------------------------
            _communicator = null;
            //  Then exit
            //  ---------
            Application.Exit();
        }

        private void _communicator_DataLoaded(object sender, EventArgs e)
        {
            if (null != CommunicatorDataLoaded)
            {
                CommunicatorDataLoaded(sender, e);
            }
        }

        private void _form_TestConnection(object sender, EventArgs e)
        {
            if (null != FormTestConnection)
            {
                FormTestConnection(sender, e);
            }
        }
    }
}

带一个按钮的基本表单(_testButton):

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;

namespace ControllerDemonstrator
{
    public partial class Form1 : Form
    {
        public event EventHandler TestConnection;

        public Form1(Controller controller)
        {
            InitializeComponent();
            controller.CommunicatorDataLoaded += controller_CommunicatorDataLoaded;
        }

        void controller_CommunicatorDataLoaded(object sender, EventArgs e)
        {
            _testButton.Text = "Loaded";
        }

        private void _testButton_Click(object sender, EventArgs e)
        {
            if (null != TestConnection)
            {
                TestConnection(this, new EventArgs());
            }
        }
    }
}

Communicator类(所有内容都已被删除,您需要添加逻辑):

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace ControllerDemonstrator
{
    public class Communicator
    {
        public event EventHandler DataLoaded;

        public Communicator(Controller controller)
        {
            controller.FormTestConnection += controller_FormTestConnection;
        }

        private void controller_FormTestConnection(object sender, EventArgs e)
        {
            //  put your code that does the connection here
            //  -------------------------------------------
            if (null != DataLoaded)
            {
                DataLoaded(this, new EventArgs());
            }
        }
    }
}

在你的Program.cs中(假设你是如何开始申请的):

using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using System.Windows.Forms;

namespace ControllerDemonstrator
{
    static class Program
    {
        /// <summary>
        /// The main entry point for the application.
        /// </summary>
        [STAThread]
        static void Main()
        {
            Application.EnableVisualStyles();
            Application.SetCompatibleTextRenderingDefault(false);
            Controller c = new Controller();
            Application.Run(c.MainForm);
        }
    }
}

通过这种设计,传播者不知道形式和反面。您可以将其扩展为具有不同类型的通信器/表单/等,并让控制器跟踪所有内容。测试这样的代码也要容易得多,因为你可以自己测试每个单独的部分,因为它们不相互依赖。这是一个快速而肮脏的实现。做一些关于模型视图控制器设计模式的研究(不是用于asp.Net的Microsoft MVC,而是实际的设计模式)。使用MVC设计模式对应用程序进行代码编写需要更多的代码,但它使测试更容易,更易于维护。