c# - DataGridViewComboBoxColumn:日期格式不适用于列表中的项目
问题描述
我目前正在开发一个带有 DataGridView 的 C# 应用程序,并试图将包含 DateTime 对象的 DataGridViewComboBoxColumn 显示为 ValueType 和 ValueMember。
我已经使用列的 DefaultCellStyle.Format 方法应用了格式,但这似乎只适用于选定的值,而不是列表中的所有项目。
因此,当我选择了某些内容时,它显示得很好,但是当打开下拉列表时,其中的所有项目都显示为 DateTime 对象的标准字符串表示形式。
这是预期的行为还是我错过了什么?
谢谢,
托拜厄斯·廷佩
解决方案
我猜网格的数据源是 aDataTable
并且显然组合框列是类型DateTime.
如果是这种情况,那么我相信您所描述的是因为网格单元格“值”是一个实际DateTime
对象并且网格将保持具有DateTime
对象默认方法的单元格值ToString()
……即……MM/DD/YYYY。
正如您所说,您可以格式化显示,但是当下拉可见时,这不适用于组合框中的下拉项。我猜上面可能是它以这种方式显示的原因。如果您尝试以任何其他方式对其进行格式化……网格的 dreadedDataError
很可能会出现。
一个可能的解决方案……</p>
由于组合框将包含DateTime
对象并且您有获取DateTime
对象的方法,因此我建议您将日期放入DataTable
如下结构中。这将是DataSource
组合框。
private DataTable GetComboTable() {
DataTable dt = new DataTable();
dt.Columns.Add("DateTime", typeof(DateTime));
dt.Columns.Add("StringDateTime", typeof(string));
return dt;
}
第一列 (DateTime) 将包含组合框的“实际”DateTime
对象。ValueMember
这将被映射到DateTime
网格表中的列并避免DataError.
下一个 (StringDateTime) 列将包含要在下拉列表中显示的“格式化”日期字符串。这个字符串将是组合框DisplayMember.
下面是用一些随机日期填充此表的示例。
private DataTable GetComboDates() {
DataTable dt = GetComboTable();
Random rand = new Random();
int duration = 5 * 365;
DateTime randomDate = DateTime.Today.AddDays(-rand.Next(duration));
for (int i = 0; i < 10; i++) {
dt.Rows.Add(randomDate, String.Format("{0:yyyy/MM/dd - hh:mm:ss tt}", randomDate));
randomDate = DateTime.Today.AddDays(-rand.Next(duration));
}
return dt;
}
请注意,此处的日期字符串格式适用于显示下拉菜单时用户将看到的内容。我们已经知道,如果组合列DefaultCellStyle.Format
(适用于未选择组合框时用户看到的内容)与此格式不匹配,那么它们将有所不同。这意味着列显示格式必须与此处的设置相匹配,才能获得您描述的所需行为。
现在我们有一个DataSource
适合组合框的列,下面的函数将使用它来返回一个DataGridViewComboBoxColumn
用于网格的。
private DataGridViewComboBoxColumn GetComboColumn() {
DataGridViewComboBoxColumn comboCol = new DataGridViewComboBoxColumn();
comboCol.DataPropertyName = "Dates";
comboCol.HeaderText = "Dates";
comboCol.DisplayMember = "StringDateTime";
comboCol.ValueMember = "DateTime";
comboCol.Width = 175;
DataTable comboData = GetComboDates();
comboCol.DataSource = comboData;
return comboCol;
}
注意:DataPropertyName
是网格中列的名称DataTable
;是DisplayMember
格式化日期字符串的组合数据表中列的名称;这ValueMember
是实际日期的组合数据表中的列的名称。
下面是一个对此进行测试的示例,我相信当下拉菜单不显示时,它会保持与下拉菜单相同的格式。只要两种格式相同,这应该可以工作。
DataTable GridTable;
public Form1() {
InitializeComponent();
}
private void Form1_Load(object sender, EventArgs e) {
GridTable = GetTable();
FillTable(GridTable);
dataGridView1.Columns.Add(GetComboColumn());
dataGridView1.DataSource = GridTable;
}
private DataTable GetTable() {
DataTable dt = new DataTable();
dt.Columns.Add("Col0", typeof(string));
dt.Columns.Add("Dates", typeof(DateTime));
return dt;
}
private DataGridViewComboBoxColumn GetComboColumn() {
DataGridViewComboBoxColumn comboCol = new DataGridViewComboBoxColumn();
comboCol.DataPropertyName = "Dates";
comboCol.HeaderText = "Dates";
comboCol.DisplayMember = "StringDateTime";
comboCol.ValueMember = "DateTime";
comboCol.Width = 175;
DataTable comboData = GetComboDates();
comboCol.DataSource = comboData;
return comboCol;
}
private void FillTable(DataTable dt) {
for (int i = 0; i < 10; i++) {
dt.Rows.Add("C0R" + i);
}
}
private DataTable GetComboTable() {
DataTable dt = new DataTable();
dt.Columns.Add("DateTime", typeof(DateTime));
dt.Columns.Add("StringDateTime", typeof(string));
return dt;
}
private DataTable GetComboDates() {
DataTable dt = GetComboTable();
Random rand = new Random();
int duration = 5 * 365;
DateTime randomDate = DateTime.Today.AddDays(-rand.Next(duration));
for (int i = 0; i < 10; i++) {
dt.Rows.Add(randomDate, String.Format("{0:yyyy/MM/dd - hh:mm:ss tt}", randomDate));
randomDate = DateTime.Today.AddDays(-rand.Next(duration));
}
return dt;
}
希望这会有所帮助并且有意义。
推荐阅读
- typescript - 无法 lint vue 3 typescript 应用程序,构建工作
- c# - 使用 2 小时后 CPU 运行高
- cmake - 无法链接到子弹物理库 - LNK2019、LNK2001
- javascript - 为什么 Javascript 中没有 HTMLSectionElement 和 HTMLArticleElement?
- sas - SAS:打印与最小值相关的名称
- flutter - 错误:无法解析“package:flutter_localizations/flutter_localizations.dart”中的“flutter_localizations”包
- jq - jq 使用 --arg 返回“无效的数字文字”
- c# - 如何解决 Lambda 函数中 ai_flags 的错误值错误
- swiftui - SwiftUI:“某些视图”类型的值没有成员“演示文稿”
- ubuntu - 在 Ubuntu 18 上持久化 arptables