1

我有两个对象:Bicycleand BicycleFullSuspension,它继承 Bicycle 并包含其他属性(字符串和小数)。我设法使一个功能DataTemplateSelector可以选择我的LbxItemTemplateBicycleDataTemplate 或我的LbxItemTemplateFullSuspensionDataTemplate,具体取决于对象ObservableCollection所属的类。这两个模板都绑定到父模板ListBoxItemTemplate

我正在尝试在 ListBox 中显示有关每个对象的信息,并且每个继承模板都应在父 DataTemplate 中的网格中添加更多字段。我的问题是我无法弄清楚如何从继承的模板之一将 WPF 元素添加到 ListBoxItemTemplate 的网格中。我无法为模板中的网格分配一个键,所以我不确定如何指定额外的 TextBlocks 应该在父模板中的同一个网格中结束。(现在,额外的 TextBlocks 堆叠在父网格的顶部。)

<DataTemplate x:Key="ListBoxItemTemplate">
        <Border Name="LbxItemTemplate" BorderBrush="DarkRed" BorderThickness="2" Padding="5" Margin="5">
        <Grid>
            <Grid.RowDefinitions>
                ...
            </Grid.RowDefinitions>
            <Grid.ColumnDefinitions>
                ...
            </Grid.ColumnDefinitions>
            <TextBlock Grid.Row="1" Grid.Column="0" Text="Bike Year:" />
            <TextBlock Grid.Row="1" Grid.Column="1" Text="{Binding BikeYear}" />
            <TextBlock Grid.Row="2" Grid.Column="0" Text="Bike Color: "/>
            <TextBlock Grid.Row="2" Grid.Column="1" Text="{Binding BikeColor}"/>
            ...
            </Grid>
        </Border>
    </DataTemplate>
   <DataTemplate x:Key="LbxItemTemplateFullSuspension" DataType="{x:Type app:BicycleFullSuspension}">
        <Grid>
        <ContentPresenter Content="{Binding}" ContentTemplate="{StaticResource ListBoxItemTemplate}" />
            <TextBlock Grid.Row="6" Grid.Column="0" Text="Shock Travel"/>
            <TextBlock Grid.Row="6" Grid.Column="1" Text="{Binding ShockTravel}"/>
        </Grid>
    </DataTemplate>

我发现这些链接有助于达到这一点:

http://dariosantarelli.wordpress.com/2011/07/28/wpf-inheritance-and-datatemplates/ http://zamjad.wordpress.com/2009/12/31/applying-data-template-conditionally/

有没有办法在 WPF 中使用数据模板继承?

编辑:

我不知道为什么我不认为将边框放在继承基础的模板上,而是通过在继承模板中的边框内嵌套一个 StackPanel(StackPanel 包含带有基本模板内容的 ContentPresenter 以及 Grid有附加信息),一切都很好:

工作解决方案,使用来自XAMeLi的输入:

<DataTemplate x:Key="ListBoxItemTemplate">
        <Grid>
            <Grid.RowDefinitions>
                <RowDefinition Height="Auto"/>
                <RowDefinition Height="Auto"/>
                ...
            </Grid.RowDefinitions>
            <Grid.ColumnDefinitions>
                <ColumnDefinition Width="150" SharedSizeGroup="LabelColumnGroup" />
                <ColumnDefinition Width="150" SharedSizeGroup="LabelColumnGroup" />
            </Grid.ColumnDefinitions>
            <TextBlock Grid.Row="1" Grid.Column="0" Text="Bike Year:" />
            <TextBlock Grid.Row="1" Grid.Column="1" Text="{Binding BikeYear}" />
            ...
        </Grid>
   </DataTemplate>
   <DataTemplate x:Key="LbxItemTemplateFullSuspension" DataType="{x:Type app:BicycleFullSuspension}" >
        <Border BorderBrush="DarkRed" BorderThickness="2" Padding="5" Margin="5" Grid.IsSharedSizeScope="True" Width="500">
            <StackPanel>
            <ContentPresenter Content="{Binding}" ContentTemplate="{StaticResource ListBoxItemTemplate}" />
            <Grid>
                <Grid.RowDefinitions>
                    <RowDefinition Height="Auto"/>
                    <RowDefinition Height="Auto"/>
                    ...
                </Grid.RowDefinitions>
                <Grid.ColumnDefinitions>
                    <ColumnDefinition Width="Auto" SharedSizeGroup="LabelColumnGroup" />
                    <ColumnDefinition Width="Auto" SharedSizeGroup="LabelColumnGroup" />
                </Grid.ColumnDefinitions>
                ...
                <TextBlock Grid.Row="7" Grid.Column="0" Text="Shock Type: "/>
                <TextBlock Grid.Row="7" Grid.Column="1" Text="{Binding ShockType}"/>
                ...
            </Grid>
            </StackPanel>
        </Border>
    </DataTemplate>
4

1 回答 1

1

您无法将 UIElemets 添加到数据模板,但您可以布局更大的模板,使其看起来像是在基本模板中添加了文本。

基本上,你是在正确的道路上,只有大模板的布局是损坏的。(太糟糕了,你省略了行和列的结构)

试试这个:

<DataTemplate x:Key="ListBoxItemTemplate">
    <Border Name="LbxItemTemplate" BorderBrush="DarkRed" BorderThickness="2" Padding="5" Margin="5">
    <Grid>
        <Grid.RowDefinitions>
            ...
        </Grid.RowDefinitions>
        <Grid.ColumnDefinitions>
            <ColumnDefinition Width="Auto"
                              SharedSizeGroup="LabelGroupColumn"/>
            ...
        </Grid.ColumnDefinitions>
      ....
    </Border>
</DataTemplate>

<DataTemplate x:Key="LbxItemTemplateFullSuspension">
    <Grid Grid.IsSharedSizeScope="True">
        <Grid.RowDefinitions>
            <RowDefinition Height="Auto"/><!--This will hold the default template-->
            <!--From here define the same structure as in the default template, if you have rows for margins and such-->
            <RowDefinition Height="Auto"/>
            <RowDefinition Height="Auto"/>
        </Grid.RowDefinitions>
        <Grid.ColumnDefinitions>
            <ColumnDefinition Width="Auto"
                              SharedSizeGroup="LabelGroupColumn"/>
            <ColumnDefinition Width="*"/>
        </Grid.ColumnDefinitions>
        <ContentPresenter Content="{Binding}" ContentTemplate="{StaticResource ListBoxItemTemplate}" />
        <TextBlock Grid.Row="1" Grid.Column="0" Text="Shock Travel"/>
        <TextBlock Grid.Row="2" Grid.Column="1" Text="{Binding ShockTravel}"/>
    </Grid>
</DataTemplate>

您的网格似乎具有标签值结构,并且您希望所有值都从同一条垂直线开始(从 UX 的角度来看,这非常好)。请注意SharedSizeGroup列定义Grid.IsSharedSizeScope="True"上的设置器和共同父级上的设置器。这将使标签列的宽度在网格之间保持同步。

于 2012-06-08T14:20:20.540 回答