1

目标:我希望拥有一个包含我的数据的对象,并将其绑定到 ContentPresenter,该 ContentPresenter 使用自定义 ContentTemplateSelector 选择适当的数据模板以在主控件中呈现。

问题: DataTemplate 在主控件中没有按预期呈现;它不呈现指定的视图控件。

代码:

MainView.xaml:

<Window x:Class="WpfContentTemplateSelector.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:this="clr-namespace:WpfContentTemplateSelector"
        Title="MainWindow" Height="350" Width="525">
    <Grid>
        <Grid.Resources>
            <this:ObjectWrapper x:Key="wrapper"/>
        </Grid.Resources>

        <ContentPresenter Content="{Binding Value}" DataContext="{StaticResource ResourceKey=wrapper}">
            <ContentPresenter.ContentTemplateSelector>
                <this:TemplateSelector/>
            </ContentPresenter.ContentTemplateSelector>
        </ContentPresenter>
    </Grid>
</Window>

数据对象.cs:

class DataObject
{
    public string Title { get; set; }

    public DataObject()
    {
        Title = "Title";
    }
}

ObjectWrapper.cs:

class ObjectWrapper
{
    public DataObject Value { get; set; }

    public ObjectWrapper()
    {
        Value = new DataObject();
    }
}

模板选择器.cs:

class TemplateSelector : DataTemplateSelector
{
    public override DataTemplate SelectTemplate(object item, DependencyObject container)
    {
        DataTemplate template = new DataTemplate(typeof(View));

        return template;
    }
}

查看.xaml:

<UserControl x:Class="WpfContentTemplateSelector.View"
             xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
             xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
             xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" 
             xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
             xmlns:this="clr-namespace:WpfContentTemplateSelector"
             mc:Ignorable="d" 
             d:DesignHeight="300" d:DesignWidth="300" Background="Navy">
    <Grid Background="Navy">
        <Button Height="30" Content="{Binding Title}"/>
    </Grid>
</UserControl>

概括:

  • ObjectWrapper 初始化。
  • DataObject 初始化。
  • 在初始化时,TemplateSelector 创建一个新的 DataTemplate。
  • 创建的 DataTemplate 在其构造函数中使用 View 类型。
  • 对象全部初始化,主视图的datacontext设置为DataObject,视图仍然没有渲染到主窗口。
4

2 回答 2

2

您的问题是,在您TemplateSelector为类型定义 DataTemplate 时,View您没有给它任何内容。您的代码相当于以下内容:

<ContentPresenter Content="{Binding Value}" DataContext="{StaticResource ResourceKey=wrapper}">
    <ContentPresenter.ContentTemplate>
        <DataTemplate DataType="this:View">
        </DataTemplate>
    </ContentPresenter.ContentTemplate>
</ContentPresenter>

在这里,您只是为 type定义一个空的 DataTemplateView,而您真正想要的是一个包含View控件的 DataTemplate:

<ContentPresenter Content="{Binding Value}" DataContext="{StaticResource ResourceKey=wrapper}">
    <ContentPresenter.ContentTemplate>
        <DataTemplate>
            <this:View />
        </DataTemplate>
    </ContentPresenter.ContentTemplate>
</ContentPresenter>

所以你需要做的是修改你TemplateSelector的返回一个正确的DataTemplate对象。

于 2012-08-19T20:28:34.630 回答
0

Adi Lester 的回应表明,我正在创建的 DataTemplate 对象的子节点没有呈现构造函数中使用的视图。

为了在代码隐藏中添加到 DataTemplate 的可视化树,我扩充了我的 TemplateSelector 对象以使用以下代码:

class TemplateSelector : DataTemplateSelector
{
    public override DataTemplate SelectTemplate(object item, DependencyObject container)
    {
        View view = item as View;
        DataTemplate template = new DataTemplate(typeof(View));

        FrameworkElementFactory factory = new FrameworkElementFactory(typeof(View));
        template.VisualTree = factory;

        return template;
    }
}

这成功地更改了可视化树并使用我的自定义 TemplateSelector 呈现视图以提供 DataTemplate。

于 2012-08-20T18:58:22.047 回答