【问题标题】:Bind WPF DataGrid to one-dimensional array将 WPF DataGrid 绑定到一维数组
【发布时间】:2018-04-12 21:16:40
【问题描述】:

我有一个简单的一维数组:

class Cylinder {
    private float[] vector = new float[3] {4,5,6};
    public float[] Vector = { get; set; }
}

在我的 XAML 中,我创建了一个带有一些简单绑定的 DataGrid

<Grid x:Name="MyGrid>
    <DataGrid ItemsSource="{Binding Vector, Mode=TwoWay}">
        <DataGrid.Columns>
            <DataGridTextColumn Binding="{Binding Path=.}"/>
            <DataGridTextColumn Binding="{Binding Path=.}"/>
            <DataGridTextColumn Binding="{Binding Path=.}"/>
        </DataGrid.Columns>
    </DataGrid>
<Grid>

然后我将MyGridDataContext 设置为Cylinder 类的一个实例。窗口显示DataGrid 控件,但我有两个问题:

  1. DataGrid 填充了正确的数据,但方式很奇怪。我得到一个 3x3 网格,第一行全是“4”,第二行全是“5”,第三行全是“6”。
  2. 当我尝试编辑 9 个单元格中的任何一个时,出现异常:

双向绑定需要 Path 或 XPath

我想我可以只制作三个单独的TextBox 控件,但我认为这样会更优雅。

【问题讨论】:

  • 3 列绑定是相同的,那么您为什么希望它们显示不同的信息呢?啊...您是否期​​望在一行中看到 4 5 6?不,集合中的每个项目代表一行。
  • 至于第二点“当我尝试编辑任何 (9!) 个单元格时,我得到一个异常“双向绑定需要 Path 或 XPath”。”,没有明确的设置器为向量场中的值定义。
  • 我明白了@Richardissimo 关于相同列绑定的说明,我意识到这行不通,但想不出更好的实现。
  • 是的,我希望将 4 5 和 6 显示为单行。如果集合中的每个项目代表一行,那么似乎我需要一个 3 项目数组的集合?而我的收藏恰好有 1 个项目(因此只有一行)?我可以实际使用 3 项数组,还是需要创建具有实际字段的对象或结构,并将对象/结构放入集合中?
  • 你可以在 WPF 中做你喜欢做的事......你只需要在问题中提出这个问题。您可以使用 ItemsControl,并将 PanelTemplate 定义为水平 StackPanel,然后在 ItemTemplate 中放置一个 TextBox。这将适用于您现有的数据结构。

标签: c# arrays wpf binding datagrid


【解决方案1】:

您有一个一维数组,那么您希望它如何绑定到 3 列?想想看,DataGrid 就像一个二维数组的显示,列是 x 轴,行是 y 轴。所以你的一维数组必须在一列的行中。

编辑要表示您在 cmets 中提到的更复杂的类型,如果您将 DataGrid 直接绑定到数据(仅适用于非常简单的项目)或更好,则可以使用 DataTable List&lt;&gt; 如果您绑定到业务对象。这是一个例子:

将您的类更改为具有您想要的三个属性(给它们起比本示例更有意义的名称):

public class Cylinder {
    public float Vector1 = { get; set; };
    public float Vector2 = { get; set; };
    public float Vector3 = { get; set; };
}

现在您可以将DataGrid 直接绑定到此类进行测试,但在数据来自数据库等来源的实际应用程序中,您可以创建此类的列表:

var cylinders = new List<Cylinder>();

然后用来自数据库的数据填充它:

foreach(var row in myTable) {
    var c = new Cylinder();
    c.Vector1 = 4;
    c.Vector2 = 5;
    c.Vector3 = 6;
    cylinders.Add(c);
}

现在您可以将DataGrid 绑定到cylinders。网格将包含代表Cylinder 类的三个属性的三列,以及与myTable 中一样多的行。

【讨论】:

  • 一维数组只是二维数组的子集,对吧?应该可以显示 X 字段的 Y 记录的数据集,其中每行是记录,每列是字段。然后我可以说,对于我的特定数据集,有 Y=1 和 X=3,所以只有一行有 3 个字段。
  • 是和不是。如果你愿意,你可以认为一维数组只是二维数组的一个子集,但是它将是 Y=3 和 X=1,而不是相反。 DataGrid 中的列是数组的维度,行是每个维度中的项目。如果您想以另一种方式进行操作,则必须自己编写代码,因为DataGrid 不是为此而设计的。如果项目的数量是固定的并且永远不会改变,那么这很容易,但这种情况很少见。
  • 我明白你所说的行与列。我认为在我的情况下我很好,因为这 3 个项目与单个记录密切相关(如果你愿意,可以是字段)。我可以有多个记录,但在这个应用程序中,我只有一个。所以我认为我遵循DataGrid 的意图,其中每一行都是记录,列是字段。基于此,我认为我的错误是在数组中捕获。似乎在一个结构中捕获可能更有意义,然后将其包含在绑定到控件的集合中。
  • 是的,现在你做对了。如果您将DataGrid 绑定到具有一条记录和三列的DataTable,您将得到您想要的。如果您获得更多记录,它将继续工作,DataGrid 将成功显示更多行。是的,数组就像一张表,有一列和多条记录。要表示更复杂的类型,请使用List&lt;&gt;。请参阅我的更新答案。
  • 知道了。数组已经隐含地是一个集合。我认为这解决了我的问题。我听说过有关是否必须将 DataGrid 绑定到您显示的 List 或 ObservableCollection 的相互矛盾的信息。两者似乎没有关系(继承或兄弟姐妹)。两者都有好处吗?
猜你喜欢
  • 2012-02-22
  • 2013-05-24
  • 2018-08-17
  • 1970-01-01
  • 1970-01-01
  • 2013-07-28
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多