我对
WPF中的数据模板有一般性问题.假设我有一个名为“问题”的抽象类,以及各种子类,如“MathQuestion”,“GeographyQuestion”等.在某些情况下,使用“问题”数据模板将问题呈现为“问题”已经足够了,但是假设我有一个不同子类的随机问题对象列表,我想反过来显示它们.我想使用他们的特定数据模板而不是他们的通用问题数据模板将它们显示给用户,但由于我不知道在设计时,无论如何都告诉WPF,“嘿,这是一个Quesitons列表,但是使用反射来弄清楚他们的具体类型并使用那个数据模板?“
到目前为止我所想到的:我认为除了我的问题集之外,我可以使用反射创建另一个特定类型的集合,并以某种方式将其绑定到“blah”,然后我会得到所需的效果,但是你只能绑定到WPF中的DependencyProperties,所以我不确定我绑定到什么.我真的不喜欢这个想法,我的直觉告诉我有一个更优雅的方法来解决这个问题.
我不是在寻找具体的代码,只是一个完成我想要做的事情的一般策略.另外,如果有帮助的话,我大部分时间都在使用MVVM.
谢谢
解决方法
我认为这样的东西应该是开箱即用的:
<UserControl.Resources> <DataTemplate DataType="{x:Type vm:GenericQuestionviewmodel}"> <v:GenericQuestion/> </DataTemplate> <DataTemplate DataType="{x:Type tvm:GeographyQuestionviewmodel}"> <tv:GeographyQuestion/> </DataTemplate> <DataTemplate DataType="{x:Type tvm:BiologyQuestionviewmodel}"> <tv:BiologyQuestion/> </DataTemplate> </UserControl.Resources> <ContentControl Content="{Binding Questionviewmodel}">
编辑:
是的,这绝对应该有效.这是一个更完整的例子:
主视图模型
public class MainWindowviewmodel : viewmodelBase { public ObservableCollection<Questionviewmodel> Questionviewmodels { get; set; } public MainWindowviewmodel() { Questionviewmodels = new ObservableCollection<Questionviewmodel> { new GenericQuestionviewmodel(),new GeographyQuestionviewmodel(),new BiologyQuestionviewmodel() }; } }
问题查看模型
public abstract class Questionviewmodel : viewmodelBase { } public class GenericQuestionviewmodel : Questionviewmodel { } public class GeographyQuestionviewmodel : Questionviewmodel { } public class BiologyQuestionviewmodel : Questionviewmodel { }
问题用户控制
<UserControl x:Class="WpfApplication1.GenericQuestion" ...> <Grid> <TextBlock Text="Generic Question" /> </Grid> </UserControl> <UserControl x:Class="WpfApplication1.GeographyQuestion" ...> <Grid> <TextBlock Text="Geography Question" /> </Grid> </UserControl> <UserControl x:Class="WpfApplication1.BiologyQuestion" ...> <Grid> <TextBlock Text="Biology Question" /> </Grid> </UserControl>
主窗口
<Window x:Class="WpfApplication1.MainWindow" ... Title="MainWindow" Height="900" Width="525"> <Window.DataContext> <local:MainWindowviewmodel /> </Window.DataContext> <Window.Resources> <DataTemplate DataType="{x:Type local:GenericQuestionviewmodel}"> <local:GenericQuestion /> </DataTemplate> <DataTemplate DataType="{x:Type local:GeographyQuestionviewmodel}"> <local:GeographyQuestion /> </DataTemplate> <DataTemplate DataType="{x:Type local:BiologyQuestionviewmodel}"> <local:BiologyQuestion /> </DataTemplate> </Window.Resources> <ItemsControl ItemsSource="{Binding Questionviewmodels}"> <ItemsControl.ItemTemplate> <DataTemplate> <ContentControl Content="{Binding}" /> </DataTemplate> </ItemsControl.ItemTemplate> </ItemsControl> </Window>
更新
Kyle Tolle指出了一个很好的简化设置ItemsControl.ItemTemplate.这是结果代码:
<ItemsControl ItemsSource="{Binding Questionviewmodels}" ItemTemplate="{Binding}" />