【问题标题】:How to Convert a Byte Array to String for a DataGridView如何将字节数组转换为 DataGridView 的字符串
【发布时间】:2015-11-13 04:35:46
【问题描述】:

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

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 Columns 就会为每一行显示 [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 中不可用。 任何帮助将不胜感激和欢迎。

【问题讨论】:

    标签: c# winforms datagridview bytearray converter


    【解决方案1】:

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

    【讨论】:

    • 感谢您的及时回答,效果很好。我确实需要将 AutoGenerateColumns 设置为 false 并手动添加列。不过,效果很好。
    【解决方案2】:

    在另一个答案的基础上,我实现这一目标的最简单方法是:

    1. 进入 DataGridView 的属性,找到 Columns 属性,对其进行编辑,然后将二进制列的 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;
        }
    }
    

    【讨论】:

      【解决方案3】:

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

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

      【讨论】:

        猜你喜欢
        • 2022-01-23
        • 2013-05-08
        • 2015-08-13
        • 1970-01-01
        • 1970-01-01
        • 2021-11-11
        相关资源
        最近更新 更多