我尝试制作管理客户联系人的应用。表格非常简单。有:面板(在此面板内是带有名称,电子邮件等的标签)和一个列表框,显示sdf文件中所有已保存的联系人。我有一个大问题。我想通过另一个类中的方法刷新列表框内容。我将列表框设置为public,调试器在项目构建期间没有显示错误。加载表单时,会提示此消息(通过try-catch异常):“对象引用未设置为对象的实例。”。我尝试以不同的方式完成这个项目 - 所有内容都写在一个类中。这是代码:
database.cs
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using System.Data.SqlServerCe;
namespace Contacts
{
class Database
{
public static void RefreshListBox()
{
SqlCeConnection connection = null;
try
{
var form1 = Form.ActiveForm as Form1;
connection = new SqlCeConnection("Datasource = C:\\Kontakty.sdf");
connection.Open();
SqlCeCommand command = new SqlCeCommand("SELECT * FROM Contacts", connection);
SqlCeDataReader reader = command.ExecuteReader();
while (reader.Read())
{
form1.listBox1.Items.Add(reader.GetString(0) + " " + reader.GetString(1));
}
}
catch(Exception exc)
{
MessageBox.Show(exc.Message);
}
}
}
Form1.cs的
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
namespace Contacts
{
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
}
private void Form1_Load(object sender, EventArgs e)
{
Database.RefreshListBox();
}
}
}
有谁在这里知道什么是错的?
PS:kontakty =联系人(捷克语; - ))
答案 0 :(得分:0)
Form.ActiveForm可能为null,因为From1仍然被加载,可能尚未显示,因此无效。
答案 1 :(得分:0)
这可能会有所帮助:
public static void RefreshListBox(ListBox listBox)
...
while (reader.Read())
{
listBox.Items.Add(reader.GetString(0) + " " + reader.GetString(1));
}
然后:
private void Form1_Load(object sender, EventArgs e)
{
Database.RefreshListBox(this.listBox1);
}
除此之外,你真的不应该将表单或列表框传递到数据库类中。它应该是另一种方式 - 你的表单应该从类中获取数据并在那里填充列表框。
答案 2 :(得分:0)
我要做的第一件事就是将对列表框的引用传递给RefreshListBox()函数。
您的课程没有理由对Form1有任何了解或参考。
以您的形式尝试:
private void Form1_Load(object sender, EventArgs e)
{
Database.RefreshListBox(this.listBox1);
}
这是你班上的:
public static void RefreshListBox(ListBox listbox)
{
SqlCeConnection connection = null;
try
{
listbox.Items.Clear() //I assume you may want to refresh?
connection = new SqlCeConnection("Datasource = "C:\\Kontakty.sdf");
connection.Open();
SqlCeCommand command = new SqlCeCommand("SELECT * FROM Contacts", connection);
SqlCeDataReader reader = command.ExecuteReader();
while (reader.Read())
{
listbox.Items.Add(reader.GetString(0) + " " + reader.GetString(1));
}
}
catch(Exception exc)
{
MessageBox.Show(exc.Message);
}
}
我遗漏了很多东西(比如坚持选定的项目),但你明白了。
此外 - 如果未指定其顺序,请不要对SQL返回值使用字段索引。按名称调用字段(我知道您不能使用CE SqlDataReader)或更好:在SQL语句中指定它们(及其顺序)。你永远不知道DB何时会被移动或重新生成,并且“Select * From ...”中的默认顺序将被激活,如果在更高版本中添加了字段,那么你只是浪费带宽/数据空间来返回它们的值如果你不打算使用它们。