2009-05-22 7 views
8

đôi khi WPF quá phức tạp đối với tôi. Tôi đã có "Window1" của tôi đang nắm giữ một bộ sưu tập của "Group" s. "Nhóm" là một lớp với một bộ sưu tập "Người". Cuối cùng, đây phải là một danh sách liên lạc. Những gì tôi chỉ đơn giản muốn làm là để hiển thị các nhóm với người của mình trong một ListBox, nơi tên nhóm của các nhóm danh sách bằng với thuộc tính tên của lớp của tôi "Groups".WPF: Bộ sưu tập liên kết với Bộ sưu tập vào một ListBox với các nhóm

Tôi đã thử với CollectionViewSource được liên kết với "Bộ sưu tập". Các nhóm được hiển thị chính xác, nhưng các mục trong danh sách bằng với tên nhóm. Vì vậy, mỗi nhóm chỉ có một mục: tên nhóm của nó.

Nhiều ví dụ ở đây cho thấy việc nhóm các mục chỉ với một bộ sưu tập. Những gì tôi có thể làm là đặt tên nhóm là Thuộc tính của "Người". Nhưng sau đó tôi không thể đếm (và đó là thực sự cần thiết): - có bao nhiêu người trong mỗi nhóm - bao nhiêu người trong số đó có "Trạng thái" "Trực tuyến".

Tôi sử dụng LINQ trong lớp "Nhóm" để tính. Cảm ơn mọi lời khuyên giúp tôi bắt đầu.

Trả lời

21

Vâng, tôi không chắc chắn nếu điều này là những gì bạn muốn đạt được nhưng đây là một cách mà bạn có thể thử:

Giả sử lớp học của bạn là như thế này:

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; } 
} 

Bạn có thể đặt ListBox.ItemTemplate làm một ListBox khác liên kết với thuộc tính Danh bạ, như:

<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> 

Bạn phải tạo kiểu cho danh sách bên trong bò một chút.

Sửa: Một giải pháp bằng cách sử dụng 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

Điều này là yên tĩnh hữu ích và bằng giải pháp cũ của tôi, nơi tôi có Expander cho mỗi nhóm và ListBox cho Danh bạ. Vấn đề ở đây là, bạn có thể chọn một người cho mỗi danh sách, nhưng tôi cho rằng bạn có thể làm điều đó với một. Tôi cố gắng sao chép giao diện người dùng của danh sách liên hệ Windows Live Messenger 2009. Tôi nghĩ rằng họ chỉ sử dụng một ListBox và Expander như ControlTemplate cho nhóm. Nhưng tôi cũng giả định, họ định nghĩa nhóm là tài sản. Nhưng tôi thực sự không biết, làm thế nào họ có thể đếm những người trực tuyến. Nhân tiện, bạn có quyền với các lớp học của bạn. –

+0

Tại sao bạn không sử dụng điều khiển TreeView để hiển thị dữ liệu phân cấp? – idursun

+0

Bạn hoàn toàn đúng! Tôi nghĩ, điều đó sẽ giải quyết được vấn đề của tôi. Tôi không có câu trả lời cho "lý do". Tôi đã không sử dụng điều khiển TreeView rất nhiều. Nhưng điều này sẽ là tốt nhất cho vấn đề của tôi. Cảm ơn! –

8

Nếu bạn có một bản sao của Programming WPF, nhảy đến trang 221. Nếu không tôi sẽ tóm tắt (trong loại vớ vẩn của tôi về chiều)

Trước tiên, bạn không cần phải tự nhóm các đối tượng Person.

Nếu mỗi đối tượng Person có một tài sản Group,

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

Tất cả các điều khiển mà xuất phát từ ItemsControl có thể hiển thị các mục nhóm, vì vậy

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

Bạn cũng có thể định nghĩa một groupstyle tùy chỉnh và xác định groupstyle .HeaderTemplate để xác định một DataTemplate mới cho thấy các thuộc tính tùy chỉnh như 'một số PropertyValue (Đếm)' - Liên kết một TextBlock với {Binding SomeProperty} và một khác tới {Binding ItemCount}

HTH

+0

Cảm ơn, đầu tiên. Đối tượng Person của tôi không có thuộc tính nhóm. Tôi muốn tránh nó. Tôi không hiểu làm thế nào tôi có thể xử lý số lượng (chỉ logic, thực tế với TextBlock là rõ ràng). Dưới đây là một số mã, nếu nó có thể giúp bạn. enum OnlineStatus {ONLINE, OFFLINE} lớp Người { // Tiêu đề của mỗi nhóm sẽ tính // số lượng Người tồn tại với OnlineStatus "Trực tuyến". Trạng thái trực tuyến công khai {get; bộ; } } Nhóm học sinh { Danh sách công khai Persons = new List (); } lớp Window1 { Danh sách công khai Groups = new List ; } –

+0

+1, '{Binding ItemCount}' là câu trả lời tôi cần! CẢM ƠN BẠN! – Dom