WPF中的数据模板 [英] DataTemplates in WPF

查看:81
本文介绍了WPF中的数据模板的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我对WPF中的数据模板有一个一般性的问题。假设我有一个名为 Question的抽象类,以及诸如 MathQuestion, GeographyQuestion等各种子类。在某些情况下,使用 Question数据模板将问题呈现为 Question就足够了,但是假设我有一个要依次显示的不同子类的随机Question对象的列表。我想使用特定的数据模板而不是通用的Question数据模板向用户显示它们,但是由于我不知道在设计时,是否可以告诉WPF:嘿,这是Quesitons的列表,但是使用反射来找出其特定类型并使用THAT数据模板?

I have a general question about data templates in WPF. Let's say I have an abstract class called "Question," and various subclasses like "MathQuestion," "GeographyQuestion," etc. In some contexts, rendering the questions as a "Question" using the "Question" data template is good enough, but let's say that I have a list of random Question objects of varying subclasses that I want to display in-turn. I want to display them to the user using their specific data templates rather than their generic Question data template, but since I don't know that at design time, is there anyway to tell WPF, "hey, here's a list of Quesitons, but use reflection to figure out their specific types and use THAT data template?"

到目前为止,我想到的是:除了收集我的问题外,我还认为,我可以使用反射创建特定类型的另一个集合,并以某种方式将其绑定到 blah,然后得到想要的效果,但是您只能绑定到WPF中的DependencyProperties,所以我不确定要绑定的内容至。我真的不喜欢这个想法,我的直觉告诉我,有一个更优雅的方法可以解决这个问题。

What I've thought of so far: I thought that in addition to having my question collection, I could create another collection of the specific types using reflection and somehow bind that to "blah," then I'd get the desired affect, but you can only bind to DependencyProperties in WPF, so I'm not sure what I'd bind to. I really don't like this idea, and my gut tells me there's a more elegant way to approach this problem.

我在这里不是在寻找特定的代码完成我想做的一般策略。另外,如果有帮助的话,我通常会使用MVVM。

I'm not looking for specific code here, just a general strategy to accomplish what I'm trying to do. Also, I'm using MVVM for the most part if that helps.

谢谢

推荐答案

我想这样的东西应该可以立即使用:

I'm thinking something like this should work right out of the box:

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






编辑:

是的,这肯定可以工作。这是一个更完整的示例:

Yes, this definitely should work. Here's a more complete example:

主视图模型

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 的一种很好的简化方法。这是结果代码:

Kyle Tolle pointed out a nice simplification for setting ItemsControl.ItemTemplate. Here is the resulting code:

<ItemsControl ItemsSource="{Binding QuestionViewModels}"
              ItemTemplate="{Binding}" /> 

这篇关于WPF中的数据模板的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆