2
votes

Background

If we have a CLR object such as:

class Person
{
   public string FirstName {get; set;}
   public string LastName {get; set;}
}

We can create an ObservableCollection, add a little boiler plate code and voila we can bind this to a DataGrid with XAML like:

<DataGrid ItemsSource="{Binding PropertyOnPersonObject}"\>

And the DataGrid knows to take this object and populate each column automatically.

What happened

Within a viewmodel, I wanted to create a single column DataGrid with an ObservableCollection<decimal>. So I made a public property and bound just like above. What kept happening was I'd get the correct number of rows but no data. Just using ItemsSource wasn't enough.

I finally figured out I needed this:

<DataGrid ItemsSource="{Binding PropertyOnSomething}"> 
            <DataGrid.Columns>
                <DataGridTextColumn Binding="{Binding}"/>
            </DataGrid.Columns>
        </DataGrid>

The DataGrid needed this extra binding code at the column level. Why?

1
Thats odd behavior. Just a note, you will usually turn AutoColumns off anyways, since the headers aren't very pretty.BradleyDotNET
How DataGridTextColumn will know that which property value I suppose to show??? That is why in every Column you must have to provide its binding property. In your case of "<DataGridTextColumn Binding="{Binding}"/>",you binded DataGrid's DataContext property to DataGridTextColumn.Amol Bavannavar
@Phenix_yu AutoGenerateColumns is set to True by default but to answer your question I explicitly set it and got same result. I also got same result with it set to False. Yes PropertyOnSomething is binded to a property of viewmodel.rsgmon

1 Answers

2
votes

DataGrid.AutoGenerateColumns property is responsible for generating the columns for you in the Datagrid automatically.

DataGrid has AutoGenerateColumns set to true by default. If you had used a ObservableCollection<Person> it will go through the list of properties of your Person class and generate the items properties - ReadOnlyCollection<ItemPropertyInfo> itemProperties. Based on this list it will bind the header and the cells internally.

But in the second case you had used ObservableCollection<decimal> which is not an object type but a value type. It does not have any property defined its definition and hence it will not yield any itemProperties list. As a result you there wont be any binding done internally and the datagrid will be just empty rows.