2009-07-23 17 views
6
<Window x:Class="WpfApplication1.Window1" 
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" 
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" 
    xmlns:local="clr-namespace:WpfApplication1" 
    Title="Window1"> 
    <Grid> 
     <local:ElementType x:Name="FirstElementName"> 
      <local:ElementType x:Name="SecondElementName" Grid.Column="1" Grid.Row="1" /> 
     </local:ElementType> 
    </Grid> 
</Window> 

そして、これは他のファイルに...カスタムXAML要素をネストする方法はありますか

<Grid x:Name="InternalElementName" x:Class="WpfApplication1.ElementType" 
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" 
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" 
    xmlns:local="clr-namespace:WpfApplication1"> 
</Grid> 

そして...

public partial class ElementType : System.Windows.Controls.Grid { } 

すべてが第二の要素を除いて、正常に動作しています。
エラーが発生しました。
要素 'ElementType'に名前属性値 'SecondElementName'を設定できません。 'ElementType'は、別のスコープで定義されたときにすでに登録されている名前を持つ要素 'ElementType'のスコープの下にあります。

カスタムグリッドが正しく定義されています。私はプロパティを取る場合のコードは、このエラーを引き起こしている何Window1.xaml

に--- ---

x:Name="SecondElementName" 

をコンパイルして実行しますか?どのように私はそれを回避するのですか?これらのカスタムグリッドの1つをもう1つのネスト内にネストする必要があります。また、それらの両方に名前が必要なので、それらを別々のデータにバインドすることができます。

ありがとうございます。あなたが他の内いずれかをしたい場合は

答えて

5

XAMLパーサーは、とりわけ、.NETクラスがそのような子のコンテナとして使用する既定の「コンテンツ」プロパティを定義しているかどうかを調べます。これは "ContentPropertyAttribute"で行われます。

[ContentProperty("Children")] 
public partial class ElementType : Grid 
{ 
    // your code here... 
} 
:私はあなたがネストされたオブジェクトがグリッド内で行ってみたい、とグリッドの子どもたちが「子供」プロパティコレクションに行くために、あなただけの次の操作を行う必要があると思いますので、あなたの場合は

コントロールに子を追加するときにロジックを行う必要がある場合(特定のタイプのみをElementTypeコントロールの子にするなど)、IAddChildから継承し、AddChildメソッドとAddTextメソッドを実装できます。

名前付けの問題に関しては、ルックレスコントロールのみがインスタンス化されたスコープ内で名前付きの子を持つことができるようです。基本的に、ElementType.xaml内に名前付きの子を持つことができますが、ElementTypeをインスタンス化する他のマークアップでは名前付きの子は指定できません。私はそれが彼らが論理的な木や何かを最適化する方法のためだと思う。 一方、見た目のないコントロールは、コードだけのコントロールです。したがって、クラスをGridの単純な古い空のサブクラスにすると、動作します:

public class ElementType : Grid 
{ 
} 

Yay!少ないコード!

+0

これも興味深いですが、それでも私は親と子のElementTypeオブジェクトに異なる名前を付けることができません。誰も私は彼らがお互いから別々に名前を付けられる方法を知っていますか? – Giffyguy

+0

ああ、申し訳ありません...上記の私の答えを完了します。 – Ludovic

1

、あなたが最初のContentプロパティにインナー1を入れたいと思います。また

<local:ElementType x:Name="FirstElementName"> 
    <local:ElementType.Content> 
     <local:ElementType x:Name="SecondElementName" Grid.Column="1" Grid.Row="1" /> 
    </local:ElementType.Content> 
</local:ElementType> 

、私はあなたがここで達成しようとしているのかわからないんだけどしかし、私はそれを恐れる。

+0

が鳴ります。あなたの最終的な見送りについて:HA!私は意図的に具体的なものを与えてくれるものを一切外しました---私を信じて、あなたは知りたくありません。あなたの解決策に関して、私はエラーが発生しています:「接続可能なプロパティ 'Content'が 'ElementType'タイプで見つかりませんでした」「Grid.Content」をその場所に試したところ、おおよそ同じエラーが発生します。その他のアイデアは? – Giffyguy

+0

私は「子供」を意味し、コンテンツは意味しません。あなたがそれを持っているように見えます。 –

0

UserControlを変更しない場合は、添付の動作を使用します。 XAMLコンパイルが失敗した場所に必要なのです!トラブルを起こすすべてのUserControlに対して1つの動作のみ。XAMLで

<preview:PreviewControl> 
    <i:Interaction.Behaviors> 
     <behaviors:UserControlNameBehavior Name="ICanSetNames"/> 
    </i:Interaction.Behaviors> 
</preview:PreviewControl> 

C#で:これは見出しすべき正しい方向であるよう

public class UserControlNameBehavior : Behavior<UserControl> 
    { 
     public string Name { get; set; } 

     protected override void OnAttached() 
     { 
      this.AssociatedObject.Loaded += OnLoaded; 
      base.OnAttached(); 
     } 

     private void OnLoaded(object sender, RoutedEventArgs routedEventArgs) 
     { 
      this.AssociatedObject.Name = this.Name; 
     } 
    } 
+0

Behaviorクラスとは何ですか?私は何ですか? –

関連する問題