2011-12-09 3 views
1

現在、私はFlowDocument環境でContentControlコントロールの動作を模倣しようとしています。 ContentControlが好きなのは、コンテンツのタイプに基づいて別のテンプレートにコンテンツを表示できるからです。私はインターネットを探し始め、私FlowDocument代替のために、この動作をコピーするために今すぐDependencyPropertyはResourceDictionary内の項目を見つけません

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

:例えば:

<ContentControl Content={Binding}/> 

はのResourceDictionaryでXAMLでhigerアップ定義されDataTemplatesを使用します。私は本当に多くの助けを受けたCreate Flexible UIs With Flow Documents And Data Bindingにやって来た。次のようにスタートとして、私はItemsContentを変更する:あなたは、それがコードのverly基本的な平和だと見ることができるように

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> 

これを

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

とリソースディクショナリにアップhiger:私はリソースディクショナリにDataTemplatesを定義する必要があります異なるコンテンツタイプに対して複数のテンプレートをサポートするために、すべてが順調に過ぎない

<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の場合とは異なるテンプレートを使用したいとします。キーを一意にする必要があるので、私はそれを行うことができませんテンプレートのキーを使用してください。 (「リソース」セクションでは、同じキーと異なるデータ型を持つ2つのDataTemplateを持つことはできません)。 MicrosoftのContentControlでは、キーなしで行うことは可能ですが、どうやってそれを行うのかわかりません...あなたの返事をありがとう! – user1088858

+0

異なるキーを使用してみませんか?また、キーが指定されていない場合、暗黙のキーがXAMLパーサーによって生成されます。キーは 'Type'のオブジェクトであり、TargetType(Styles、ControlTemplatesの場合)またはDataTemplatesを持つDataTypeから値を取得します。 –

+0

私が正しくリコールした場合、あなたが参照した記事は暗黙のデータテンプレート(明示的なキーなし、定義されたデータタイプのみ)をサポートしていません。それ以外の場合は、x:Key属性を削除し、フレームワークが型に基づいてテンプレートを正しく自動的に適用できるようにします。これをかなり簡単にサポートするようにコードを変更するか、状況に応じてItemTemplateを設定してデフォルトのスタイルを作成することができます:) –

関連する問題