-1
public partial class MainWindow : Window
    {
        public MainWindow()
        {
            BinaryReader br = new BinaryReader(File.Open(FILE_NAME, FileMode.Open));
            long dataLength = br.BaseStream.Length;
            byte[] a = new byte[br.BaseStream.Length];
            a= br.ReadBytes((int)br.BaseStream.Length);

            InitializeComponent();
        }
....

readData is byte array read from a binary file. How can we make this byte array into a DataGrid of 5 columns using c#?

like this...

position| 0  | 1  | 2  | 3  | 4  |
0       |a[0]|a[1]|a[2]|a[3]|a[4]|
1       |a[5]|a[6]|a[7]|a[8]|a[9]|

...

I tried to create an object with 9 bytes and do it with ListView, but I didn't think this was appropriate for future work...

public class Data
    {
        public int position { get; set; }
        public byte _0 { get; set; }
        public byte _1 { get; set; }
        public byte _2 { get; set; }
        public byte _3 { get; set; }
        public byte _4 { get; set; }
        public byte _5 { get; set; }
        public byte _6 { get; set; }
        public byte _7 { get; set; }
        public byte _8 { get; set; }
        public byte _9 { get; set; }
        public byte _A { get; set; }
        public byte _B { get; set; }
        public byte _C { get; set; }
        public byte _D { get; set; }
        public byte _E { get; set; }
        public byte _F { get; set; }
    }
김지수
  • 5
  • 1
  • 1
    You could write a Binding Converter for the ItemsSource Binding, which converts the byte array to a collection of data items with five properties each. – Clemens Jul 19 '23 at 09:07
  • [possible duplicate](https://stackoverflow.com/questions/276808/how-to-populate-a-wpf-grid-based-on-a-2-dimensional-array). Converting a 1D array to 2D is fairly trivial, just use `y * noColumns + x` to calculate the 1D index. – JonasH Jul 19 '23 at 09:57

1 Answers1

0

If your array is not too big you can use the following LINQ based solution. Otherwise you would have to create a generator (an enumeration stream using yield return).

You should use the asynchronous File API to improve the performance Use File.ReadAllBytesAsync to read the binary file. BinaryReader is not longer required for common scenarios (note that both BinaryReader and FileStream implement IDisposable and that your posted code does not dispose neither of the instances!).

MainWíndow.xaml

<Window>
  <DataGrid x:Name="BytesTable" />
</Window>

MainWindow.xaml.cs

partial class MainWindow : Windwo
{
  public MainWindow()
  {
    InitilaizeComponent();
    this.Loaded += OnLoaded;
  }

  private async void OnLoaded(object sender, RoutedEventArgs e)
  {
    // Define the desired column count.
    // The source array will be partitioned accordingly.
    // An extra column to display the row index is additionally added to the table.
    int columnCount = 5;

    // Asynchronously read the binary file
    byte[] bytes = await File.ReadAllBytesAsync(FILE_NAME);

    // Create the DataGrid data source
    var dataTable = new DataTable();

    // Add the "position" column that maps to the row index
    dataTable.Columns.Add("position", typeof(int));

    // Add the byte value columns
    for (int columnIndex = 0; columnIndex < columnCount; columnIndex++)
    {
      dataTable.Columns.Add(columnIndex.ToString(), typeof(byte));
    }

    // Split the array into groups of n long collections using LINQ.
    // Each group represents a row of n values/cells.
    var groupedValues = bytes
      .Select((item, itemIndex) => (itemIndex, item))
      .GroupBy(itemInfo => Math.Floor(itemInfo.itemIndex / (double)columnCount))
      .Select(group => group.Select(groupvalue => groupvalue.item));

    // Populate the table rows using the grouped collections.
    // Each group represents a row of n values, where n is '5' in your example
    for (int rowIndex = 0; rowIndex < groupedValues.Count(); rowIndex++)
    {
      var rowData = groupedValues.ElementAt(rowIndex);
      DataRow newRow = dataTable.NewRow();
      newRow.ItemArray = new List<byte>{ (byte)rowIndex }
        .Concat(rowData)
        .Cast<object>()
        .ToArray();
      dataTable.Rows.Add(newRow);
    }

    this.BytesTable.ItemsSource = dataTable.DefaultView;
  }
}