如何实现WPF DataGrid与一维数组的正确绑定?
正确实现WPF DataGrid与一维数组的绑定
首先得明确你的需求:是把数组的3个元素作为DataGrid的一行三列展示,还是把每个元素作为一行一列展示?这两种场景的实现方式完全不同,我分别给你说明:
场景1:将一维数组作为DataGrid的一行,三列分别对应数组元素
你的原写法问题在于:float[]会被WPF当作一个包含3个独立元素的集合,所以DataGrid会生成3行,每行的三列都显示同一个元素值——这显然不是你想要的。要实现“一行三列”,需要把数组所在的对象作为DataGrid的数据源项,然后每个列绑定到数组的对应索引:
步骤1:确保DataContext正确设置
比如在窗口构造函数里把Cylinder实例设为DataContext:
public MainWindow() { InitializeComponent(); DataContext = new Cylinder(); }
步骤2:修改DataGrid的绑定配置
把ItemsSource绑定到当前DataContext(也就是你的Cylinder实例),然后每个列绑定到数组的对应索引位置:
<Grid x:Name="MyGrid"> <DataGrid ItemsSource="{Binding}" AutoGenerateColumns="False"> <DataGrid.Columns> <DataGridTextColumn Header="X值" Binding="{Binding Vector[0], Mode=TwoWay}"/> <DataGridTextColumn Header="Y值" Binding="{Binding Vector[1], Mode=TwoWay}"/> <DataGridTextColumn Header="Z值" Binding="{Binding Vector[2], Mode=TwoWay}"/> </DataGrid.Columns> </DataGrid> </Grid>
这里ItemsSource="{Binding}"会把当前DataContext识别为单一行数据源,每个列直接绑定数组的对应索引,就能实现你想要的一行三列展示效果。
场景2:将数组的每个元素作为DataGrid的一行,每行显示一个元素
如果你想展示3行,每行对应数组的一个元素,那原写法的列数太多(只需要1列),但还有个关键问题:值类型数组的双向绑定不会自动同步,因为float是值类型,绑定传递的是副本,修改单元格值不会更新原数组。要解决这个问题,需要把数组元素包装成实现INotifyPropertyChanged的引用类型:
步骤1:创建元素包装类
using System.ComponentModel; using System.Runtime.CompilerServices; public class FloatValue : INotifyPropertyChanged { private float _value; public float Value { get => _value; set { if (_value != value) { _value = value; OnPropertyChanged(); } } } public event PropertyChangedEventHandler PropertyChanged; private void OnPropertyChanged([CallerMemberName] string propertyName = null) { PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName)); } }
步骤2:修改Cylinder类使用包装后的数组
using System.ComponentModel; using System.Runtime.CompilerServices; class Cylinder : INotifyPropertyChanged { private FloatValue[] _vector = new FloatValue[] { new FloatValue { Value = 4 }, new FloatValue { Value = 5 }, new FloatValue { Value = 6 } }; public FloatValue[] Vector { get => _vector; set { if (_vector != value) { _vector = value; OnPropertyChanged(); } } } public event PropertyChangedEventHandler PropertyChanged; protected void OnPropertyChanged([CallerMemberName] string propertyName = null) { PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName)); } }
步骤3:修改DataGrid的绑定配置
<Grid x:Name="MyGrid"> <DataGrid ItemsSource="{Binding Vector, Mode=TwoWay}" AutoGenerateColumns="False"> <DataGrid.Columns> <DataGridTextColumn Header="数组元素值" Binding="{Binding Value, Mode=TwoWay}"/> </DataGrid.Columns> </DataGrid> </Grid>
这样修改单元格的值会直接同步回数组,而且因为FloatValue实现了INotifyPropertyChanged,数组元素变化时UI也会自动更新。
内容的提问来源于stack exchange,提问作者Carlos N
相关产品推荐
相关产品推荐

