【问题标题】:WPF ContentTemplateSelector weirdnessWPF ContentTemplateSelector 怪异
【发布时间】:2012-08-19 19:12:47
【问题描述】:

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

问题: DataTemplate 在主控件中未按预期呈现;它不会呈现指定的 View 控件。

代码:

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>

DataObject.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;
    }
}

View.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,视图仍然没有渲染到主窗口。

【问题讨论】:

    标签: wpf datatemplate contenttemplateselector


    【解决方案1】:

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

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

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

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

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

    【讨论】:

    • 非常感谢您的回复。虽然我无法在 XAML 中定义视图,但您的回复更清楚地为我确定了问题。
    • @TylerKendrick 我认为一旦您知道问题出在哪里,修复您的TemplateSelector 就没有问题,而且我确实从您自己的回答中看到您已经解决了 :)
    【解决方案2】:

    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-16
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2015-12-29
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2018-06-30
      相关资源
      最近更新 更多