C#通过静态方法

时间:2015-07-13 13:08:25

标签: c# winforms static scope encapsulation

我正在处理一个静态的方法,并从WinForm返回一个值,它会在按钮点击时生成新表单,并且在按下提交或取消按钮时它会返回其值。

问题是,我不能在我的表单上引用一个组合框控件来填充我的sqlreader的结果。

我已经阅读过使用类似于

的包装器的建议
public ComboBox comboHolder { get return this.foo } 
然而,我似乎无法提及它。有什么建议可以解决这个问题吗?

完整代码

        public ComboBox comboboxWrapper
    {
        get { return this.comboUsernames; }
    }
    public static string SelectProfile()
    {

        Form selectProfile = new Select_Profile();
        selectProfile.ShowDialog();

        SqlConnection connection = new SqlConnection(@"Data Source=(LocalDB)\v11.0;AttachDbFilename=|DataDirectory|\Users.mdf;Integrated Security=True;Connect Timeout=30");
        connection.Open();
        SqlCommand command = new SqlCommand("SelectAllUsers", connection);
        SqlDataReader usersReader = command.ExecuteReader();

        List<string> accountNames = new List<string>();

        while (usersReader.Read())
        {
            accountNames.Add((string)usersReader["Username"]);
        }

        //populate the combo box

        foreach (string s in accountNames)
        {
           //I'd like to call comboboxWrapper here.

        }
        //set the combo box to have a default item
       // combo.SelectedIndex = 0;
    }

此外,这是一项正在进行中的工作,我意识到我应该尝试一下,抓住并最终声明,除此之外我还要接受任何代码改进建议。

谢谢!

4 个答案:

答案 0 :(得分:1)

我建议不要将方法设为静态。但是,如果您出于某种原因确实需要,可以将对表单的引用传递给静态方法,例如:

SelectProfile(Form myForm)

然后你就可以在这样的方法中使用它:

foreach (string s in accountNames)
{
   // e.g myForm.comboboxWrapper
}

答案 1 :(得分:0)

你的静态方法需要类的对象,你必须传递comboboxwrapper定义的类的对象

public static string SelectProfile(ClassobjectofCoboboxWrapper obj)
{
    obj.comboboxWrapper;
}

从外部调用此方法

SelectProfile(new ClassobjectofCoboboxWrapper())   

注意: 由于静态方法与对象的实例无关,它与类有关。所以要在静态方法中引用非静态的元素,你需要创建引用类的对象,或者你需要传递你想要引用的类的对象。

答案 2 :(得分:0)

这是您的表单实例:

Form selectProfile = new Select_Profile();

因此,您要在该实例上调用comboboxWrapper

selectProfile.comboboxWrapper

首先,您需要更改其类型,因为Form没有名为comboboxWrapper的成员。相反地​​声明它:

Select_Profile selectProfile = new Select_Profile();

或简单地说:

var selectProfile = new Select_Profile();

尽管comboboxWrapper成员是在static方法之外定义的,但 表单实例。 static成员没有特定实例的默认概念,需要提供一个。或者,在这种情况下,在内部创建一个。

答案 3 :(得分:0)

首先,分解您的解决方案:只需将 cram 数据库和UI分解为单个方法。接下来想一想你的方法应该返回作为String

public static IEnumerable<String> AccountNames() {
  //TODO: Move it into Settings/Config... 
  String connectionString = @"Data Source=(LocalDB)\v11.0;AttachDbFilename=|DataDirectory|\Users.mdf;Integrated Security=True;Connect Timeout=30";

  // Dispose (via using) all Disposable...  
  using (SqlConnection connection = new SqlConnection(connectionString)) {
    connection.Open();

    // Dispose: prevent resource leakage...
    using (SqlCommand command = new SqlCommand("SelectAllUsers", connection)) {
      using (SqlDataReader usersReader = command.ExecuteReader()) {
        while (usersReader.Read())
          yield return (string)usersReader["Username"];
      }
    } 
  }
}

// returns selected profile 
// or null if no profile was seelcted
public static string SelectProfile() {
  // var: You need Select_Profile, not just a Form, right?
  // again (using): don't forget to clear up the resources
  using (var selectProfile = new Select_Profile()) {
    // Providing that comboboxWrapper is public (bad practice) 
    // or SelectProfile() is implemented within Select_Profile class (good   one) 
    selectProfile.comboboxWrapper.Items.AddRange(AccountNames());

    if (selectProfile.comboboxWrapper.Items.Count > 0)
      selectProfile.comboboxWrapper.SelectedIndex = 0;

    if (selectProfile.ShowDialog() == System.Windows.Forms.DialogResult.OK) {
      if (selectProfile.comboboxWrapper.SelectedIndex < 0)
        return null; // No item to select
      else
        selectProfile.comboboxWrapper.SelectedItem.ToString();
    }
    else 
      return null; // Just closed
  }
}