为ListBox中的每个项加载不同的DataTemplate

时间:2014-01-14 10:57:28

标签: c# wpf xaml listbox

我正在尝试创建一个学习应用程序,我想基于问题类型加载数据模板 如下所述。

     If Question Type is TYPE1

     load InstructionTemplate_Type1.xaml
     load ChoiceTemplate_Type1.xaml
     load QuestionTemplate_Type1.xaml

     If Question Type is TYPE2

     load InstructionTemplate_Type2.xaml
     load ChoiceTemplate_Type2.xaml
     load QuestionTemplate_Type2.xaml

     If Question Type is TYPE3

     load InstructionTemplate_Type3.xaml
     load ChoiceTemplate_Type3.xaml
     load QuestionTemplate_Type3.xaml

     else

     load InstructionTemplate_Type3.xaml
     load ChoiceTemplate_Type3.xaml
     load QuestionTemplate_Type3.xaml

我的页面看起来应该......

learn page

有人可以帮我解决这个问题。

我正在使用上一篇文章中的代码

Nested ObservableCollection data binding in WPF

和xaml是......

    

    <learn:SelectedItemIsCorrectToBooleanConverter x:Key="SelectedCheckedToBoolean" />

    <Style x:Key="ChoiceRadioButtonStyle" TargetType="{x:Type RadioButton}" BasedOn="{StaticResource {x:Type RadioButton}}">
        <Style.Triggers>
            <DataTrigger Value="True">
                <DataTrigger.Binding>
                    <MultiBinding Converter="{StaticResource SelectedCheckedToBoolean}">
                        <Binding Path="IsCorrect" />
                        <Binding RelativeSource="{RelativeSource Self}" Path="IsChecked" />
                    </MultiBinding>
                </DataTrigger.Binding>
                <Setter Property="Background" Value="Green"></Setter>
            </DataTrigger>
            <DataTrigger Value="False">
                <DataTrigger.Binding>
                    <MultiBinding Converter="{StaticResource SelectedCheckedToBoolean}">
                        <Binding Path="IsCorrect" />
                        <Binding RelativeSource="{RelativeSource Self}" Path="IsChecked" />
                    </MultiBinding>
                </DataTrigger.Binding>
                <Setter Property="Background" Value="Red"></Setter>
            </DataTrigger>
        </Style.Triggers>
    </Style>

    <DataTemplate x:Key="InstructionTemplate" DataType="{x:Type learn:Question}">
        <TextBlock Text="{Binding Path=Instruction}" />
    </DataTemplate>

     <DataTemplate x:Key="ChoiceTemplate" DataType="{x:Type learn:Choice}">
                        <RadioButton Content="{Binding Path=Name}" IsChecked="{Binding RelativeSource=   {RelativeSource Mode=FindAncestor, AncestorType={x:Type ListBoxItem}}, Path=IsSelected}" Margin="10 1" 
                                     Style="{StaticResource ChoiceRadioButtonStyle}" />
                    </DataTemplate>

    <DataTemplate x:Key="QuestionTemplate" DataType="{x:Type learn:Question}">
        <StackPanel Margin="10 0">
            <TextBlock Text="{Binding Path=Name}" />
            <ListBox ItemsSource="{Binding Path=Choices}" SelectedItem="{Binding Path=SelectedChoice}" HorizontalAlignment="Stretch" ItemTemplate="ChoiceTemplate">

            </ListBox>
        </StackPanel>
    </DataTemplate>
</Window.Resources>

<DockPanel>
    <StackPanel Orientation="Horizontal" DockPanel.Dock="Bottom">
        <Button Content="Select Question 3 choice 3" Click="ButtonBase_OnClick" />
    </StackPanel>
    <ItemsControl ItemsSource="{Binding Path=Questions}">
        <ItemsControl.ItemTemplateSelector>
            <learn:QuestionTemplateSelector QuestionTemplate="{StaticResource QuestionTemplate}" InstructionTemplate="{StaticResource InstructionTemplate}" />
        </ItemsControl.ItemTemplateSelector>
    </ItemsControl>
</DockPanel>

有人可以帮助我了解如何通过更智能的设计存档 (可能是Question的常见基类,并且每个问题类型都有Derived Question类,并使用类中的虚函数加载数据模板...)但是我想知道如何使用模板选择器来完成...或者我们需要使用一些不同的方法..

1 个答案:

答案 0 :(得分:2)

如果您创建从常见的Quiestion ViewModel派生的ViewModel,则可以创建列表(ObservableCollection<Question>)。然后使用以下ListBox:

<ListBox ItemsSource="{Binding YourQuestionList}">
     <ListBox.Resources>
           <DataTemplate DataType="{x:Type VM:QuestionType1}">
                  ( ... question1 full design ... )
           </DataTemplate>
           <DataTemplate DataType="{x:Type VM:QuestionType2}">
                  ( ... question2 full design ... )
           </DataTemplate>
           ( ... other data templates ... )
</ListBox>

DataContext将是您自定义完整设计中的特定问题ViewModel,因此您也可以使用这些属性进行绑定。您需要将对ViewModel所在的命名空间的引用(例如:xmlns:VM="clr-namespace:YourApp.VMs")添加到xaml文件的顶部(如果ViewModel的命名空间为VMs

我认为这应该为你做的工作。