我是Winforms的新手,并且正在尝试制作一个将以DataGridView样式保存某些数据的应用程序。
现在,我设法创建了该应用程序,如果单击一个单元格,文本框,Combobox会从GridView中填充数据,但是我现在正在努力让DateTimePicker进行相同的操作...
Bellow您将看到我使用的代码将数据拨回文本和组合框,但是我错过了DateTimePicker的适当调用,我不知道该如何正确地称呼它,
private void dataGridView1_CellClick(object sender, DataGridViewCellEventArgs e)
{
index = e.RowIndex;
DataGridViewRow row = dataGridView1.Rows[index];
textBox1.Text = row.Cells[0].Value.ToString();
dateTimePicker1.Value = row.Cells[1].Value.ToString();
comboBox1.Text = row.Cells[2].Value.ToString();
textBox2.Text = row.Cells[3].Value.ToString();
}
我知道我无法转换将字符串键入System.DateTime,但我不知道该怎么做...
谢谢您。
因此,要回答您的问题Johng,
我当前的代码将一排数据添加到网格中:
private void btnInsert_Click(object sender, EventArgs e)
{
dt.Rows.Add(textBox1.Text, dateTimePicker1.Value, comboBox1.Text, textBox2.Text);
}
问题发生在我添加新行,所有行的DateTime值单元更新中的日期,这是我不想要的。
希望这会有所帮助。
校正,它仅更新选定的行,而它创建了一个新行。
I am new to WinForms and am trying to make an application that will hold certain data in a DataGridView Style.
Now I've managed to create the app where if clicked on a cell the TextBoxes and the ComboBox get populated with data from the GridView, but I am now struggling to get the DateTimePicker to do the same...
Bellow you will see the code I am using to call the data back into the text and combo boxes, but I am missing the proper call for the DateTimePicker and I don't know how to call it properly
private void dataGridView1_CellClick(object sender, DataGridViewCellEventArgs e)
{
index = e.RowIndex;
DataGridViewRow row = dataGridView1.Rows[index];
textBox1.Text = row.Cells[0].Value.ToString();
dateTimePicker1.Value = row.Cells[1].Value.ToString();
comboBox1.Text = row.Cells[2].Value.ToString();
textBox2.Text = row.Cells[3].Value.ToString();
}
I am aware I can't convert type string to System.DateTime, but I don't know how I can do that...
Thank you in advance.
So to answer your question JohnG,
My current code adds a row of data into the Grid:
private void btnInsert_Click(object sender, EventArgs e)
{
dt.Rows.Add(textBox1.Text, dateTimePicker1.Value, comboBox1.Text, textBox2.Text);
}
The issue occurs when i add a new row, the date in the DateTime value cell updates for all rows, something i do not want.
Hope this helps.
Correction, it updates only the selected row, while it creates a new row.
发布评论
评论(3)
在下面的示例中,您可能会注意到代码对网格使用
dataSource
。我强烈建议您做同样的事情,无论电网最初是空的,并且只希望用户输入数据。换句话说,它将以多种多样的方式简化事物。因此,如果我有正确的话,您有一个网格,以及一些“外部”文本框,一个日期时间选择器和一个表单上的组合框。网格中的列有一些值,例如名称,日期和其他一些值。而且……您想要的是,当用户在网格中选择一个单元/行…然后……“外部”文本框,日期时间选择器和组合框将包含与网格中所选行相同的值。
我假设您希望用户能够“编辑”文本框,并且还可以更新网格的单元格,反之亦然。如果是这种情况,则下面的示例使用此方法。
这是相当微不足道的文本框或日期时间选择器……但是,组合框有点工作,您没有指定“如何”“如何”在组合框中添加项目。换句话说,如果用户将数据输入到网格中,并且进入单元格2(组合框值),则有以下代码……
这有点奇怪,因为用户键入单元格的值将是“忽略”,除非该值实际上存在于“组合框”列表中。换句话说,这意味着对组合框中的项目列表中的项目列表中有一些预先思考。如果网格单元2本身就是一个组合盒单元,那么这可能会改变事物,但是,您仍然需要做额外的工作才能填写组合框列表。
不幸的是,即使有一个组合盒单元格…,从网格到“外部”常规组合盒的组合框“绑定”的组合框并不像看起来那样容易。如果网格中的“组合框”列表仅简单地
字符串
,而“外部”常规组合框列表列表仅简称strings
,那么这是可行的。但是,这种情况很少是这种情况,它仍然涉及与您当前方法类似的东西。因此,我将暂时遗漏“外部”组合框。下面的示例显示了如何“绑定”“外部”
textboxes
和dateTimePicker
。我们将使用简单的DataTable
作为网格的dataSource
。此外,当我们“绑定”文本框和日期时间选择器时,我们还将使用相同的DataTable
作为dataSource
。一种更好的方法是使用bindingsource
,并以后更新。首先,让我们获取一些网格的测试数据。网格将有四列:名字,姓氏,雇用日期和部门。租用日期是类型
DateTime
的列,所有其他列都是String
类型。下面的方法将返回dataTable
显示上述列……在表单范围中,我们将创建一个全局变量
griddt
,并使用上面的方法进行设置。然后,我们将将DataTable
用作网格的dataSource
。表单load
事件可能看起来像……这应该显示如下……
=“ https://i.sstatic.net/rrcxc.gif”
databindings.add
是自称的,但是可以在 control.databindings属性如果您立即运行代码,当用户选择网格中的不同行时,您会注意到文本框更改值。还应注意,这是一种“缓慢”的双向绑定。例子;如果您更改“外部”名称文本框…,那么您将不会在网格中看到此更改。根据您单击的控制,更改可能不会反映在网格中。如果单击另一个文本框或按“选项卡键”……更改可能不会在网格中显示。
同样的想法也适用于网格。如果用户更改名字单元格中的文本,则这些更改将不会“立即”反映在“外部”文本框中,直到用户在网格中选择“不同”行。如果用户按下选项卡键或单击同一行中的另一个单元格…,则将不会在外部文本框中反映更改。
从用户角度出现了一个小问题。 IMO…我想至少在用户编辑并将单元格留在网格中或用户编辑并留下“外部”文本框时“看到”这些更改。为了解决此问题,我将使用
bindingsource
而不是dataTable
作为dataSource
。切换到
bindingsource
之后,您将不会看到太大的变化,并且先前的问题持续存在。但是,这将简化我们对先前问题的解决方案。 1)我们将连接“外部”文本框离开
事件,以执行bindingsources
endedit()
方法以更新网格。 2)我们将连接网格CellValueChanged
事件,以更新外部文本框。 3)我们将使用日期拾取器离开
事件做同样的事情。注意,我为两个文本框使用了相同的
离开
事件。这些最终更改在下面…。我希望这有意义并有所帮助。
In the example below, you may note that the code uses a
DataSource
to the grid. And I highly recommend you do the same regardless if the grid is initially empty and is only expecting data to be input by the user. In other words, it will simplify things in many-many ways.So, if I have this correct, you have a grid, and some “external” text boxes, a date time picker and a combo box on a form. The columns in the grid have some values like name, date and some other values. And… is what you want is that when the user selects a cell/row in the grid… then… the “external” text boxes, date time picker and combo box will contain the same values as the selected row in the grid.
I will assume you want the user to be able to “edit” the text box and have it also update the grid’s cell and vice versa. If this is the case, then the example below uses this approach.
This is fairly trivial with a text box or date time picker… however a combo box is a little more work and you do not specify “how” you are currently adding items to the combo box. In other words, if the user is entering data into the grid and they get to cell 2 (the combo box value) you have the following code…
This is a little odd in a sense that the value the user types into the cell will be “ignored” unless the value actually exists in the combo boxes list of items. In other words, this implies some pre-thought about what items are in the combo boxes list of items. If the grids cell 2 was itself a combo box cell, then this may change things, however, you would STILL have to do extra work to fill the combo boxes list of items.
Unfortunately, even with a combo box cell…, “binding” the combo boxes value from the grid to an “external” regular combo box is not as easy as it may appear. If the combo boxes list of items in the grid were simply
strings
AND the “external” regular combo boxes list of items was simplystrings
, then this is doable. However, this is rarely the case and it would still involve something similar to your current approach. Because of this, I will leave out the “external” combo box for now.The example below shows how to “bind” the “external”
TextBoxes
andDateTimePicker
. We will use a simpleDataTable
as aDataSource
to the grid. In addition, we will also use this sameDataTable
as aDataSource
when we “bind” the text boxes and date time picker. A better approach is to use aBindingSource
and will update this later.First let us get some test data for the grid. The grid will have four columns: First Name, Last Name, Hire Date and Department. The Hire Date is a column of type
DateTime
and all others are of astring
type. The method below will return aDataTable
showing the columns described above…In the forms scope, we will create a global variable
GridDT
and set it using the method above. Then we will use theDataTable
as aDataSource
to the grid. The formsLoad
event may look something like…This should display the grid like below…
If you run this code, you will not see the text boxes and date time picker with the same values as the selected row. We still need to add the “binding” code for the controls like below…
The
DataBindings.Add
is self-explanatory, however the documentation can be found at Control.DataBindings PropertyIf you run the code now, you will note the text boxes change values when the user selects different rows in the grid. It should also be noted that this is a “slow” kind of a two-way binding. Example; If you change the “external” first name text box… then you will NOT see this change “immediately” in the grid. Depending on what control you click on, the change may not be reflected in the grid. If you click on another text box or press the Tab key… the change may not show in the grid.
The same idea applies to the grid. If the user changes the text in the first name cell, then those changes will NOT be “immediately” reflected into the “external” text box until the user selects a “different” ROW in the grid. If the user presses the Tab key or clicks on another cell in the SAME row… then the changes will NOT be reflected in the external text boxes.
This presents a little problem from a user stand point. IMO… I WANT to “see” those changes at least when the user either edits and leaves the cell in the grid OR if the user edits and leaves an “external” text box. To fix this, I will use a
BindingSource
instead of aDataTable
as theDataSource
.After we switch to the
BindingSource
, you will not see much change and the previous problems persist. However, this will simplify our solution to the previous problem. 1) We will wire up the “external” text boxesLeave
event to execute theBindingSources
EndEdit()
method to update the grid. 2) we will wire up the gridsCellValueChanged
event to do the same to update the external text boxes. 3) we will use the date time pickersLeave
event to do the same.Note I used the same
Leave
event for both text boxes. These final changes are below….I hope this makes sense and helps.
dateTimePicker.value 是
dateTime
。为了初始化
DateTime
对象,您可以使用以下一个:datetime.parse
- 返回dateTime
。如果字符串格式无效,则可能会引发异常。datetime
out 参数。如果字符串格式无效,则返回false。但是 - 由于
dateTimePicker.Value
是一个属性,因此不能以out
参数传递。如果要直接分析它,请使用分析
,如下所示。另外,您可以使用tryparse
将其解析为本地变量,然后将propety分配给它。示例使用
解析
:The type of
DateTimePicker.Value
isDateTime
.In order to initialize a
DateTime
object, you can use one of the following:DateTime.Parse
- Returns theDateTime
. May throw an exception if the string format is not valid.DateTime.TryParse
- Updates aDateTime
out parameter. Returns false if the string format is not valid.However - since
DateTimePicker.Value
is a property, it cannot be passed as anout
parameter. If you want to parse directly into it, use theParse
as you can see below. Alternatively you can useTryParse
to parse into a local variable and then assign the propety to it.Example using
Parse
:按照Johng的出色评论,使用绑定不仅解决
datetime
格式化问题;它为使用日期/时间选择器和组合框内的内联编辑提供了额外的好处,datagridview
本身。如果您想尝试这种方法,请在视图中绘制一个类以表示
row
。接下来,将其制作
bindingList< record>
...并将其设置为
dataSource
dataGridView
在此初始化方法中,该方法还安装了该方法自定义列(calendarcolumn
类从此Microsoft sample )。如果您选择不是使用内联编辑,则修改了使用绑定的处理程序代码:
Following on JohnG's excellent comment, using binding not only solves the
DateTime
formatting issue; it provides the added benefit of inline editing using date/time pickers and combo boxes within theDataGridView
itself.If you'd like to try this approach, make a class to represent a
Row
in the view.Next make a
BindingList<Record>
of them...and set it as the
DataSource
of yourDataGridView
in this initialization method which also installs the custom columns (theCalendarColumn
class is copied from this Microsoft sample).If you choose not to use inline editing, here's your handler code modified to use binding: