R – Silverlight add datagrid column with usercontrol using xamlreader

datagridsilverlight

I try to add a column to my datagrid using the follwing code, but I'll get an browser crash (can't see a exception). I've added a sample project here: http://cid-5d0909fd6cd506a0.skydrive.live.com/self.aspx/Offentlig/DependencyPropblem.zip

The code is as follow:

 private void LoadDynamicDataColumnTemplate()
    {

        string xaml;
        if (false)
        {
            // THis one does not work. Whats wrong?????????
            xaml = @"<DataTemplate xmlns=""http://schemas.microsoft.com/client/2007"" 
                               xmlns:me=""clr-namespace:SilverlightApplication2"">
                                              <me:MyUserControl Age=""{Binding Path=Age}""/>
                                        </DataTemplate>";
        }
        else
        {
            // This runs fine!
            xaml = @"<DataTemplate xmlns=""http://schemas.microsoft.com/client/2007"" 
                               xmlns:me=""clr-namespace:SilverlightApplication2"">
                                  <Button Content=""{Binding Path=Age}""/>
                            </DataTemplate>";
        }

        DataGridTemplateColumn tc = new DataGridTemplateColumn();
        tc.CellTemplate = (DataTemplate)XamlReader.Load(xaml);
        tc.Header = "Dynamic";
        MyDataGrid.Columns.Add(tc);
    }

My datagrid is defined like this:

        <data:DataGrid x:Name="MyDataGrid" ItemsSource="{Binding Path=Rows}" AutoGenerateColumns="False">
        <data:DataGrid.Columns>
            <data:DataGridTextColumn Binding="{Binding Path=Name}" Header="Name"></data:DataGridTextColumn>
            <data:DataGridTemplateColumn Header="Static">
                <data:DataGridTemplateColumn.CellTemplate>
                    <DataTemplate>
                        <me:MyUserControl Age="{Binding Path=Age}"/>
                    </DataTemplate>
                </data:DataGridTemplateColumn.CellTemplate>
            </data:DataGridTemplateColumn>
        </data:DataGrid.Columns>
    </data:DataGrid>

And my usercontrol like this:

<UserControl x:Class="SilverlightApplication2.MyUserControl"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" 
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" 
>
<Grid x:Name="LayoutRoot" Background="Red">
    <Button Content="{Binding Age}" Click="Button_Click"/>
</Grid>

Any helps would be great!

I'was using running with SL 3 beta, but after uninstalling it, and reinnstalling the tools I managed to get an exception:

Sys.InvalidOperationException: ManagedRuntimeError error #4004 in control 'Xaml1': System.Windows.Markup.XamlParseException: System.Windows.Markup.XamlParseException: System.Windows.Markup.XamlParseException: System.Windows.Markup.XamlParseException: System.Windows.Markup.XamlParseException: System.Windows.Markup.XamlParseException: System.Windows.Markup.XamlParseException: System.Windows.Markup.XamlParseException: System.Windows.Markup.XamlParseException: System.Windows.Markup.XamlParseException: System.Windows.Markup.XamlParseException: AG_E_UNKNOWN_ERROR [Line: 1 Position: 162]
at MS.Internal.XcpImports.MethodEx(IntPtr ptr, String name, CValue[] cvData)
at MS.Internal.XcpImports.MethodEx(DependencyObject obj, String name)
at MS.Internal.XcpImports.DataTemplate_LoadContent(DataTemplate template)
at System.Windows.DataTemplate.LoadContent()
at System.Windows.Controls.DataGrid.PopulateCellContent(Boolean forceTemplating, 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)
at System.Windows.Controls.DataGrid.GetEdgedExactRowHeight(Int32 rowIndex)
at System.Windows.Controls.DataGrid.UpdateDisplayedRows(Int32 newFirstDisplayedRowIndex, Double displayHeight)
at System.Windows.Controls.DataGrid.ComputeScrollBarsLayout()
at System.Windows.Controls.DataGrid.MeasureOverride(Size availableSize)
at System.Windows.FrameworkElement.MeasureOverride(IntPtr nativeTarget, Single inWidth, Single inHeight, Single& outWidth, Single& outHeight) [Line: 0 Position: 0]
at MS.Internal.XcpImports.MethodEx(IntPtr ptr, String name, CValue[] cvData)
at MS.Internal.XcpImports.MethodEx(DependencyObject obj, String name)
at MS.Internal.XcpImports.DataTemplate_LoadContent(DataTemplate template)

But still no running code. Now I'm using the 2.0.40115.0, and VSTS 2008 Dev ed.

Any ideas?

Regards Larsi

Best Answer

I tried your sample, and it works fine on my machine when changing " if (false)" to " if (true)"

What version of SL, VS etc are you using?

OK, here's your problem: In the string that defines the "dynamic" template, you indicate

xmlns:me=""clr-namespace:SilverlightApplication2""

In the context of the XamlLoader, you need to indicate the actual assembly, because this is not being compiled (I believe this is a shortcut that is replaced at compile time when used in a xaml file).

In any case, and whatever the underlying reason, you need to indicate:

xmlns:me=""clr-namespace:SilverlightApplication2;assembly=SilverlightApplication2""

this gives you

xaml = @"<DataTemplate xmlns=""http://schemas.microsoft.com/client/2007"" 
              xmlns:me=""clr-namespace:SilverlightApplication2;assembly=SilverlightApplication2"">
              <me:MyUserControl Age=""{Binding Path=Age}""/>
         </DataTemplate>";

This code actually works on my machine with SL 3.0.

Related Topic