我想将序列号扫描到一个列表视图中,该列表视图将数据存储到访问数据库中。当用户单击“提交”时,程序应存储数据或显示一条消息,指示序列号重复。这是我的代码:
这是我连接数据库的方式:
namespace Serial_Number_Checker
{
public partial class Form1:Form
{
static string conString = ""
OleDbConnection con = new OleDbConnection(conString);
OleDbCommand cmd;
OleDbDataAdapter adapter;
DataTable dt = new DataTable();
这是我为列表视图创建列的方式:
public Form1()
{
InitializeComponent();
listView1.SelectedIndexChanged += new EventHandler(listView1_SelectedIndexChanged); // Adding columns to listView1
// list view properities
listView1.View = View.Details;
listView1.FullRowSelect = true;
// Add Columns
listView1.Columns.Add("Employee #", 150);
listView1.Columns.Add("Serial Number", 150);
listView1.Columns.Add("Date/Time", 150);
}
这是“添加到listView”部分:
// Add To ListView1
private void populate(String employeeid, String sn, String timestamp)
{
// Row
String[] row = { employeeid, sn, timestamp };
ListViewItem item = new ListViewItem(row);
listView1.Items.Add(item);
}
这是检索功能:
// Retrieve Check In
private void retrieve()
{
listView1.Items.Clear();
//Sql statement
String sql = "Select * FROM SN_Incoming";
cmd = new OleDbCommand(sql, con);
//Open connection, retrieve, and fill listview1
try
{
con.Open();
adapter = new OleDbDataAdapter(cmd);
adapter.Fill(dt);
//Loop thru dt
foreach (DataRow row in dt.Rows)
{
populate(row[0].ToString(), row[1].ToString(), row[2].ToString());
}
con.Close();
//Clear datatable
dt.Rows.Clear();
}
catch (Exception ex)
{
MessageBox.Show(ex.Message);
con.Close();
}
}
这是“提交”按钮部分:
private void button1_Click(object sender, EventArgs e)
{
foreach (ListViewItem itemSelected in listView1.SelectedItems)
{
listView1.Items.Remove(itemSelected);
}
if (textBox1.Text == "")
{
MessageBox.Show("Please Enter A Serial Number!", "Input");
}
else
{
add(textBox1.Text);
}
textBox1.Text = "";
textBox1.Focus(); // Set Focus
textBox1.SelectionStart = textBox1.Text.Length == 0 ? 0 : textBox1.Text.Length - 1; // set text selection to end
textBox1.SelectionLength = 0; // Set text Selection Length
retrieve();
}
这应该是大多数代码。任何帮助。
答案 0 :(得分:0)
据我所知,您想避免将重复的记录添加到ListView
控件中。我将介绍防止在您的ListView
和Access Database
中重复。
ListView
在将序列号添加到控件之前,我将其分配给每个Tag
的{{1}}属性来处理。然后,为确保不添加重复项,我将使用ListViewItem
作为要添加的新序列号的参考点。例如:
Tag
以上解决方案使用// Make sure you include the using statement at the top of your code file.
using System.Linq;
private void populate(string employeeid, string, sn, string timestamp) {
ListViewItem lvi = listView1.Items.Cast<ListViewItem>()
.SingleOrDefault(s => s.Tag == sn);
if (lvi == null) {
lvi = new ListViewItem(employeeid);
lvi.SubItems.Add(sn);
lvi.SubItems.Add(timestamp);
lvi.Tag = sn;
listView1.Items.Add(lvi);
} else
MessageBox.Show("Serial number supplied already exists.");
}
,它代表Language Integrated Query。它是在.NET 3.5中引入的。该方法实际上是试图找到一个LINQ
,其中包含ListViewItem
属性,该属性的值是提供的序列号。
自Tag
to开始,method Cast
呼叫使您可以利用SingleOrDefault
可用的IEnumerable
property Items
不是源自ListView
,而是源自IEnumerable
。
您可以通过实现ListViewItemCollection
循环而不是利用foreach
将其降低到.NET的较低级别。例如:
LINQ
数据库
由于您对数据库使用Access,因此您可以按照this指南中的说明,防止列中出现重复值(在您的情况下,这将防止重复的序列号)。本质上,您只是为希望具有唯一性的字段创建唯一索引。这是通过将字段的private void populate(string employeeid, string, sn, string timestamp) {
foreach (ListViewItem lvi in listView1.Items) {
if (lvi.Tag == sn) {
MessageBox.Show("Serial number supplied already exists.");
return;
}
}
// We know the serial number doesn't exist, so just add the new item.
ListViewItem lvi = new ListViewItem(employeeid);
lvi.SubItems.Add(sn);
lvi.SubItems.Add(timestamp);
lvi.Tag = sn;
listView1.Items.Add(lvi);
}
属性设置为Indexed
来完成的。
将字段的索引属性设置为是(无重复)
- 在导航窗格中,右键单击包含该字段的表,然后单击“设计视图”。
- 选择要确保具有唯一值的字段。
- 在“字段属性”窗格中的“常规”选项卡上,将“索引”属性设置为“是(无重复)”。
有用点
Yes
表达式由编译器分解成其基本实现。例如,LINQ
遍历对象集合,尝试查找满足指定条件的单个对象,然后返回结果。如果未找到对象,则返回SingleOrDefault
。这是通过null
循环完成的。foreach
循环实际上比使用foreach
更快。在小范围内,甚至都不会注意到。但是,将必须遍历的LINQ
对象的数量增加到300,000+范围内,您将有很大的不同。ListViewItem
对象添加到通用集合,然后再通过ListViewItem
最终添加到ListView
更为有效。如果我没记错的话,这是因为AddRange
和Add
导致AddRange
重新排序,并且如上文第2点所述,您拥有的物品越多,对性能的影响就越差。我在下面提供了这种实现的示例:添加范围实现
ListView
代码重构
我自由地重构代码,以教会您更简单/有效的方法来实现目标。您可能需要查看以下文档:using statement,string.IsNullOrWhiteSpace(),string.Empty。我会用List<ListViewItem> items = new List<ListViewItem>();
for (int i = 0; i < 50000; i++) {
ListViewItem lvi = new ListViewItem($"Some kind of text {i}.");
lvi.Tag = i;
items.Add(lvi);
}
listView1.Items.AddRange(items.ToArray());
语句提示您的一件事是,在执行块的最后部分时,它将自动关闭任何打开的连接,这是由于对象的处置所致:
当
using
对象的生存期仅限于单个方法时,应在IDisposable
语句中声明并实例化它。using
语句以正确的方式在对象上调用Dispose方法,并且(如前所述,当您使用它时)它也会导致对象本身在{{3 }} 叫做。在using
块中,该对象为只读对象,无法修改或重新分配。
using