C# 如何在网格中显示字节数组?

C# 如何在网格中显示字节数组?,c#,wpf,arrays,C#,Wpf,Arrays,我有一个字节数组,它的大小非常大。我想把它绑定到一个固定大小的网格上,比如说10 所以前10个字节将在第一行,接下来的10个字节将在第二行。。。直到数组结束 我需要能够编辑任何字节,这需要反映到数组中。我的字节数组需要保持一个简单的字节数组 所有这些都是使用WPF C 谢谢你的帮助 编辑: 实际上,AS-CII的解决方案不会将更新的值保存到原始数组中。 我修改了示例以满足以下标准: <DataGrid AutoGenerateColumns="False" Name="dataGrid1"

我有一个字节数组,它的大小非常大。我想把它绑定到一个固定大小的网格上,比如说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>

请注意,唯一的更改是数组[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;         
        }
    }
公共结构阵列
{       
私有T[]m_数据;
私人国际货币单位偏移量;
私有整数mu长度;
公共T此[int索引]{
获取{
返回m_长度>索引?m_数据[m_偏移量+索引]:默认值(T);
}
设置{
如果(m_长度>索引)
m_数据[m_偏移量+索引]=值;
}
}
公共数组类型(T[]数组,整数偏移量,整数长度)
:此()
{
m_数据=数组;
m_Offset=偏移量;
m_长度=长度;
}
}
这是新的阵列

通过这些更改,当UI中的某个值发生更改时,该值将更新为原始数组

这有一个问题:如果最后一个ArrayPice只有8个元素而不是10个元素,那么与直接使用数组时不同,DataGrid中左侧的2个元素将显示0。我尝试实现Length和LongLength属性,但没有成功。如果我把索引抛出边界,它就不会被捕获


谢谢

我想您可以使用一个数组来将行(
ArraySegment
)映射到底层数组。你需要自己做切片,但这应该是一个简单的循环

编辑:

我对WPF的了解还不够好,不知道是否可以绑定到
ArraySegment
的索引。

我想您可以使用的数组将行(
ArraySegment
)映射到基础数组。你需要自己做切片,但这应该是一个简单的循环

编辑:

我对WPF还不太了解,不知道您是否可以绑定到
ArraySegment
的索引。

有没有可能使用固定宽度字体的文本框(如Consolas或Courier New)工作?您可以编写一个从
字节[]
字符串的值转换器,或者如果您使用的是MVVM,则在那里进行翻译。

有没有可能使用固定宽度字体的文本框(如ConsoleAS或Courier New)工作?您可以将值转换器从
byte[]
写入
string
,或者如果您使用的是MVVM,则在那里进行转换。

这是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);
    }
}
public分部类主窗口:窗口,INotifyPropertyChanged
{
公共主窗口()
{
初始化组件();
//设置数据上下文
this.DataContext=this;
//样本阵列生成
字节[]数组=新字节[138];
for(int i=0;iarray.Length?array.Length-offset:10
选择new ArrayPice(数组、偏移量、计数)).ToArray();
}
ArrayPiece[]_字节;
公共arraypece[]字节
{
获取{返回_字节;}
设置{u bytes=value;OnPropertyChanged(“bytes”);}
}
公共事件属性更改事件处理程序属性更改;
受保护的无效OnPropertyChanged(字符串propertyName)
{
if(PropertyChanged!=null)
PropertyChanged(这是新的PropertyChangedEventArgs(propertyName));
}
}
公共结构阵列
{
公共T[]块{get;set;}
公共数组类型(T[]数组,int偏移量,int长度):this()
{
件=新T[长度];
块拷贝(数组、偏移量、片段、0、长度);
}
}
我们使用LINQ将数组拆分为多行,然后使用WPF绑定将数据显示到DataGrid中

编辑:对于阵列的大尺寸,我认为它们不是问题,因为WPF中的DataGrid使用UI虚拟化,因此它只分配显示可见数据所需的内存

这是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);
    }
}
public分部类主窗口:窗口,INotifyPropertyChanged
{
公共主窗口()
{
初始化组件();
//设置数据上下文
this.DataContext=this;
//样本阵列生成
字节[]数组=新字节[138];
for(int i=0;iarray.Length?array.Length-offset:10
选择new ArrayPice(数组、偏移量、计数)).ToArray();
}
ArrayPiece[]_字节;
公共arraypece[]字节
{
获取{返回_字节;}
设置{u字节=值;打开