2
votes

In Silverlight 4 I have a DataGrid which is bound to a RIA DomainDataSource, all done in XAML. The AutoGenerateColumns property is set to false and each column is manually defined and bound. Basically this works fine.

Where I now run into problems is having an additional DataGridTextColumn which has no Binding. I want to manually populate the cells in this column in the code behind. When having this column without the Binding, at runtime the following exception pops up:

System.ArgumentNullException: Value cannot be null.
Parameter name: binding
   at System.Windows.Data.BindingOperations.SetBinding(DependencyObject target, DependencyProperty dp, BindingBase binding)
   at System.Windows.Controls.DataGridTextColumn.GenerateElement(DataGridCell cell, Object dataItem)
   at System.Windows.Controls.DataGrid.PopulateCellContent(Boolean isCellEdited, DataGridColumn dataGridColumn, DataGridRow dataGridRow, DataGridCell dataGridCell)
   at System.Windows.Controls.DataGrid.AddNewCellPrivate(DataGridRow row, DataGridColumn column)
   at System.Windows.Controls.DataGrid.CompleteCellsCollection(DataGridRow dataGridRow)
   at System.Windows.Controls.DataGrid.GenerateRow(Int32 rowIndex, Int32 slot, Object dataContext)
   at System.Windows.Controls.DataGrid.AddSlots(Int32 totalSlots)
   at System.Windows.Controls.DataGrid.RefreshRows(Boolean recycleRows, Boolean clearRows)
   at System.Windows.Controls.DataGrid.RefreshRowsAndColumns(Boolean clearRows)
   at System.Windows.Controls.DataGrid.InitializeElements(Boolean recycleRows)
   at System.Windows.Controls.DataGridDataConnection.NotifyingDataSource_CollectionChanged(Object sender, NotifyCollectionChangedEventArgs e)
   at System.Windows.Controls.DomainDataSourceView.OnCollectionChanged(NotifyCollectionChangedEventArgs e)
   at System.Windows.Controls.DomainDataSourceView.OnCollectionViewCollectionChanged(Object sender, NotifyCollectionChangedEventArgs e)
   at System.Windows.Controls.EntityCollectionView.OnCollectionChanged(NotifyCollectionChangedEventArgs args)
   at System.Windows.Controls.PagedEntityCollectionView.OnCollectionChanged(NotifyCollectionChangedEventArgs args)
   at System.Windows.Controls.PagedEntityCollectionView.RefreshView()
   at System.Windows.Controls.PagedEntityCollectionView.SourceCollectionChanged(NotifyCollectionChangedEventArgs args)
   at System.Windows.Controls.EntityCollectionView.HandleSourceCollectionChanged(Object sender, NotifyCollectionChangedEventArgs e)
   at System.Windows.Controls.PagedEntityCollection.RaiseCollectionChanged(NotifyCollectionChangedAction action, Entity entity, Int32 index)
   at System.Windows.Controls.PagedEntityCollection.CompleteLoad()
   at System.Windows.Controls.DomainDataSource.ProcessLoadedEntities(LoadContext loadContext, IEnumerable`1 entities)
   at System.Windows.Controls.DomainDataSource.DomainContext_Loaded(LoadedDataEventArgs e, LoadContext loadContext)

How can I avoid this exception and have my DataGrid with most columns bound and one column unbound?

Thanks in advance.

Edit:

My XAML looks as follows:

    <sdk:DataGrid AutoGenerateColumns="False"
        ItemsSource="{Binding Data, ElementName=MyDomainDataSource, Mode=OneWay}">
        <sdk:DataGrid.Columns>
            <sdk:DataGridTextColumn Binding="{Binding Name}" Header="Name" />
            <sdk:DataGridTextColumn Binding="{Binding CreationDate}" Header="Creation Date" />
            <sdk:DataGridTextColumn Header="Unbound Col" />
        </sdk:DataGrid.Columns>
    </sdk:DataGrid>

Edit #2:

One idea I found on the web was to bind the last column to some unique value (I have an ID in my data model) and use a custom IValueConverter which converts the ID to a dependent value. This would have been exactly what I wanted, but unfortunately I get the dependent value from a WCF service call, which is always asynchronous. As you cannot use async method calls in an IValueConverter this solution is not an option for me.

1
Can you show your associate Xaml?Gone Coding
I added the XAML code for my DataGrid in my question.Tobias

1 Answers

1
votes

Have you considered using a DataGridTemplateColumn instead? It does not matter if you set the binding or not for this type of column.

For example, if you just want to set the unbound value once at the time of loading you could do something like this:

                    <sdk:DataGridTemplateColumn>
                        <sdk:DataGridTemplateColumn.CellTemplate>
                            <DataTemplate>
                                <TextBox x:Name="MyText" Loaded="MyText_Loaded"></TextBox>
                            </DataTemplate>
                        </sdk:DataGridTemplateColumn.CellTemplate>
                    </sdk:DataGridTemplateColumn>

...and then set the value in the code behind like this:

    private void MyText_Loaded(object sender, RoutedEventArgs e)
    {
        var textBox = sender as TextBox;
        if (textBox != null) textBox.Text = "My one off text"; 
    }

I'm not sure what your exact requirements are.