當前我試圖模仿FlowDocument環境中的ContentControl控件的行爲。我喜歡ContentControl,因爲它允許根據內容的類型在不同的模板中顯示內容。例如: -DependencyProperty在ResourceDictionary中找不到項目
<ContentControl Content={Binding}/>
將在ResourceDictionary中使用已定義的海格起來的DataTemplates在XAML:
<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);
}
}
正如你可以看到它的代碼verly基本和平和它的作品時,我在下面的方式使用它作爲預期:
<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
它從來沒有被調用過。
我希望你的專家能幫助我進一步與此!
提前感謝!
嗨!這確實有效,但對我的問題沒有解決方案,因爲我想爲每種內容類型定義不同的模板。 例如,如果內容的類型爲Person,那麼與內容爲House類型時相比,我希望使用不同的模板。通過使用模板的密鑰,我無法做到這一點,因爲密鑰需要是唯一的。 (在「資源」部分不允許有兩個具有相同鍵和不同數據類型的DataTemplates)。隨着微軟ContentControl有可能沒有密鑰,但我無法弄清楚他們是如何做到的......感謝您的回覆! – user1088858
爲什麼不使用不同的鍵?另外,當沒有指定鍵時,XAML解析器會生成一個隱式鍵 - 鍵將是'Type'的一個對象,並從TargetType(對於樣式,ControlTemplates)或DataType與DataTemplates中獲取其值。 –
如果我沒有記錯,那麼您引用的文章不支持隱式數據模板(沒有明確的鍵,只是定義了數據類型)。否則,解決方案將刪除x:Key屬性,並允許框架根據類型正確自動應用模板。您可以修改代碼以相當容易地支持,或者您可以根據您的情況設置ItemTemplate來創建默認樣式:) –