在表格/类之间共享信息

时间:2017-04-04 23:53:57

标签: c# winforms

我知道标题问题不是唯一的,而且很多消息都可用。我打开一个帖子的原因是我真的很难根据我的项目来理解这个问题。

最近,我尝试启动WinForm以从REST API获取值。

就像在单击metroButton1时对Form1的开始测试一样,我应该将一个SessionToken添加到metroTextBox1.Text,这是有效的。

我在努力将输出用作getvirtualmachine类的输入。

在类中使用Form1.connect()获取SessionToken后,我正在关注错误:

  

非静态字段,方法或属性需要对象引用' Form1.connect()'

我不确定如何将其全局用作几个类的输入。猜猜我在某种程度上/某个地方犯了一个大错误。

FORM1

public partial class Form1 : MetroFramework.Forms.MetroForm
{
    public Form1()
    {
        InitializeComponent();
    }

    private void Form1_Load(object sender, EventArgs e)
    { }

    public string connect()
    {
        var httpWebRequest = (HttpWebRequest)WebRequest.Create("http://localhost:35113/api/sessions/start");
        httpWebRequest.Headers["Authorization"] = "Basic " + Convert.ToBase64String(Encoding.Default.GetBytes(metroTextBox3.Text + ":" + metroTextBox4.Text));
        httpWebRequest.ContentType = "application/json";
        httpWebRequest.Method = "POST";

        using (var streamWriter = new StreamWriter(httpWebRequest.GetRequestStream()))
        {
            string json = JsonConvert.SerializeObject(new
            {
                ServerPort = "35107",
                Username = metroTextBox3.Text,
                Password = metroTextBox4.Text,
                Domain = metroTextBox5.Text
            });

            streamWriter.Write(json);
        }

        var httpResponse = (HttpWebResponse)httpWebRequest.GetResponse();
        using (var streamReader = new StreamReader(httpResponse.GetResponseStream()))
        {
            var result = streamReader.ReadToEnd();
            dynamic item = Newtonsoft.Json.JsonConvert.DeserializeObject(result);
            return (string)item.Data;
        }
    }

    public  void metroButton1_Click(object sender, EventArgs e)
    {
        metroTextBox1.Text = connect();
    }

GetVirtualMachines类

public class GetVirtualMachines
{
    public  string gVM()
    {
        var httpWebRequest = (HttpWebRequest)WebRequest.Create("http://localhost:35113/api/vms/list/");
        httpWebRequest.ContentType = "application/json";
        httpWebRequest.Method = "GET";

        using (var streamWriter = new StreamWriter(httpWebRequest.GetRequestStream()))
        {
            string json = JsonConvert.SerializeObject(new
            {
                SessionToken = Form1.connect(),
            });

            streamWriter.Write(json);
        }

        var httpResponse = (HttpWebResponse)httpWebRequest.GetResponse();
        using (var streamReader = new StreamReader(httpResponse.GetResponseStream()))
        {
            var result = streamReader.ReadToEnd();
            dynamic item = Newtonsoft.Json.JsonConvert.DeserializeObject(result);
            return item;
        }
    }
}

2 个答案:

答案 0 :(得分:0)

您需要将方法设为静态,因此它是类定义的一部分而不是实例方法,即

public static string connect()

或创建Form1的实例并使用该实例调用connect()。然而,这最终会产生另一个问题,因为现在你已经在内存中挂出了一个没有人看到的表单(并且会阻止应用程序关闭),所以你真的应该确保它被处理掉,即

using(var form = new Form1)
{
    form.connect();
}

然而,我更大的问题是,你为什么要用Form来执行这个操作呢。在我看来,更像是connect()类属于GetVirtualMachines类。

目前,考虑到您展示的代码,这对工具集的使用非常糟糕。

答案 1 :(得分:0)

您需要在此重新考虑您的方法。 Windows窗体(Form1)是用户看到的实际GUI。您的后端GetVMs类似乎纯粹用于数据处理,而用户并未实际与之交互。

因此,您可以真正让GetVMs类创建Windows窗体的新实例,因为用户无法看到您新建的表单(这里简化了很多!)。

我会通过遵循相对标准的视图/控制器类型模式来解决这个问题:

  1. 您的Windows窗体是视图 - 这是用户看到的内容
  2. 表单包含GetVMs类private GetVirtualMachines VMGetter
  3. 的实例
  4. 表单通过类的实例(GetVirtualMachines)调用VMGetter的方法,并使用文本框中的任何内容传递参数。
  5. 这仍然不是我给出的简化方法中最好的想法,因为你将挂起UI线程。但是,希望它能给你一个跳跃点。

    编辑:我还将connect方法及其业务逻辑移动到GetVMs类。通常,我们会尝试在所有视图/显示类中避免使用业务逻辑。