如何将字节数组转换为 DataGridView 的字符串

How to Convert a Byte Array to String for a DataGridView

我有一个具有以下属性(字段)的域 Class 用户:

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;
    }
}

以其他答案为基础,我实现此目的的最简单方法是:

  1. 进入 DataGridView 的属性,找到列 属性,对其进行编辑,并将二进制列的 ColumnType 更改为 DataGridViewTextBoxColumn。
  2. 进入“事件”窗格并在 CellFormatting 事件上生成一个方法。
  3. 将方法的代码设置为:

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;
    }
}

我在绑定到其中包含字节数据的 table 时遇到了类似的问题,所以我编写了以下创建新文本列的方法,将其添加到 table,复制到byte 列中的数据,同时将其转换为字符串,将新列移动到旧列的位置,并删除旧列

这是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;
    }

}