XAML强制autogeneratingcolumn使用自定义datatemplate

时间:2015-04-28 10:22:25

标签: c# wpf xaml templates datagrid

背景:使用大量数据处理项目,创建分析工具。

问题:DataGridTemplateColumn不支持Binding。我需要使用相同的模板创建大量的datagrid,但具有不同的绑定。

         mc:Ignorable="d" 
         >
<UserControl.Resources>
    <ObjectDataProvider x:Key="designData" 
                        ObjectType="{x:Type data:designData}"
                        MethodName="getVenstreOversiktSkuff"/>
    <CollectionViewSource x:Key="cv" Source="{StaticResource designData}"/>


    <UserControl x:Key="ucContentForDataContext">
        <StackPanel Margin="5">
            <TextBlock Text="Kassett"/>
            <TextBlock Text="{Binding KassettNr}" />
            <TextBlock Text="{Binding Varenr}" />
            <TextBlock Text="{Binding Varenavn}" />
        </StackPanel>
    </UserControl>
    <DataTemplate x:Key="DataTemplate01">
        <ContentControl Content="{StaticResource ucContentForDataContext}" DataContext="{Binding Plass01}"/>
    </DataTemplate>
    <DataTemplate x:Key="DataTemplate02">
        <ContentControl Content="{StaticResource ucContentForDataContext}" DataContext="{Binding Plass02}"/>
    </DataTemplate>
    <DataTemplate x:Key="DataTemplate03">
        <ContentControl Content="{StaticResource ucContentForDataContext}" DataContext="{Binding Plass03}"/>
    </DataTemplate>
    <DataTemplate x:Key="DataTemplate04">
        <ContentControl Content="{StaticResource ucContentForDataContext}" DataContext="{Binding Plass04}"/>
    </DataTemplate>
    <DataTemplate x:Key="DataTemplate05">
        <ContentControl Content="{StaticResource ucContentForDataContext}" DataContext="{Binding Plass05}"/>
    </DataTemplate>
    <DataTemplate x:Key="DataTemplate06">
        <ContentControl Content="{StaticResource ucContentForDataContext}" DataContext="{Binding Plass06}"/>
    </DataTemplate>
    <DataTemplate x:Key="DataTemplate07">
        <ContentControl Content="{StaticResource ucContentForDataContext}" DataContext="{Binding Plass07}"/>
    </DataTemplate>
    <DataTemplate x:Key="DataTemplate08">
        <ContentControl Content="{StaticResource ucContentForDataContext}" DataContext="{Binding Plass08}"/>
    </DataTemplate>
    <DataTemplate x:Key="DataTemplate09">
        <ContentControl Content="{StaticResource ucContentForDataContext}" DataContext="{Binding Plass09}"/>
    </DataTemplate>
    <DataTemplate x:Key="DataTemplate10" >
        <ContentControl Content="{StaticResource ucContentForDataContext}" DataContext="{Binding Plass10}"/>
    </DataTemplate>
    <DataTemplate x:Key="DataTemplate11">
        <ContentControl Content="{StaticResource ucContentForDataContext}" DataContext="{Binding Plass11}"/>
    </DataTemplate>

</UserControl.Resources>
<DataGrid x:Name="dg" ItemsSource="{Binding Source={StaticResource cv}}" AutoGenerateColumns="False"  >
    <DataGrid.Columns>

        <DataGridTemplateColumn CellTemplate="{DynamicResource DataTemplate01}" />
        <DataGridTemplateColumn CellTemplate="{DynamicResource DataTemplate02}" />
        <DataGridTemplateColumn CellTemplate="{DynamicResource DataTemplate03}" />
        <DataGridTemplateColumn CellTemplate="{DynamicResource DataTemplate04}" />
        <DataGridTemplateColumn CellTemplate="{DynamicResource DataTemplate05}" />
        <DataGridTemplateColumn CellTemplate="{DynamicResource DataTemplate06}" />
        <DataGridTemplateColumn CellTemplate="{DynamicResource DataTemplate07}" />
        <DataGridTemplateColumn CellTemplate="{DynamicResource DataTemplate08}" />
        <DataGridTemplateColumn CellTemplate="{DynamicResource DataTemplate09}" />
        <DataGridTemplateColumn CellTemplate="{DynamicResource DataTemplate10}" />
        <DataGridTemplateColumn CellTemplate="{DynamicResource DataTemplate11}" />
    </DataGrid.Columns>
</DataGrid>

Visual Studio: !(http://i.imgur.com/GXPqNki.png

正在运行App: !(http://i.imgur.com/S366s2Y.png

为什么在Visual Studio中的DesignMode中显示数据窗口,但是当我使用完全相同的数据源启动应用程序时却不会。

1 个答案:

答案 0 :(得分:0)

重点是DataGridTemplateColumn 不属于可视树。因此,StaticResource标记无法检索您在UserControl资源字典中声明的资源,因为DataGridTemplateColumn和UserControl之间没有“连接”。

您可以考虑使用代码创建DataTemplate。 看看这里。

<强>的Xaml

<UserControl x:Class="WpfApplication1.UserControl1"
             xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
             xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
             xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" 
             xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
             xmlns:data="clr-namespace:WpfApplication1"
             mc:Ignorable="d" 
             d:DesignHeight="300" d:DesignWidth="300">
    <UserControl.Resources>
        <ObjectDataProvider x:Key="designData" 
                        ObjectType="{x:Type data:DesignData}"
                        MethodName="GetVenstreOversiktSkuff"/>
        <CollectionViewSource x:Key="cv" Source="{StaticResource designData}"/>

    </UserControl.Resources>

    <DataGrid x:Name="dg2" ItemsSource="{Binding Source={StaticResource cv}}" AutoGenerateColumns="true"
              AutoGeneratingColumn="dg2_AutoGeneratingColumn" />
</UserControl>

<强>代码隐藏

private void dg2_AutoGeneratingColumn(object sender, DataGridAutoGeneratingColumnEventArgs e)
{
    DataGridTemplateColumn dataGridTemplateColumn = new DataGridTemplateColumn();

    FrameworkElementFactory fefTextBlock1
        = new FrameworkElementFactory(typeof(TextBlock));
    fefTextBlock1.SetValue(TextBlock.TextProperty, "Kassett");

    FrameworkElementFactory fefTextBlock2
        = new FrameworkElementFactory(typeof(TextBlock));
    fefTextBlock2.SetBinding(TextBlock.TextProperty, new Binding("KassettNr"));

    FrameworkElementFactory fefTextBlock3
        = new FrameworkElementFactory(typeof(TextBlock));
    fefTextBlock3.SetBinding(TextBlock.TextProperty, new Binding("Varenr"));

    FrameworkElementFactory fefTextBlock4
        = new FrameworkElementFactory(typeof(TextBlock));
    fefTextBlock4.SetBinding(TextBlock.TextProperty, new Binding("Varenavn"));

    FrameworkElementFactory fefStackPanel
        = new FrameworkElementFactory(typeof(StackPanel), "stackPanel");

    fefStackPanel.SetBinding(FrameworkElement.DataContextProperty,
        new Binding(e.PropertyName));
    fefStackPanel.SetValue(FrameworkElement.MarginProperty, new Thickness(5));
    fefStackPanel.AppendChild(fefTextBlock1);
    fefStackPanel.AppendChild(fefTextBlock2);
    fefStackPanel.AppendChild(fefTextBlock3);
    fefStackPanel.AppendChild(fefTextBlock4);

    dataGridTemplateColumn.CellTemplate = new DataTemplate();
    dataGridTemplateColumn.CellTemplate.VisualTree = fefStackPanel;
    dataGridTemplateColumn.CellTemplate.Seal();

    e.Column = dataGridTemplateColumn;
}

我希望它可以帮到你。