5

I need to create a grid. It should be editable
And i should set row and column count.
for example

mygrid.RowCount = 3;
mygrid.ColumnCount = 3;

Here is how it should look like:

enter image description here

How to BIND 2D array to DataGrid?

Sergey
  • 103
  • 1
  • 1
  • 6
  • How to create such grid? – Sergey Feb 12 '11 at 16:50
  • 2
    Sergey, take a look at this post: http://stackoverflow.com/questions/276808/how-to-populate-a-wpf-grid-based-on-a-2-dimensional-array , especially the answer of Meleak (not the accepted answer). I think what he offers does what you are looking for. – Slauma Feb 12 '11 at 19:50

2 Answers2

22

You can use the WPF DataGrid control. It displays a grid of cells that correspond to a collection of objects (rows) containing properties (columns). You need to supply the data storage - a collection of objects. The number of objects in the collection (the collection count) will determine the number of rows in the grid. The DataGrid supports editing the data in the UI.

This example defines three columns and binds them to the A, B, and C properties of the data object.

<DataGrid AutoGenerateColumns="False" 
          Height="200" 
          HorizontalAlignment="Left" 
          Name="dataGrid1" 
          VerticalAlignment="Top" 
          Width="200">
    <DataGrid.Columns >
            <DataGridTextColumn Binding="{Binding Path=A}" MinWidth="50" />
            <DataGridTextColumn Binding="{Binding Path=B}" MinWidth="50" />
            <DataGridTextColumn Binding="{Binding Path=C}" MinWidth="50" />
    </DataGrid.Columns>
</DataGrid>

You will need to assign (in code or using data binding) a collection of objects with these properties to the DataGrid's ItemsSource property, as with any other ItemsControl. Something like this:

public partial class MainWindow: Window
{
        public class DataObject
        {
            public int A { get; set; }
            public int B { get; set; }
            public int C { get; set; }
        }

        public MainWindow()
        {
            InitializeComponent();

            var list = new ObservableCollection<DataObject>();
            list.Add(new DataObject() { A = 6, B = 7, C = 5 });
            list.Add(new DataObject() { A = 5, B = 8, C = 4 });
            list.Add(new DataObject() { A = 4, B = 3, C = 0 });
            this.dataGrid1.ItemsSource = list;
}

And the result looks like this, when editing the center cell:

WPF DataGrid

Side note: the WPF Grid class is only for layout. It does not provide data editing support.

dthorpe
  • 35,318
  • 5
  • 75
  • 119
  • I need a dynamic number of rows and columns. I cant have a 100..000 properties. I have to bind a 2D array to DataGrid – Sergey Feb 12 '11 at 19:13
  • So use a 2D collection: A List>, and bind each column to an element of the array: List> list = new List>(3); list.Add(new List(new int[] { 6, 7, 5 })); (etc) this.dataGrid1.ItemsSource = list; in the xaml, set the columns up like this: then Path=[1] etc. You will still have to write code to add column definitions when you resize your data, but that's not hard. – dthorpe Feb 12 '11 at 19:42
  • On the other hand, if what you really want is an arbitrary 2D cell matrix and you don't want to do the work of managing the data storage and UI upkeep, perhaps you should be using Excel instead? ;> – dthorpe Feb 12 '11 at 19:43
1

Here's the general technique for creating an ItemsControl that uses a Grid to lay out its items. In this example (which uses an XML data source), the ItemsSource is a collection of items with Row, Column, and Data properties.

Note the use of ItemContainerStyle. This is necessary here because in order for the Grid control to use the Grid.Row and Grid.Column attached properties, those properties must be attached to the objects inserted into the grid - if you try to set them on the TextBox that the ItemsTemplate is generating, the grid won't see them, because it's looking at the generated ContentPresenter, not the TextBox inside it.

<Page
  xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
  xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml">
  <Page.Resources>
    <XmlDataProvider x:Key="Data">
      <x:XData>
        <Data xmlns="">
          <Item Row="0" Column="0" Data="0,0"/>
          <Item Row="1" Column="1" Data="1,1"/>
          <Item Row="2" Column="1" Data="2,1"/>
          <Item Row="3" Column="2" Data="3,2"/>
          <Item Row="4" Column="4" Data="4,4"/>
          <Item Row="4" Column="3" Data="4,3"/>
        </Data>
      </x:XData>
    </XmlDataProvider>
  </Page.Resources>
  <DockPanel>
    <ItemsControl ItemsSource="{Binding Source={StaticResource Data}, XPath=/Data/Item}">
      <ItemsControl.ItemsPanel>
        <ItemsPanelTemplate>
          <Grid>  
            <Grid.ColumnDefinitions>
              <ColumnDefinition Width="50"/>
              <ColumnDefinition Width="50"/>
              <ColumnDefinition Width="50"/>
              <ColumnDefinition Width="50"/>
              <ColumnDefinition Width="50"/>
            </Grid.ColumnDefinitions>
            <Grid.RowDefinitions>
              <RowDefinition Height="30"/>    
              <RowDefinition Height="30"/>    
              <RowDefinition Height="30"/>    
              <RowDefinition Height="30"/>    
              <RowDefinition Height="30"/>    
            </Grid.RowDefinitions>
          </Grid>        
        </ItemsPanelTemplate>
      </ItemsControl.ItemsPanel>
      <ItemsControl.ItemContainerStyle>
        <Style TargetType="ContentPresenter">
          <Setter Property="Grid.Row" Value="{Binding XPath=@Row}"/>
          <Setter Property="Grid.Column" Value="{Binding XPath=@Column}"/>
        </Style>
      </ItemsControl.ItemContainerStyle>
      <ItemsControl.ItemTemplate>
        <DataTemplate>
          <TextBox Text="{Binding XPath=@Data, Mode=TwoWay}"/>
        </DataTemplate>
      </ItemsControl.ItemTemplate>
    </ItemsControl>
  </DockPanel>
</Page>
Robert Rossney
  • 94,622
  • 24
  • 146
  • 218
  • I need a dynamic number of rows and columns. – Sergey Feb 12 '11 at 19:11
  • 2
    It is kind of annoying that the built-in `Grid` can't do this. But it's not hard to subclass it to add this functionality - see http://blog.rag.no/post/A-simpler-(and-dynamic)-Grid-control-for-WPF.aspx. – Robert Rossney Feb 12 '11 at 20:01