2012-04-01 15 views
2

私は三分の一を参照する2つのクラス、持っている:今再利用要素とDataContextの

class Data1 
{ 
    public Named Xxx { get; set; } 
    public SomeClass1 Foo { get; set; } 
    ... 
} 

class Data2 
{ 
    public Named Yyy { get; set; } 
    public SomeClass2 Bar { get; set; } 
    ... 
} 

class Named 
{ 
    public string Name { get; set; } 
    ... 
} 

を、私は両方のData1 & Data2を表示したいと思います:

<TreeView DataContext={Binding Path=Data1}> 
    <TreeView.Items> 
    <TreeViewItem> 
     <TreeViewItem.Header> 
     <StackPanel Orientation="Horizontal"> 
      <ContentControl xml:space="preserve">Name: </ContentControl> 
      <ContentControl Content="{Binding Path=Xxx.Name}" /> 
     </StackPanel> 
     </TreeViewItem.Header> 
    </TreeViewItem> 
    <TreeViewItem><!-- somehow display Foo --></TreeViewItem> 
    <!-- More TreeViewItems, specific to Data1 --> 
    </TreeView.Items> 
</TreeView> 

<TreeView DataContext={Binding Path=Data2}> 
    <TreeView.Items> 
    <TreeViewItem> 
     <TreeViewItem.Header> 
     <StackPanel Orientation="Horizontal"> 
      <ContentControl xml:space="preserve">Name: </ContentControl> 
      <ContentControl Content="{Binding Path=Yyy.Name}" /> 
     </StackPanel> 
     </TreeViewItem.Header> 
    </TreeViewItem> 
    <TreeViewItem><!-- somehow display Bar --></TreeViewItem> 
    <!-- More TreeViewItems, specific to Data2 --> 
    </TreeView.Items> 
</TreeView> 

ので、マークアップを除いて、異なっていますNamedクラスを表示するTreeViewItemの場合このTreeViewItemのマークアップを再利用したいと思います。 UserControlを作成するのは簡単すぎますが、例に示すよりもやや複雑です。

<ResourceDictionary> 
    <TreeViewItem x:Key="Named"> 
    <TreeViewItem.Header> 
     <StackPanel Orientation="Horizontal"> 
     <ContentControl xml:space="preserve">Name: </ContentControl> 
     <ContentControl Content="{Binding Path=Name}" /> 
     </StackPanel> 
    </TreeViewItem.Header> 
    </TreeViewItem> 
</ResourceDictionary> 

そして、ちょうどこのようにそれを使用します:だから、私は本当にこのような何かをしたいと思います

<TreeView DataContext={Binding Path=Data1}> 
    <TreeView.Items> 
    <StaticResource ResourceKey="Named" /> 
    </TreeView.Items> 
</TreeView> 

あなたが見ることができるように、NamedためData1のプロパティ名はしばらくの間、XxxですNamedData2のプロパティ名はYyyです。だから、私は何とか私のリソースにそれを渡す必要があります。しかしどうですか?

など。このStaticResourceサブツリーのDataContextXxxData1に設定するにはどうすればよいですか?このような

何かが動作しません:長い質問の

<StaticResource ResourceKey="Named" DataContext={Binding Path=Xxx} /> 

申し訳ありません。

編集

私が欲しいのはNamedインスタンスを表示することが可能なXAMLの作品です。だから、インスタンスを取得する場所(XxxまたはYyyの外側にあるを指定できるようにしたいので、再利用できます。

EDIT2は:ここでは、しかし、それがうまく動作しない、ControlTemplateとソリューションです:TreeViewItemは選択不可となります。どうしましたか?

<ControlTemplate x:Key="Named" TargetType="TreeViewItem"> 
    <TreeViewItem> 
     <TreeViewItem.Header> 
      <StackPanel Orientation="Horizontal"> 
       <TextBlock Text="Name: " /> 
       <TextBlock Text="{Binding Path=Name}" /> 
      </StackPanel> 
     </TreeViewItem.Header> 
    </TreeViewItem> 
</ControlTemplate> 

<!-- now use the template: --> 
<TreeView> 
    <TreeView.Items> 
    <TreeViewItem Template="{StaticResource Named}" 
        DataContext="{Binding Path=Xxx}" /> 
    ... 

答えて

0

私は今日昼寝しました。私が目を覚ましたとき、私は突然、答えが何であるかを知りました!ここでは、次のとおりです。

<!-- In resources: --> 
<Style TargetType="TreeViewItem" x:Key="Named"> 
    <Setter Property="Header" Value="{Binding Name}" /> 
    <Setter Property="HeaderTemplate"> 
    <Setter.Value> 
     <DataTemplate> 
     <StackPanel Orientation="Horizontal"> 
      <TextBlock Text="Name: " /> 
      <TextBlock Text="{Binding}" /> 
     </StackPanel> 
     </DataTemplate> 
    </Setter.Value> 
    </Setter> 
</Style> 

<!-- now use the template: --> 
<TreeView> 
    <TreeView.Items> 
    <TreeViewItem Style="{StaticResource Named}" 
        DataContext="{Binding Path=Xxx}" /> 
    ... 
1

テンプレートトピック全体を調べる必要があります。 TreeViewItemのインスタンスを手動で作成する代わりに、アイテムのリストをTreeView.ItemsSourceプロパティにバインドし、再利用可能な静的リソースであるTreeView.ItemTemplateを指定する必要があります。 あなたは、あなたがtorvin、動的にあなたがあなたのコメントによると、より多くの情報

+0

は、マーティン、ありがとうございました。私は 'ItemsSource'を認識していますが、この場合、あなたが見ることができるように、バインドするコレクションはありません。 – torvin

0

を参照http://msdn.microsoft.com/en-us/library/system.windows.controls.itemscontrol.itemtemplateselector.aspx

を望むDataTemplateを選択するために、TreeView.ItemTemplateSelectorを使用できるデータ型を混在している場合は、あなたがたDataTemplateを使用する必要があります。 ItemsControlはテンプレートをサポートするだけでなく、ContentControlにもこの機能があります。 ContentTemplateプロパティがあります。 ContentControlは、DataTemplate.DataTypeプロパティを使用してテンプレートを自動的にフックします。

だから、あなたが名前付きオブジェクトを表しDataTemplateを作成することができます。そして、あなたがコンテンツとして名前付きオブジェクトを設定する必要があり

<...Resources> 
    <DataTemplate DataType="{x:Type local:Named}"> 
     <TextBlock Text="{Binding Name}"/> 
    </DataTemplate> 
</...Resources> 

を:

<TreeViewItem.Header> 
    <StackPanel Orientation="Horizontal"> 
     <ContentControl xml:space="preserve">Name: </ContentControl> 
     <ContentControl Content="{Binding Path=Xxx}" /> 
    </StackPanel> 
</TreeViewItem.Header> 

すべてです!今度はあなたを正しく理解してくれることを願っています:)

+0

ええああああああ!あまりにも多くのコード!この時点で、UserControlを書くだけで簡単になります。 – torvin

+0

UserControlを持っていても、XxxまたはYyyの指定を避けることはできません。 WPFがNameプロパティの変更を追跡することができないため、私の解決策も完璧ではありません。しかし、これを達成するためにコンバータを変更することができます。私は私の答えを編集しました。 –

+0

ありがとう、マラート、あなたが私を誤解したように見えます。私は2つの全く異なる 'TreeView'を持っています、彼らは同じソースに縛られていません。だから私はXxxやYyyの仕様を避ける必要はありません。私はちょうど共通のマークアップでこの仕様を避けたいです。言い換えれば、XAMLの一部に 'Named'クラスを表示したいだけです。名前付きインスタンスはこの部分の中に入っています。私は質問にこれを追加する必要があります... – torvin

関連する問題