Loading Different DataTemplate for each item in ListBox

匿名 (未验证) 提交于 2019-12-03 01:01:02

问题:

I am trying to create a learn application and I would like to load data template for based on Question type as explained below.

     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 

and the my page should look like...

Can Someone help me how to do this.

I am using the code from my previous post

Nested ObservableCollection data binding in WPF

and the xaml is ...

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

Can Some one help me in understanding how this can be archived with smarter design (may be a common base class for Question and have Derived Question class for each Question Type and load the data template using a virtual function from the class...) but I am wondering how this can be done using Template Selector ...or do we need to use some different approach..

回答1:

If you create your ViewModel-s derived from a common Quiestion ViewModel, you can create the list (ObservableCollection<Question>). Then use the following 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> 

The DataContext will be the specific Question ViewModel inside your custom full design, so you can use those properties for binding, too. You need to add the reference to the namespace your ViewModels are in (eg.: xmlns:VM="clr-namespace:YourApp.VMs") to the top of the xaml file (if your namespace for ViewModels is VMs.

I think this should do the work for you.



标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!