DependencyProperty 在 ResourceDictionary 中找不到项目
目前我正在尝试模仿 FlowDocument 环境中 ContentControl 控件的行为。我喜欢 ContentControl,因为它允许根据内容的类型在不同的模板中显示内容。例如:
<ContentControl Content={Binding}/>
将使用在 ResourceDictionary 的 XAML 中定义的 DataTemplates:
<DataTemplate DataType={x:Type local:Person}>...</DataType>
<DataTemplate DataType={x:Type local:Pet}>...</DataType>
现在为了复制此行为以用于我的 FlowDocument 替代方案,我开始搜索互联网。我遇到了使用流文档和数据绑定创建灵活的 UI帮了很多忙。首先,我按如下方式更改了 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
它永远不会被调用。
希望各位专家能进一步帮助我解决这个问题!
提前非常感谢!
Currently i'm trying to mimic the behavior of the ContentControl Control in a FlowDocument environment. I like the ContentControl because it allows to display content in a different template based on the content's type. E.g.:
<ContentControl Content={Binding}/>
will use DataTemplates defined higer up in the XAML in a ResourceDictionary:
<DataTemplate DataType={x:Type local:Person}>...</DataType>
<DataTemplate DataType={x:Type local:Pet}>...</DataType>
Now to copy this behavior for my FlowDocument alternative i started searching the internet. I the came across Create Flexible UIs With Flow Documents And Data Binding which really helped a lot. As a start I altered the ItemsContent as follows:
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);
}
}
As you can see it's a verly basic peace of code and it works as expected when i use it in the following manner:
<FlowDocument>
<local:TemplatedContent Content={Binding}>
<local:TemplatedContent.Template>
<DataTemplate DataType={x:Type local:Person}>...</DataTemplate>
</local:TemplatedContent.Template>
</local:TemplatedContent>
</FlowDocument>
This is all well but to support multiple templates for different content types i will need to define the DataTemplates in a resource dictionary:
<FlowDocument>
<local:TemplatedContent Content={Binding}>
</local:TemplatedContent>
</FlowDocument>
and higer up in a resource dictionary:
<DataTemplate DataType={x:Type local:Person}>...</DataTemplate>
Now, the TemplatedContent is unable to find the DataTemplate. How is this possible? If I understand the theory around DependencyProperty correctly it should look in the xaml tree for entries that match the type of the content right? It doesn't. When setting a breakpoint on line:
private static void OnTemplateChanged
it's never called.
I hope you experts can help me further with this!
Lots of thanks in advance!
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
您需要在资源字典中定义模板,如下所示:
现在对模板的引用是通过
StaticResource
标记扩展完成的:希望这会有所帮助!
You need to define the template in your resource dictionary like so:
And the reference to your template is now done with a
StaticResource
markup extension:Hope this helps!