如何将字节数组转换为DataGridView的字符串
本文关键字:DataGridView 字符串 转换 数组 字节 字节数 | 更新日期: 2023-09-27 18:08:51
我有一个域类用户,具有以下属性(字段):
UserId (int)
UserName (nvarchar(25))
SecurePassword (varbinary(32))
Salt (varbinary(32))
SecurePassword和Salt存储一个长度为32的字节数组,您可能已经猜到了。如果我设置
BindingSource.DataSource = context.Users.Local.ToBindingList();
然后我的
DataGridView.DataSource = BindingSource;
我会得到一个错误告诉我处理GridView的DataError事件。一旦我用空方法这样做了,SecurePassword和Salt列就会为每一行显示[X]。
现在,我可以使用linq将其呈现为匿名类型:
var data = from u in context.Users
select new
{
u.UserId,
u.UserName,
SecurePassword = BitConverter.ToString(u.SecurePassword),
Salt = BitConverter.ToString(u.Salt)
};
但是我真的不想要匿名类型。在WPF中,我可以编写一个继承IValueConverter的转换器,但这似乎在WinForms中不可用。
使用CellFormatting事件。比如:
void dataGridView_CellFormatting(object sender, DataGridViewCellFormattingEventArgs e)
{
// 2 - Salt, 3 - SecurePassword
if (e.ColumnIndex == 2 || e.ColumnIndex == 3)
{
if (e.Value != null)
{
byte[] array = (byte[])e.Value;
e.Value = BitConverter.ToString(array);
e.FormattingApplied = true;
}
else
e.FormattingApplied = false;
}
}
在另一个答案的基础上,我实现它的最简单方法是:
- 进入你的DataGridView的属性,找到Columns属性,编辑它,并改变你的二进制列的ColumnType为DataGridViewTextBoxColumn。
- 进入Events窗格并生成一个关于CellFormatting事件的方法。
- 设置方法的代码如下:
private void dataGridView1_CellFormatting(object sender, DataGridViewCellFormattingEventArgs e)
{
if (e.ColumnIndex == 1 || e.ColumnIndex == 2)
{
if (e.Value != null)
{
e.Value = Encoding.UTF8.GetString((byte[]) e.Value);
e.FormattingApplied = true;
}
else
e.FormattingApplied = false;
}
}
当绑定到一个包含字节数据的表时,我遇到了类似的问题,因此我编写了以下方法,创建一个新的文本列,将其添加到表中,在将字节列转换为字符串时复制数据,将新列移动到旧列的位置,并删除旧列
下面是vb 中的代码Private Sub ReplaceByteColumns(table As DataTable)
Dim byteColumns As New Dictionary(Of DataColumn, DataColumn)
For Each column As DataColumn In table.Columns
If column.DataType = GetType(Byte()) Then
Dim byteColumn As New DataColumn
byteColumn.DataType = GetType(String)
byteColumns.Add(column, byteColumn)
End If
Next
For Each column As DataColumn In byteColumns.Keys
Dim byteColumn As DataColumn = byteColumns(column)
table.Columns.Add(byteColumn)
For Each row As DataRow In table.Rows
row.Item(byteColumn) = BitConverter.ToString(CType(row.Item(column), Byte()))
Next
byteColumn.SetOrdinal(column.Ordinal)
byteColumn.ReadOnly = True
table.Columns.Remove(column)
byteColumn.ColumnName = column.ColumnName
Next
End Sub
下面是使用https://www.carlosag.net/tools/codetranslator/
自动转换为c#的代码private void ReplaceByteColumns(DataTable table) {
Dictionary<DataColumn, DataColumn> byteColumns = new Dictionary<DataColumn, DataColumn>();
foreach (DataColumn column in table.Columns) {
if ((column.DataType == typeof(byte[]))) {
DataColumn byteColumn = new DataColumn();
byteColumn.DataType = typeof(string);
byteColumns.Add(column, byteColumn);
}
}
foreach (DataColumn column in byteColumns.Keys) {
DataColumn byteColumn = byteColumns[column];
table.Columns.Add(byteColumn);
foreach (DataRow row in table.Rows) {
row.Item[byteColumn] = BitConverter.ToString(((byte[])(row.Item[column])));
}
byteColumn.SetOrdinal(column.Ordinal);
byteColumn.ReadOnly = true;
table.Columns.Remove(column);
byteColumn.ColumnName = column.ColumnName;
}
}