我已将DataGridView
绑定到DataTable
并附带一些数字数据,我需要两件事来确保正常工作:
doubles
/ ints
)有没有一种简单的方法可以在DataTable级别添加它们?
我知道我可以将DataTable
列的类型更改为String
,但之后我需要添加更多代码,只是为了按已经内置的方式对列进行排序 - 我当然不需要改变绘制字形的方式等。
另外,由于我的DGV产生的数量和方式,它不会像为每个DGV添加一种方法那么容易。
[编辑]
我将同一组DataTables写入excel文件,因此对其工作方式的重大改变会产生问题且容易出错 - 我想避免使用它。
我在大多数情况下填写dataTables的代码如下所示:
var row = MyDataTable.GetMyDataTableNewRow();
row.partName = part.name;
row.weight = part.weight.ToString(); // it's double
row.quantity = part.GetParentSet().FindQuantities(part.name).ToString(); // it's int
row.maxsize = part.CalculateMaxSize().ToString();
MyDataTable.AddMyDataTableRow(row);
答案 0 :(得分:4)
在DataTable
级别定义所需行为的唯一方法是引入一个包含double和string的自定义类型,并定义适当的TypeConverter
(以正确显示对象并启用编辑在DataGridView
)。
e.g。 :
[TypeConverter(typeof(DoubleOrTextConverter))]
public class DoubleOrText : IComparable
{
public double Value { get; private set; }
public string Text { get; private set; }
public DoubleOrText(double val, string text)
{
this.Value = val;
this.Text = text;
}
public static DoubleOrText FromString(System.Globalization.CultureInfo culture, string str)
{
double v;
if (double.TryParse(str, out v))
return new DoubleOrText(v, null);
return new DoubleOrText(0, str);
}
public string ToString(System.Globalization.CultureInfo culture)
{
if (this.Text != null)
return this.Text;
return this.Value.ToString(culture);
}
// define your sorting strategy here
public int CompareTo(object obj)
{
if (obj == null) return 1;
var other = obj as DoubleOrText;
if (other != null)
return this.Value.CompareTo(other.Value);
else
throw new ArgumentException("Object is not a DoubleOrText");
}
}
public class DoubleOrTextConverter : TypeConverter
{
public override bool CanConvertFrom(ITypeDescriptorContext context, Type sourceType)
{
if (sourceType == typeof(string))
return true;
return base.CanConvertFrom(context, sourceType);
}
public override object ConvertFrom(ITypeDescriptorContext context, System.Globalization.CultureInfo culture, object value)
{
if (value is string)
return DoubleOrText.FromString(culture, value as string);
return base.ConvertFrom(context, culture, value);
}
public override object ConvertTo(ITypeDescriptorContext context, System.Globalization.CultureInfo culture, object value, Type destinationType)
{
if (destinationType == typeof(string))
{
var dValue = (DoubleOrText)value;
return dValue.ToString(culture);
}
return base.ConvertTo(context, culture, value, destinationType);
}
}
用法示例:
DataTable dt = new DataTable();
dt.Columns.Add("Column 1", typeof(DoubleOrText));
dt.Rows.Add(new DoubleOrText(0.0, null));
dt.Rows.Add(new DoubleOrText(1.0, "X"));
dt.Rows.Add(new DoubleOrText(2.3, "-"));
dt.Rows.Add(new DoubleOrText(4.1, null));
this.dataGridView1.DataSource = dt;
结果:
答案 1 :(得分:1)
使用DataGridView
,您可以在UI级别应用格式,处理您的情况,并专门更改数字列中的某些值,而不将列更改为文本。
这是使用CellFormatting
的{{1}}和CellParsing
事件实现的。
例如,假设您的数据表中有一个int列,并且您希望将所有1的实例显示为x,将所有实例3显示为y。
您使用DataGridView
事件,如下所示:
CellFormatting
使用这种方法,基础数据表与基础单元格值一样不受影响,因此格式化仍然可以像数字1和3那样工作。
然后,您需要在void dataGridView1_CellFormatting(object sender, DataGridViewCellFormattingEventArgs e)
{
if (dataGridView1.Columns[e.ColumnIndex].Name == "CustomerID")
{
if (int.Parse(e.Value.ToString()) == 1)
{
e.Value = "x";
}
else if (int.Parse(e.Value.ToString()) == 3)
{
e.Value = "y";
}
}
}
事件中进行一些处理以将字符串转换回来。这又是因为您的基础表仍然有一个数字列。
如下所示,在解析的值未转换为int的情况下,仅使用单元格的实际值。但是,您可以在此处理程序中执行任何操作:
CellParsing