2

私は WPF が初めてで、このオブジェクトを wpf コントロールにバインドする方法について簡単なアドバイスが欲しいのですが、どのコントロールを使用すればよいかわかりません。

public class Parent
{
  public string Name{get; set;}
  public List<Child> Childs {get; set;}
}

public class Child
{
  public string Name{get; set;}
  public int Age {get; set;}
}

public class ParentFactory
{
   public List<Parent> Parents {get; set;}

   public ParentFactory()
   {
      Child child1 = new Child() {Name="Peter", Age=10;};
      Child child2 = new Child() {Name="Mary", Age=9;};
      Child child3 = new Child() {Name="Becky", Age=12;};

      Parent parent1 = new Parent(){Name="Adam", Childs = new List<Child<>(){child1, child2}};
      Parent parent2 = new Parent(){Name="Kevin", Childs = new List<Child<>(){child3}};

      Parents = new List<Parent>(){parent1, parent2};
   }
}

このインスタンスを作成した後:

ParentFactory parentFactory = new ParentFactory();

parentFactory.Parents() を WPF のコントロールにバインドしたいと思います。私は次のようなものを見ると思います:


アダム

-- ピーター、10歳

-- メアリー、9 歳

ケビン

-- ベッキー、12歳


それらはすべてテキストボックスに表示され、変更できます。

前もって感謝します。

4

2 に答える 2

4

HierarchicalDataTemplate で TreeView を使用します。

ただし、モデルに INotifyPropertyChanged を実装しないと、プロパティの変更時にバインディングが更新されないことに注意してください。また、リストを ObservableCollections に置き換えないと、リストにアイテムを追加してもビューが更新されません。

このようなものが機能するはずです。最初にテンプレートを定義します。

<Window.Resources>
    <HierarchicalDataTemplate DataType="{x:Type local:Parent}" ItemsSource="{Binding Childs}">
        <TextBlock Text="{Binding Name}"/>
    </HierarchicalDataTemplate>
    <DataTemplate DataType="{x:Type local:Child}">
        <StackPanel Orientation="Horizontal">
            <TextBlock Text="{Binding Name}"/>
            <TextBlock>, </TextBlock>
            <TextBlock Text="{Binding Age}"/>
        </StackPanel>
    </DataTemplate>
</Window.Resources>

次に、次のように TreeView でそれらを使用できます (Parents が TreeView の DataContext のプロパティであると仮定します)。

<TreeView ItemsSource="{Binding Parents}"/>

TreeView が必要ない場合は、ListView を使用して簡単にリストを作成し、DataTemplates を次のように変更できます。

    <DataTemplate DataType="{x:Type local:Parent}">
        <StackPanel>
            <TextBlock Text="{Binding Name}"/>
            <ListView ItemsSource="{Binding Childs}"/>
        </StackPanel>
    </DataTemplate>
    <DataTemplate DataType="{x:Type local:Child}">
        <StackPanel Orientation="Horizontal">
            <TextBlock Text="{Binding Name}"/>
            <TextBlock>, </TextBlock>
            <TextBlock Text="{Binding Age}"/>
        </StackPanel>
    </DataTemplate>

そして、次のようにバインドできます。

<ListView ItemsSource="{Binding Parents}"/>

注: すぐに使えるように見えるので、スタイルを少しいじる必要があるかもしれません。少なくとも、子の ListView (親の DataTemplate で定義されているもの) をインデントして、その境界線を取り除きたいと思うでしょう。

また、注意: 名前と年齢のために複数の TextBlocks をレイアウトするための StackPanel も理想的ではありませんが、迅速で汚れています。別の方法で処理したい場合があります。(マルチ) コンバーターを使用してフォーマットしたり、StringFormat を使用したり、表示のためだけにモデルに別のプロパティを追加したり、子クラスで ToString をオーバーライドしたりすることもできます。

別の編集

DataGrid を使用した簡単な (そして醜い) 例:

<DataGrid ItemsSource="{Binding Parents}" AutoGenerateColumns="False">
    <DataGrid.RowDetailsTemplate>
        <DataTemplate>
            <DataGrid ItemsSource="{Binding Childs}"/>
        </DataTemplate>
    </DataGrid.RowDetailsTemplate>
    <DataGrid.Columns>
        <DataGridTextColumn Binding="{Binding Name}"/>
    </DataGrid.Columns>
</DataGrid>

これにより、行の詳細テンプレートを使用して、データ グリッドがデータ グリッド内に配置されます。行をクリックすると、子が行の詳細として表示されます。詳細を常に利用できるようにする場合は、RowDetailsTemplate を削除し、DataGridTextColumn を DataGridTemplateColumn に置き換えてから、データのテンプレートを定義します。

于 2012-04-17T13:40:30.757 に答える
3

ツリー ビューが必要ない場合 (階層があるため、これがおそらく最適です。階層は 1 レベルしかないため、リストのケースがまだある可能性があります)...次の
ようなことができます (これは大まかなアウトラインです。ドットを埋める必要があります)...

<ItemsControl ItemsSource="{Binding AllNodes}">
</ItemsControl>

...そして、マットが言及したように、各タイプに固有のテンプレートを定義します...

<DataTemplate DataType="{x:Type namespace:Child}">
...
</DataTemplate>

<DataTemplate DataType="{x:Type namespace:Parent}">
...
</DataTemplate>

...は、あなたが持っている階層から AllNodes必要なリストですが、これを使用できます...flatten

var allnodes = Parents.SelectMany(p => new object[]{p}.Concat(p.Childs));  

...そして AllNodes を Parents と同様のプロパティとして公開します - 提案されているように、適切に実装された INotifyPropertyChanged を持つビューモデルが必要です。

お役に立てれば

于 2012-04-17T14:10:36.677 に答える