2011-12-09 37 views
1

當前我試圖模仿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 

它從來沒有被調用過。

我希望你的專家能幫助我進一步與此!

提前感謝!

回答

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}" /> 

希望這有助於!

+0

嗨!這確實有效,但對我的問題沒有解決方案,因爲我想爲每種內容類型定義不同的模板。 例如,如果內容的類型爲Person,那麼與內容爲House類型時相比,我希望使用不同的模板。通過使用模板的密鑰,我無法做到這一點,因爲密鑰需要是唯一的。 (在「資源」部分不允許有兩個具有相同鍵和不同數據類型的DataTemplates)。隨着微軟ContentControl有可能沒有密鑰,但我無法弄清楚他們是如何做到的......感謝您的回覆! – user1088858

+0

爲什麼不使用不同的鍵?另外,當沒有指定鍵時,XAML解析器會生成一個隱式鍵 - 鍵將是'Type'的一個對象,並從TargetType(對於樣式,ControlTemplates)或DataType與DataTemplates中獲取其值。 –

+0

如果我沒有記錯,那麼您引用的文章不支持隱式數據模板(沒有明確的鍵,只是定義了數據類型)。否則,解決方案將刪除x:Key屬性,並允許框架根據類型正確自動應用模板。您可以修改代碼以相當容易地支持,或者您可以根據您的情況設置ItemTemplate來創建默認樣式:) –