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