views:

47

answers:

2

Hi, i've got following problem: i have to display tabular data in some kind of grid.

Say class A is a data item, with properties Foo and Bar, and i have a list of items List or sth like this. i want to display these items in a grid, where items with same Foo are in one column, and items with same Bar in one row. basic. simple. i thought?

My initial attempt was to create an ItemsControl, use a Grid as ItemsPanelTemplate, and an ItemsTemplate where i bound the Grid.Row and Grid.Column attached properties to A.Foo and A.Bar, using IValueConverters to associate a specific Foo with a specific Column, e.g. the converter would look up the Foo value in a kind of Columns array and return the proper index. The thing is, building the row and column defintions for Grid. As they are completely dynamic (i dont know at design time, which Foo's and Bar's will be in the source collection), i cannot define them in the xaml file. But at runtime, ItemsControl really doesnt provide access to the current ItemsPanel instance. The only way i found was a dirty way using VisualTreeHelper.GetChild, and i managed to get the ItemsPanel instance and create the needed Row- and ColumnDefinitions, but my ItemTemplate-d items just wouldn't be rendered in the right row and column, although my Converters returned the right column/row indices. Maybe i don't really understand how ItemsControl works internally, but the thing is, im out of ideas.

Someone suggested using ListView with a GridView, grouping my items of same Bar in another object, this would relieve me of creating the rows dynamicly, but creating the columns dynamicly seems quite complicated.

Does anyone have an idea or at least a hint? Did i miss something obvious?

A: 

Okay, i really should stop working at night, a new day, a clear head and i found the solution pretty quick. Basically it's answered here http://stackoverflow.com/questions/1265364/setting-canvas-properties-in-an-itemscontrol-datatemplate already. I had to use the ItemContainerStyle to set Grid.Row and Grid.Column for my rendered items, or rather the wrapping ContentPresenter.

Cice
A: 

Because you mention the potential of switching to a ListView I thought I would recommend using a DataGrid instead because once you load your data into a DataTable the DataGrid does all the work for you to generate the columns and rows.

Here is some working code I copied to get you started.

Here is the binding for the DataGrid:

<WpfToolkit:DataGrid
            IsReadOnly="True"
            IsTabStop="False"
            ItemsSource="{Binding Path=GridData, Mode=OneWay}">
</WpfToolkit:DataGrid>

Define a property for the XAML binding in a class (I use the MVVM pattern):

private DataTable _dt = new DataTable("MyDataTable");
public DataView GridData
{
   get
   {
      return _dt.DefaultView;
   }
}

Add the DataColumns to your DataTable as follows:

DataColumn fileType = new DataColumn("FileType");
fileType.AllowDBNull = true;
fileType.DataType = typeof(string);
_dt.Columns.Add(fileType);

Add the DataRows to your DataTable as follows:

DataRow dr = _dt.NewRow();
dr["FileType"] = "*.txt";
_dt.Rows.Add(dr);

Reset the rows and coluns as follows:

_dt.Rows.Clear();
_dt.Columns.Clear();

Using these parts is all I needed to dynamically generate a DataGrid.

Zamboni
Note that the DataGrid is part of the WpfToolkit for .Net 3.5, but has migrated the the base .Net Framework for version 4.0.
Alex Paven