我正在尝试制作一个充当 parking 场的程序。
到目前为止,我使用了一些功能,一切都工作正常,直到我尝试在 parking 场添加一辆新车。
在这种情况下我尝试使用 add 方法,但找不到问题所在。虽然当我在 Form_Load 事件中使用该方法时它可以正常工作,但它在 Button_Click
事件处理程序中不起作用。
我的类(class)是这样的:
class Parking
{
public int Spot { get; set; }
public string Plate { get; set; }
public DateTime EnterTime { get; set; }
public DateTime? ExitTime { get; set; }
public Parking(int spot, string plate, DateTime enterTime)
{
Spot = spot;
Plate = plate;
EnterTime = enterTime;
ExitTime = null;
}
}
到目前为止我的代码:
public partial class Form1 : Form
{
Timer clock = new Timer();
List<Parking> parking = new List<Parking>();
public Form1()
{
InitializeComponent();
GetLoadDataBase();
}
private void GetLoadDataBase()
{
parking.AddRange(new List<Parking>
{
new Parking(1, "TKN1893", DateTime.Now),
new Parking(2, "TKN1951", DateTime.Now),
new Parking(3, "TNA725", DateTime.Now),
new Parking(4, "TNA725", DateTime.Now),
new Parking(5, "TNA725", DateTime.Now),
new Parking(6, "TNA725", DateTime.Now),
new Parking(7, "TNA725", DateTime.Now),
new Parking(8, "TNA725", DateTime.Now)
});
}
private void Form1_Load(object sender, EventArgs e)
{
clock.Interval = 1000;
clock.Tick += new EventHandler(this.clock_Tick);
clock.Start();
*parking.Add(new Parking(10, "IP3147", DateTime.Now));
dataGridView1.DataSource = parking;
}
private void DataGridView1_CellDoubleClick(object sender, DataGridViewCellEventArgs e)
{
try
{
string spot = dataGridView1.Rows[e.RowIndex].Cells[0].Value.ToString();
string plate = dataGridView1.Rows[e.RowIndex].Cells[1].Value.ToString();
string enterTime = dataGridView1.Rows[e.RowIndex].Cells[2].Value.ToString();
ExitTimeInsert(e.RowIndex, parking);
string exitTime = dataGridView1.Rows[e.RowIndex].Cells[3].Value.ToString();
string BoxText = spot + " " + plate + " " + enterTime + " " + exitTime;
DialogResult charge = MessageBox.Show(BoxText, "Test", MessageBoxButtons.YesNo, MessageBoxIcon.Question);
if (charge == DialogResult.Yes)
{
parking[e.RowIndex] = null;
dataGridView1.Refresh();
}
else
{
parking[e.RowIndex].ExitTime = null;
}
}
catch(NullReferenceException)
{
MessageBox.Show("The Spot is Empty!");
}
}
private void ExitTimeInsert(int index, List<Parking> parking)
{
parking[index].ExitTime = DateTime.Now;
}
private void clock_Tick(object sender, EventArgs e)
{
//get current time
int hh = DateTime.Now.Hour;
int mm = DateTime.Now.Minute;
int ss = DateTime.Now.Second;
//time
string date = DateTime.Now.Date.ToLongDateString();
string time = "";
//padding leading zero
if (hh < 10)
{
time += "0" + hh;
}
else
{
time += hh;
}
time += ":";
if (mm < 10)
{
time += "0" + mm;
}
else
{
time += mm;
}
time += ":";
if (ss < 10)
{
time += "0" + ss;
}
else
{
time += ss;
}
//update label
label1.Text = time;
label2.Text = date;
}
private void Exit_Click(object sender, EventArgs e)
{
System.Windows.Forms.Application.Exit();
}
private void Input_Button_Click(object sender, EventArgs e)
{
**Parking Adition = new Parking(10, "IP3147", DateTime.Now);
**parking.Add(Adition);
**parking.Add(new Parking(10, "IP3147", DateTime.Now));
**Add_Record(textBox1.Text);
**dataGridView1.DataSource = parking;
dataGridView1.Refresh();
}
private void Add_Record(string value)
{
**parking.Add(new Parking(10, value, DateTime.Now));
**dataGridView1.DataSource = parking;
}
}
我希望这是有道理的:
“*”“有效的实现” “**”“单独尝试的实现并非全部一起尝试,但不起作用”
其他一切正常。
最佳答案
当DataGridView的DataSource为标准时List<T>
,List<T>
上的更改内容不会自动反射(reflect)在 DataGridView 中:List<T>
不会发送更新通知。
将 DataGridView 的 DataSource 属性重新设置为相同的 List<T>
也不会刷新数据,因为 DataSource 对象引用实际上是相同的。
在.Net源码中可以看到:DataGridView.DataSource property setter 。
set
{
if (value != this.DataSource) { ... }
value
是 =
至this.DataSource
:数据源相同,因此不执行任何操作。
将 DataSource 属性设置为 null
然后再回到之前的List<T>
将重置数据源。
另一个选项(可能更可取)是使用 BindingList而不是List<T>
。
The
BindingList<T>
class can be used as a base class to create a two-way data-binding mechanism.BindingList<T>
provides a concrete, generic implementation of theIBindingList
interface.
让我们使用当前设置让它工作:
- 添加
Parking
元素添加到 BindingList(表单构造函数或Form.Load
) - 设置
DataGridView.DataSource
BindingList 对象的属性。
使用 BindingList
与使用标准 List<T>
几乎相同.
请注意,当您从 BindingList
添加或删除元素时,DataGridView 会立即更新,无需任何进一步操作:
private BindingList<Parking> parking = null;
public Form1()
{
InitializeComponent();
var tmpList = new List<Parking>
{
new Parking(1, "TKN1893", DateTime.Now),
new Parking(2, "TKN1951", DateTime.Now),
new Parking(3, "TNA725", DateTime.Now),
};
this.parking = new BindingList<Parking>();
tmpList.ForEach(elm => parking.Add(elm));
}
private void Form1_Load(object sender, EventArgs e)
{
//(...)
this.dataGridView1.DataSource = this.parking;
}
private void btnAddRecord_Click(object sender, EventArgs e)
{
this.parking.Add(new Parking(10, "IP3147", DateTime.Now));
}
private void btnRemoveRecord(string value)
{
this.parking.RemoveAt(0);
}
关于c# - List<T> Add 方法在 Button.Click 事件中不起作用,但在 Form.Load 中起作用,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/54762091/