2010-05-27 36 views
6

Argh, mặc dù tôi đã googling, tôi thực sự sẽ đánh giá cao nếu ai đó có thể phá vỡ vấn đề của tôi xuống như tất cả các ví dụ mã trực tuyến gây nhầm lẫn cho tôi nhiều hơn hỗ trợ (có lẽ nó chỉ là muộn) .. .WPF Databinding Với đối tượng sưu tập

tôi có một lớp đơn giản theo quy định dưới đây:

public class Person 
{ 
    int _id; 
    string _name; 

    public Person() 
    { } 

    public int ID 
    { 
     get { return _id; } 
     set { _id = value; } 
    } 

    public string Name 
    { 
     get { return _name; } 
     set { _name = value; } 
    } 
} 

được lưu trữ trong một cơ sở dữ liệu, và thông qua một mã chút nữa tôi đặt nó vào một đối tượng ObservableCollection để cố gắng DataBind trong WPF sau:

public class People : ObservableCollection<Person> 
{ 
    public People() : base() { } 

    public void Add(List<Person> pListOfPeople) 
    { 
     foreach (Person p in pListOfPeople) this.Add(p); 
    } 
} 

Trong XAML, tôi có bản thân mình một ListView mà tôi muốn điền một ListViewItem (bao gồm một textblock) cho mỗi mục trong đối tượng "Mọi người" khi nó được cập nhật từ cơ sở dữ liệu. Tôi cũng muốn khối chữ đó liên kết với thuộc tính "Tên" của đối tượng Person.

tôi nghĩ lúc đầu tiên mà tôi có thể làm điều này:

lstPeople.DataContext = objPeople; 

nơi lstPeople là kiểm soát ListView của tôi trong XAML của tôi, nhưng điều đó tất nhiên không có gì. Tôi đã tìm thấy TẤN của các ví dụ trực tuyến nơi mọi người thông qua XAML tạo một đối tượng và sau đó liên kết với nó thông qua XAML của họ; nhưng không phải là nơi chúng tôi liên kết với một đối tượng được khởi tạo và vẽ lại cho phù hợp.

Ai đó có thể xin vui lòng cho tôi một vài gợi ý về:

A) Làm thế nào để ràng buộc một điều khiển ListView để khởi tạo của tôi "Mọi người" đối tượng bộ sưu tập?

B) Làm cách nào để áp dụng mẫu cho ListView để định dạng mẫu cho các đối tượng trong bộ sưu tập?

Ngay cả liên kết đến một ví dụ phong nha (không phải một thao tác trên một đối tượng được khai báo trong XAML) sẽ được đánh giá cao.

Cảm ơn thời gian của bạn.

Trả lời

6

Bạn đã thân thiết đến vậy.

lstPeople.ItemsSource = objPeople; // :) 

Điều duy nhất bạn cần là cách áp dụng chế độ xem cho từng mục trong bộ sưu tập của bạn. Không vấn đề gì. Tôi sẽ không sử dụng một ListView ... Tôi sẽ chỉ sử dụng một ItemsControl vì nó đơn giản hơn một chút.

<ItemsControl x:Name="lstPeople"> 
    <ItemsControl.ItemTemplate> 
     <DataTemplate> 
       <TextBlock Text="{Binding Name}" /> 
     </DataTemplate> 
    </ItemsControl.ItemTemplate> 
</ItemsControl> 

Khá nhiều. Chiến lược này giống nhau cho một Listview, nhưng bạn chỉ cần cung cấp một chút XAML để cung cấp các tiêu đề cột và nội dung. Tôi không chắc chắn 100% bạn cần điều này vào lúc này, vì vậy tôi đã bỏ nó ra.

Chỉnh sửa: Đây là phương pháp mở rộng cho "AddRange" sẽ thực hiện những gì bạn đang cố gắng thực hiện bằng cách phân lớp ObservableCollection. Chút dễ dàng hơn ... đặc biệt là nếu bạn kết thúc với rất nhiều loại bộ sưu tập (bạn sẽ)

public static void AddRange<T>(this ObservableCollection<T> collection, IEnumerable<T> items) 
{ 
    foreach(var item in items) 
    { 
      collection.Add(item); 
    } 
} 

Sau đó, bạn có thể chỉ cần làm:

ObservableCollection<Person> peeps = new ObservableCollection<Person>(); 
peeps.AddRange(new List<Person> 
{ 
    new Person() { Name = "Greg" }, 
    new Person() { Name = "Joe" } 
}); 
+0

+1 tôi có câu trả lời gần như giống hệt với bạn. – slugster

+0

Ah, cảm ơn vì đã giải thích tất cả mọi người! – Randster

0

@Anderson đánh tôi bằng giây, câu trả lời của tôi là rất tương đồng.

Một điều tôi sẽ thêm mặc dù: không có cần phải xác định một loại mới của bộ sưu tập được thừa kế từ ObservableCollection, thay vào đó bạn chỉ có thể làm điều này:

ObservableCollection<Person> myPeopleCollection = new ObservableCollection<Person>(); 

lần duy nhất bạn muốn mở rộng nó là nếu bạn định làm điều gì đó khác lạ hoặc lạ lùng với nó, điều mà bạn dường như không làm.

+0

OP muốn có loại phương thức "AddRange" cho bộ sưu tập của mình. Tôi thường muốn bản thân mình trên ObservableCollections. Tôi có thể thấy lý do tại sao bạn sẽ làm điều đó. Tôi đã viết ExtensionMethods để làm điều tương tự. –

+0

@Anderson - vâng trên cái nhìn đầu tiên, tất cả những gì tôi thấy là chức năng * Thêm *, khi bạn đề cập đến nó, tôi nhìn lại và thấy thông số mà anh ta đã truyền vào nó. – slugster

0

Trên thực tế đáp ứng 'Anderson IME' là đúng (phiếu bầu tán thành), mặc dù tôi có hai nhận xét:

Thứ nhất, nếu bạn chỉ cần để hiển thị một tài sản của một đối tượng, tôi nghĩ rằng nó dễ dàng hơn và sạch hơn để sử dụng ListBox thay của ListView, vì mã cho ràng buộc tài sản sẽ được giảm xuống còn

<ListBox x:Name="lstPeople" DisplayMemberPath="Name" /> 

thứ hai, nếu bạn đang sử dụng WPF và Ràng buộc, chắc chắn rằng đối tượng của bạn thực hiện INotifyPropertyChanged, do đó thay đổi luôn được đồng bộ hóa giữa UI và các các đối tượng.

public class Person : INotifyPropertyChanged 
{ 
    int _id; 
    string _name; 

    public Person() 
    { } 

    public int ID 
    { 
     get { return _id; } 
     set { 
      _id = value; 
      RaisePropertyChanged("ID"); 
      } 
    } 

    public string Name 
    { 
     get { return _name; } 
     set { 
      _name = value; 
      RaisePropertyChanged("Name"); 
      } 
    } 

    pivate void RaisePropertyChanged(string propName) 
    { 
     if (PropertyChanged != null) 
      PropertyChanged(this, new PropertyChangedEventArgs(propName)); 
    } 

} 
+0

Cảm ơn mẹo; tiếp tục googling dẫn tôi tin rằng bạn là đúng và tôi sẽ phải thực hiện INotifyPropertyChanged trong mã của tôi. Cảm ơn thông tin! – Randster

Các vấn đề liên quan