简体   繁体   中英

Bind WPF DataGrid to one-dimensional array

I have a simple one-dimensional array:

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

In my XAML, I have created a DataGrid with some simple binding:

<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>

I then set the DataContext of MyGrid to an instance of the Cylinder class. The window displays with the DataGrid control, but I have 2 problems:

  1. The DataGrid is populated with the right data, but in a strange way. I get a 3x3 grid with the first row all '4's, the second row all '5's, and the third row all '6's.
  2. When I try to edit any of the 9 cells, I get an exception:

Two-way binding requires Path or XPath

I suppose I could just make three separate TextBox controls, but I thought this would be more elegant.

You have a one-dimensional array, so how are you expecting it to bind to 3 columns? Think about it, the DataGrid is like a display for a two-dimensional array, the columns are the x axis, and the rows are the y axis. So your one-dimensional array must go in the rows of one column.

EDIT To represent a more complex type as you mentioned in your comments, you can use DataTable if you bind the DataGrid directly to the data (only for very simple projets) or better List<> if you bind to business objects. Here is an example:

Change your class to have the three properties that you want (give them more meaningful name than this example):

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

Now you can bind your DataGrid directly to this class for testing, but in a real application where data is coming from some source like a database, you create a list of this class:

var cylinders = new List<Cylinder>();

And then populate it with the data coming from the database:

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

And now you can bind your DataGrid to cylinders . The grid will have three columns representing the three properties of the Cylinder class, and as many rows as you have in myTable .

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM