none
コレクションの匿名バインドではうまく取り込まれ、クラス型経由でバインドすると取り込まれない理由 RRS feed

  • 質問

  • お世話になっております。

    C#でWindows8.1用のストアアプリを作成しています。理解できない動きがありまして、なぜなのかご教示くださると幸いです(もしかしたら、C#の基礎かもしれませんが、ご容赦いただきたく思います)。

    ページの xaml の中へ次のように記載しました。

    <ItemsControl x:Name="People" ItemsSource="{Binding}">
     <ItemsControl.ItemTemplate>
      <DataTemplate>
       <StackPanel Orientation="Vertical" >
        <TextBlock Text="{Binding Name}" />
        <Button Content="{Binding}" />
       </StackPanel>
      </DataTemplate>
     </ItemsControl.ItemTemplate>
    </ItemsControl>


    そして、ページのクラスのコンストラクタには次のように記載しました。

        public class Person
        {
            public string Name;
            public int Age;
            public Person(string p1, int p2) { this.Name = p1; this.Age = p2;}
        }
    
       public class MainPage()
       {
          this.InitializeComponent();
          ...    
          var d4 = new object[] { new {Name="YAMAGUCHI", Age = 30},
                                        new {Name="WADA", Age=24}};
    
          var d5 = new Person[] { new Person("SATO",21),
                                        new Person("NISHIDA",47)};
                
          this.People.DataContext = d5;  // or d4
          ...
       }

    ここでコンストラクタ中のコードを this.People.DataContext = d4; とすれば

    YAMAGUCHI

    [{Name=YAMAGUCHI, Age=30}]

    WADA

    [{Name=WADA, Age=24}]

    と表示されます([ ] はボタンです)。xaml 中の {Binding Name} をしっかり拾ってくれています。

    かし、クラスとして受け取るように、コンストラクタ中のコードを this.People.DataContext = d5; とすれば

    [Sample01.Person]

    [Sample01.Person]

    と表示され、{Binding Name} は拾われません。

    メンバーはpublicアクセスできるようにしています。匿名型と非匿名型で、なぜこのような動きの違いがでてくるのでしょうか?

    ちなみに、xamlの先頭部分を <ItemsControl x:Name="People" ItemsSource="{Binding Person}">

    としてみても、中ほどの部分を <TextBlock Text="{Binding Person.Name}" />

    としても、どちらも表示されません。

    バインド機構を利用できるのは匿名型のみ、などということは無いですよね...

    恐れ入りますが、ご教示のほどよろしくお願いいたします。


    2014年7月13日 14:06

回答

  • メンバーはpublicアクセスできるようにしています。匿名型と非匿名型で、なぜこのような動きの違いがでてくるのでしょうか?

    バインド機構を利用できるのは匿名型のみ、などということは無いですよね...

    フィールドはバインディングの対象とはなりません。プロパティに変更してください。

    public class Person
    {
        public string Name{get;set;}
        public int Age{get;set;}
        public Person(string p1, int p2) { this.Name = p1; this.Age = p2;}
    }
    なお、匿名型の各項目もプロパティになります。


    個別に明示されていない限りgekkaがフォーラムに投稿したコードにはフォーラム使用条件に基づき「MICROSOFT LIMITED PUBLIC LICENSE」が適用されます。(かなり自由に使ってOK!)


    • 編集済み gekkaMVP 2014年7月13日 14:25
    • 回答としてマーク Always fresh 2014年7月14日 0:57
    2014年7月13日 14:23

すべての返信

  • メンバーはpublicアクセスできるようにしています。匿名型と非匿名型で、なぜこのような動きの違いがでてくるのでしょうか?

    バインド機構を利用できるのは匿名型のみ、などということは無いですよね...

    フィールドはバインディングの対象とはなりません。プロパティに変更してください。

    public class Person
    {
        public string Name{get;set;}
        public int Age{get;set;}
        public Person(string p1, int p2) { this.Name = p1; this.Age = p2;}
    }
    なお、匿名型の各項目もプロパティになります。


    個別に明示されていない限りgekkaがフォーラムに投稿したコードにはフォーラム使用条件に基づき「MICROSOFT LIMITED PUBLIC LICENSE」が適用されます。(かなり自由に使ってOK!)


    • 編集済み gekkaMVP 2014年7月13日 14:25
    • 回答としてマーク Always fresh 2014年7月14日 0:57
    2014年7月13日 14:23
  • gekka様

    ご教示いただきまして、有難う御座います。確かにプロパティとして公開していませんでした...

    バインドで利用される型の情報は、単に構造や型情報をコンパイル時に決められるものではなくて、バインドの対象はオブジェクトとして扱われるものであって、そのための構造や振る舞いを求められているのですね。


    2014年7月14日 1:13
  • バインドで利用される型の情報は、単に構造や型情報をコンパイル時に決められるものではなくて、バインドの対象はオブジェクトとして扱われるものであって、そのための構造や振る舞いを求められているのですね。

    基本的には、publicなフィールドは使用しないという考え方が.NETにはあります。バインドだから特別というわけではないんです。

    フィールド (C# プログラミング ガイド)
    http://msdn.microsoft.com/ja-jp/library/ms173118.aspx


    ★良い回答には回答済みマークを付けよう! わんくま同盟 MVP - Visual C# http://d.hatena.ne.jp/trapemiya/

    2014年7月14日 6:53
    モデレータ
  • gekka様

    どうも有難う御座います。

    プログラムガイドに、流儀が丁寧に書かれていますね。ガイド全体を精読してみます。

    2014年7月15日 1:42