如何在有和没有绑定的情况下混合使用Silverlight DataGrid列?

时间:2011-10-06 08:52:18

标签: silverlight silverlight-4.0 datagrid

在Silverlight 4中,我有一个绑定到RIA DomainDataSource的DataGrid,所有这些都在XAML中完成。 AutoGenerateColumns属性设置为false,并且每列都是手动定义和绑定的。基本上这很好用。

我现在遇到的问题是还有一个没有绑定的DataGridTextColumn。我想在后面的代码中手动填充此列中的单元格。当没有Binding的此列时,会在运行时弹出以下异常:

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)

如何避免此异常并让我的DataGrid绑定大多数列并且一列未绑定?

提前致谢。

修改

我的XAML如下所示:

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

编辑#2:

我在网上发现的一个想法是将最后一列绑定到某个唯一值(我的数据模型中有一个ID)并使用自定义IValueConverter将ID转换为依赖值。这本来就是我想要的,但不幸的是我从WCF服务调用获得了依赖值,它始终是异步的。由于您无法在IValueConverter中使用异步方法调用,因此此解决方案不适用于我。

1 个答案:

答案 0 :(得分:1)

您是否考虑过使用DataGridTemplateColumn?如果为此类型的列设置绑定,则无关紧要。

例如,如果您只想在加载时设置一次未绑定值,则可以执行以下操作:

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

...然后在代码中设置值,如下所示:

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

我不确定您的具体要求是什么。