DependencyProperty在ResourceDictionary中找不到项目

时间:2011-12-09 01:21:26

标签: c# wpf xaml dependency-properties resourcedictionary

目前,我试图在FlowDocument环境中模仿ContentControl控件的行为。我喜欢ContentControl,因为它允许根据内容的类型在不同的模板中显示内容。 E.g:

<ContentControl Content={Binding}/>

将使用在ResourceDictionary的XAML中定义的DataTemplates:

<DataTemplate DataType={x:Type local:Person}>...</DataType>
<DataTemplate DataType={x:Type local:Pet}>...</DataType>

现在为我的FlowDocument替代方案复制此行为,我开始搜索互联网。我遇到了Create Flexible UIs With Flow Documents And Data Binding这真的帮了很多忙。作为开始,我按如下方式更改了ItemsContent:

public class TemplatedContent : Section
{
    private static readonly DependencyProperty ContentProperty = DependencyProperty.Register("Content", typeof(object), typeof(TemplatedContent), new PropertyMetadata(OnContentChanged));
    private static readonly DependencyProperty TemplateProperty = DependencyProperty.Register("Template", typeof(DataTemplate), typeof(TemplatedContent), new PropertyMetadata(OnTemplateChanged));

    public TemplatedContent()
    {
        //Helpers.FixupDataContext(this);
        Loaded += TemplatedContent_Loaded;
    }

    private void TemplatedContent_Loaded(object sender, RoutedEventArgs e)
    {
        GenerateContent(Template, Content);
    }

    public object Content
    {
        get { return GetValue(ContentProperty); }
        set { SetValue(ContentProperty, value); }
    }

    public DataTemplate Template
    {
        get { return (DataTemplate)GetValue(TemplateProperty); }
        set { SetValue(TemplateProperty, value); }
    }


    private void GenerateContent(DataTemplate template, object content)
    {
        Blocks.Clear();
        if (template != null && content != null)
        {
            FrameworkContentElement element = Helpers.LoadDataTemplate(template);
            element.DataContext = content;
            //Helpers.UnFixupDataContext(element);
            Blocks.Add(Helpers.ConvertToBlock(content, element));
        }
    }

    private void GenerateContent()
    {
        GenerateContent(Template, Content);
    }

    private void OnContentChanged(object newValue)
    {
        if (IsLoaded)
            GenerateContent(Template, newValue);
    }

    private void OnTemplateChanged(DataTemplate newValue)
    {
        if (IsLoaded)
            GenerateContent(newValue, Content);
    }

    private static void OnContentChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
    {
        ((TemplatedContent)d).OnContentChanged(e.NewValue);
    }

    private static void OnTemplateChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
    {
        ((TemplatedContent)d).OnTemplateChanged((DataTemplate)e.NewValue);
    }
}

正如您所看到的那样,这是一个非常基本的代码安静,当我以下列方式使用它时,它可以按预期工作:

 <FlowDocument>
     <local:TemplatedContent Content={Binding}>
        <local:TemplatedContent.Template>
           <DataTemplate DataType={x:Type local:Person}>...</DataTemplate>
        </local:TemplatedContent.Template>
     </local:TemplatedContent>
 </FlowDocument>

这很好但是为了支持不同内容类型的多个模板,我需要在资源字典中定义DataTemplates:

<FlowDocument>
    <local:TemplatedContent Content={Binding}>
    </local:TemplatedContent>
</FlowDocument>

并在资源词典中高高举起:

 <DataTemplate DataType={x:Type local:Person}>...</DataTemplate>

现在,TemplatedContent无法找到DataTemplate。这怎么可能?如果我正确理解DependencyProperty的理论,它应该在xaml树中查找与内容类型匹配的条目吗?它没有。在线设置断点时:

private static void OnTemplateChanged

它从未被召唤过。

我希望你的专家可以帮助我进一步解决这个问题!

提前多多谢意!

1 个答案:

答案 0 :(得分:0)

您需要在资源字典中定义模板,如下所示:

<FlowDocument>
    <FlowDocument.Resources>
        <DataTemplate x:Key="MyDataTemplate">
            <!-- Contents of template go here -->
        </DataTemplate>
    </FlowDocument.Resources>
    <!-- document content here -->
</FlowDocument>

现在使用StaticResource标记扩展程序完成对模板的引用:

<local:TemplateContent Content="{Binding}" Template="{StaticResource MyDataTemplate}" />

希望这有帮助!