Как отобразить массив байтов в сетке? - PullRequest
1 голос
/ 21 октября 2010

У меня есть байтовый массив, который может быть очень большим по размеру.Я хочу привязать его к сетке с фиксированным размером столбца, скажем, 10.

, поэтому первые 10 байтов будут в первой строке, 10 следующих байтов будут во второй строке ...до конца массива.

Мне нужно иметь возможность редактировать любые байты, и это должно быть отражено в массиве.Мой байтовый массив должен оставаться простым байтовым массивом.

Все это с использованием WPF C #.

Спасибо за вашу помощь!

РЕДАКТИРОВАТЬ:

На самом деле, решение AS-CII не сохраняет обновленные значения в исходный массив.Я изменил пример, чтобы он соответствовал этому критерию:

<DataGrid AutoGenerateColumns="False" Name="dataGrid1" ItemsSource="{Binding Bytes}" ColumnWidth="1*">
    <DataGrid.Columns>
        <DataGridTextColumn Header="1" Binding="{Binding [0]}"></DataGridTextColumn>
        <DataGridTextColumn Header="2" Binding="{Binding [1]}"></DataGridTextColumn>
        <DataGridTextColumn Header="3" Binding="{Binding [2]}"></DataGridTextColumn>
        <DataGridTextColumn Header="4" Binding="{Binding [3]}"></DataGridTextColumn>
        <DataGridTextColumn Header="5" Binding="{Binding [4]}"></DataGridTextColumn>
        <DataGridTextColumn Header="6" Binding="{Binding [5]}"></DataGridTextColumn>
        <DataGridTextColumn Header="7" Binding="{Binding [6]}"></DataGridTextColumn>
        <DataGridTextColumn Header="8" Binding="{Binding [7]}"></DataGridTextColumn>
        <DataGridTextColumn Header="9" Binding="{Binding [8]}"></DataGridTextColumn>
        <DataGridTextColumn Header="10" Binding="{Binding [9]}"></DataGridTextColumn>
    </DataGrid.Columns>
</DataGrid>

Обратите внимание, что единственным изменением было Array [0] на [0]

public struct ArrayPiece<T>
    {       
        private T[] m_Data;
        private int m_Offset;
        private int m_Length;

        public T this[int index] { 
            get{                
                return m_Length > index? m_Data[m_Offset + index] : default(T);
            }

            set{
                if(m_Length > index)
                    m_Data[m_Offset + index] = value;
            }
        }

        public ArrayPiece(T[] array, int offset, int length)
            : this()
        {
            m_Data = array;
            m_Offset = offset;
            m_Length = length;         
        }
    }

И это новый ArrayPiece.

С этими изменениями, когда в пользовательском интерфейсе значение изменяется, оно обновляется до исходного массива.

Существует одна проблема с этим: если последний ArrayPiece имеет только 8 элементов вместо 102 левых элемента будут отображать 0 в DataGrid в отличие от использования массива напрямую.Я попытался реализовать свойства Length и LongLength безуспешно.Если я выбрасываю указатель из границы, он не перехватывается.

Спасибо!

Ответы [ 3 ]

1 голос
/ 21 октября 2010

Это часть WPF:

<DataGrid AutoGenerateColumns="False" Name="dataGrid1" ItemsSource="{Binding Bytes}" ColumnWidth="1*">
        <DataGrid.Columns>
            <DataGridTextColumn Header="1" Binding="{Binding Piece[0]}"></DataGridTextColumn>
            <DataGridTextColumn Header="2" Binding="{Binding Piece[1]}"></DataGridTextColumn>
            <DataGridTextColumn Header="3" Binding="{Binding Piece[2]}"></DataGridTextColumn>
            <DataGridTextColumn Header="4" Binding="{Binding Piece[3]}"></DataGridTextColumn>
            <DataGridTextColumn Header="5" Binding="{Binding Piece[4]}"></DataGridTextColumn>
            <DataGridTextColumn Header="6" Binding="{Binding Piece[5]}"></DataGridTextColumn>
            <DataGridTextColumn Header="7" Binding="{Binding Piece[6]}"></DataGridTextColumn>
            <DataGridTextColumn Header="8" Binding="{Binding Piece[7]}"></DataGridTextColumn>
            <DataGridTextColumn Header="9" Binding="{Binding Piece[8]}"></DataGridTextColumn>
            <DataGridTextColumn Header="10" Binding="{Binding Piece[9]}"></DataGridTextColumn>
        </DataGrid.Columns>
    </DataGrid>

И это код:

public partial class MainWindow : Window, INotifyPropertyChanged
{
    public MainWindow()
    {
        InitializeComponent();

        // Set the datacontext
        this.DataContext = this;

        // Sample array generation
        byte[] array = new byte[138];

        for (int i = 0; i < array.Length; i++)
        {
            array[i] = (byte)i;
        }

        int length = (int)Math.Ceiling(array.Length / 10m);

        Bytes = (from i in Enumerable.Range(0, length)
                let offset = i * 10
                let count = offset + 10 > array.Length ? array.Length - offset : 10
                select new ArrayPiece<byte>(array, offset, count)).ToArray();
    }

    ArrayPiece<byte>[] _bytes;

    public ArrayPiece<byte>[] Bytes
    {
        get { return _bytes; }
        set { _bytes = value; OnPropertyChanged("Bytes"); }
    }

    public event PropertyChangedEventHandler PropertyChanged;
    protected void OnPropertyChanged(string propertyName)
    {
        if (PropertyChanged != null)
            PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
    }
}

public struct ArrayPiece<T>
{
    public T[] Piece { get; set; }

    public ArrayPiece(T[] array, int offset, int length) : this()
    {
        Piece = new T[length];
        Buffer.BlockCopy(array, offset, Piece, 0, length);
    }
}

Мы используем LINQ для разделения массива на несколько строк, а затем с привязкой WPFмы показываем данные в DataGrid.

РЕДАКТИРОВАТЬ: Для больших размеров массива я не думаю, что они являются проблемой, потому что DataGrid в WPF использует виртуализацию пользовательского интерфейса, и поэтомуон просто выделяет память, необходимую для отображения видимых данных.

0 голосов
/ 21 октября 2010

Есть ли шанс, что текстовое поле с шрифтом фиксированной ширины (например, Consolas или Courier New) будет работать?Вы можете написать конвертер значений из byte[] в string или, если вы используете MVVM, выполнить там перевод.

0 голосов
/ 21 октября 2010

Полагаю, вы можете использовать массив ArraySegment для сопоставления ваших строк (ArraySegment) с базовым массивом.Вы должны сделать нарезку на сегменты самостоятельно, но это должен быть простой цикл.

Редактировать:
Я не знаю достаточно WPF, чтобы знать, если выможет связываться с индексами ArraySegment или нет.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...