2009-05-22 10 views
8

WPFは時には複雑すぎます。私は "グループ"のコレクションを保持して私の "Window1"を持っている。 "Group"は "Person"の集合を持つクラスです。最後に、これは連絡先リストにする必要があります。私が単にやってみたいのは、リストボックスのグループ名がクラス「グループ」の名前プロパティと等しいリストボックスにその人物を含むグループを表示することです。WPF:グループでListBoxにコレクションをバインドする

"Collection"にバインドされたCollectionViewSourceを試しました。グループは正しく表示されますが、リストの項目はグループ名と同じです。したがって、各グループには1つの項目、つまりそのグループ名のみがあります。

多くの例では、1つのコレクションのみのアイテムのグループ化を示しています。私ができることは、 "Person"のプロパティとしてグループ名を設定することです。しかし、私は数えることができません(それは本当に必要です)。 - 各グループには何人の人がいますか? - 「ステータス」が「オンライン」である人の数。

私はそれをカウントするために "グループ"クラスのlinqを使用します。 私が手伝ってくれたアドバイスをありがとう。

答えて

21

まあ、私は、これはあなたが達成したいものですかどうかわからないのですが、ここであなたが試すことができます方法です同様に、コンタクトプロパティに別のListBoxのバインドとしてListBox.ItemTemplate設定することができます。

<CollectionViewSource x:Key="groups" Source="{Binding}" > 
    <CollectionViewSource.GroupDescriptions> 
     <PropertyGroupDescription PropertyName="Name" /> 
    </CollectionViewSource.GroupDescriptions> 
</CollectionViewSource> 

<DataTemplate x:Key="groupTemplate" DataType="Group"> 
    <StackPanel Orientation="Horizontal"> 
     <TextBlock Text="{Binding Name}" /> 
    </StackPanel> 
</DataTemplate> 

<ListBox ItemsSource="{Binding Source={StaticResource groups}}"> 
    <ListBox.GroupStyle> 
     <GroupStyle HeaderTemplate="{StaticResource groupTemplate}" /> 
    </ListBox.GroupStyle> 
    <ListBox.ItemTemplate> 
     <DataTemplate DataType="Contact"> 
      <ListBox ItemsSource="{Binding Contacts}"> 
       <ListBox.ItemTemplate> 
        <DataTemplate DataType="Contact"> 
         <TextBlock Text="{Binding Name}" /> 
        </DataTemplate> 
       </ListBox.ItemTemplate> 
      </ListBox> 
     </DataTemplate> 
    </ListBox.ItemTemplate> 
</ListBox> 

あなたは、内側ListBののスタイルを持っています牛少し。

編集TreeView

<DataTemplate DataType="Contact"> 
    <TextBlock Text="{Binding Name}" /> 
</DataTemplate> 

<TreeView ItemsSource="{Binding Source={StaticResource groups}}"> 
    <TreeView.ItemTemplate> 
     <HierarchicalDataTemplate DataType="Group" ItemsSource="{Binding Contacts}"> 
      <TextBlock Text="{Binding Name}" /> 
     </HierarchicalDataTemplate> 
    </TreeView.ItemTemplate> 
</TreeView> 
+0

これは静かで便利で、私の古いソリューションと同じです。ここでは、グループごとにエクスパンダーを、連絡先にListBoxを用意しました。ここで問題となるのは、リストごとに人を選択できるということですが、あなたはそれを1人で行うことができると思います。 Windows Live Messenger 2009連絡先リストのUIをコピーしようとしました。私は彼らがグループのControlTemplateとして1つのListBoxとExpanderを使用したと思う。しかし、私は彼らがグループを不動産と定義したと仮定します。しかし、私は実際にオンライン人をどのように数えることができるのか分かりません。ところで、あなたはクラスに合っています。 –

+0

階層データを表示するのにTreeViewコントロールを使用しないのはなぜですか? – idursun

+0

あなたは絶対に正しいです!私は確かに私の問題を解決するだろうと思う。私は "なぜ"の答えがありません。私は多くのTreeViewコントロールを使用していません。しかし、これは私の問題のためには最高です。ありがとう! –

8

あなたがProgramming WPFのコピーを持っている場合ではない場合は、ページ221にジャンプ私は(道の私の不適切な並べ替えに)まとめます

まず、手動でグループPersonオブジェクトには必要ありません。

各Personオブジェクトは、グループのプロパティを持っている場合は、

People people = // retrieve the List<Person> somehow 
ICollectionView view = CollectionViewSource.GetDefaultView(people); 
view.GroupDescriptions.Add(new PropertyGroupDescription("Group")); 

ItemsControlから派生するすべてのコントロールがとても

// the XAML 
<ListBox ... ItemsSource={Binding}> 
    <ListBox.GroupStyle> 
    <x:Static Member="GroupStyle.Default" /> 
    </ListBox.GroupStyle> 
</ListBox> 

あなたはまた、カスタムGroupStyleを定義し、GroupStyleを指定することができ、グループ化されたアイテムを表示することができます.HeaderTemplateを使用して、 'some PropertyValue(Count)'のようなカスタム属性を表示する新しいDataTemplateを定義する - 1つのTextBlockを{Binding SomeProperty}にバインドし、もう1つを{Binding ItemCount}

にバインドするこれらのようなものです

をあなたのクラスと仮定すると::

public class Group 
{ 
    public string Name { get; set; } 
    public List<Contact> Contacts { get; set; } 
} 

public class Contact 
{ 
    public string Name { get; set; } 
    public bool IsOnline { get; set; } 
} 

あなた

HTH

+0

おかげで、最初を使用して、別の解決策。私のPersonオブジェクトにはまだグループプロパティはありません。私はそれを避けたいです。私はカウントを処理する方法を理解していませんでした(ロジックのみ、TextBlockでの事実はクリアです)。 ここにいくつかのコードがあります。 列挙{オンライン、オフライン} OnlineStatus クラス人{// をカウントする必要があり、各グループのヘッダ// OnlineStatus「オンライン」で存在するどのように多くの人。 public OnlineStatus Status {get;セット; } } クラスグループ{ 公開リスト人=新しいリスト(); } class Window1 { 公開リストグループ=新しいリスト; } –

+0

+1、{バインディングItemCount}は私が必要としていた答えでした!ありがとうございました! – Dom

関連する問題