2011-05-31 13 views
5

Tôi có một chút mã đọc phản hồi json từ máy chủ HTTP, sau đó phân tích cú pháp này và chèn dữ liệu vào điều khiển ListBox.Databinding with a Listbox

Sự kiện này tôi bắn ra khi quá trình download hoàn tất như sau:

void webClient_OpenReadCompleted(object sender, OpenReadCompletedEventArgs e) 
{ 
    DataContractJsonSerializer ser = null; 

    try 
    { 
     ser = 
     new DataContractJsonSerializer(typeof(ObservableCollection<UserLeaderboards>)); 

     ObservableCollection<UserLeaderboards> users = 
      ser.ReadObject(e.Result) as ObservableCollection<UserLeaderboards>; 

     foreach (UserLeaderboards em in users) 
     { 
      int Fid = em.id; 
      string Fusername = em.username; 
      int Fscore = em.score; 
      lstbLeaders.Items.Add(Fid + Fusername + Fscore); 
     } 
    } 
    catch (Exception ex) 
    { 
     MessageBox.Show(ex.Message); 
    } 
} 

Bây giờ, khi tôi làm items.add Tôi đoán nó chỉ tham gia lên 3 biến và thêm nó vào một cột trong ListBox . Điều này hoạt động tốt và tôi thấy tất cả 3 mục đã tham gia và hiển thị.

Tôi muốn tách riêng phần này và làm cho nó đẹp hơn một chút vì vậy tôi đã tạo một số XAML để thử và liên kết các biến với textblocks. Sau đây chỉ là ràng buộc tên người dùng. Tôi cũng có một lớp công khai nhận/đặt tất cả 3 biến.

<ListBox Height="346" HorizontalAlignment="Left" Margin="5,221,0,0" 
     Name="lstbLeaders" VerticalAlignment="Top" Width="446"> 
    <DataTemplate>        
     <TextBlock Text="{Binding Source=Fusername}" />       
    </DataTemplate> 
</ListBox> 

Khi chạy ở trên, tôi hoàn toàn không thấy gì cả. Tôi có cảm giác nó đơn giản?

Cảm ơn.

Trả lời

5

Để hiển thị một chuỗi đơn giản XAML của bạn sẽ giống như thế này:

<ListBox Height="346" HorizontalAlignment="Left" Margin="5,221,0,0" 
     Name="lstbLeaders" VerticalAlignment="Top" Width="446"> 
    <ListBox.ItemTemplate> 
     <DataTemplate>        
      <TextBlock Text="{Binding}" />       
     </DataTemplate> 
    <ListBox.ItemTemplate> 
</ListBox> 

và bạn phải cung cấp một đối tượng thay vì một chuỗi đơn giản nếu bạn muốn chia các thuộc tính để làm nó trông đẹp hơn. Nếu bạn chỉ cần thêm Fid + Fusername + Fscore, bạn sẽ kết thúc bằng một chuỗi đơn giản.

<ListBox Height="346" HorizontalAlignment="Left" Margin="5,221,0,0" 
     Name="lstbLeaders" VerticalAlignment="Top" Width="446"> 
    <ListBox.ItemTemplate> 
     <DataTemplate>        
      <StackPanel Orientation="Horizontal"> 
       <TextBlock Text="{Binding Id}" />       
       <TextBlock Text="{Binding Name}" />       
       <TextBlock Text="{Binding Score}" />       
      </StackPanel> 
     </DataTemplate> 
    <ListBox.ItemTemplate> 
</ListBox> 

Bạn sẽ cần một lớp view:

public class UserView 
{ 
    public string Id {get;set;} 
    public string Name {get;set;} 
    public int Score {get;set;} 
} 

trong mã của bạn đằng sau:

var usersList = new List<UserView>(); 

foreach (UserLeaderboards em in users) 
{ 
    int Fid = em.id; 
    string Fusername = em.username; 
    int Fscore = em.score; 
    usersList.Add(new UserView { Id = Fid, Name = Fusername, Score = Fscore}); 
} 

lstbLeaders.ItemsSource = usersList; 

ghi chú thêm:

  • Tại sao không ràng buộc ObservableCollection<UserLeaderboards> direcectly để hộp danh sách?

Nếu không có lý do gì để chuyển đổi sang một kiểu khác bỏ qua foreach một phần của mã và chỉ cần đặt lstbLeaders.ItemsSource = users;.

void webClient_OpenReadCompleted(object sender, OpenReadCompletedEventArgs e) 
{ 
    try 
    { 
     var ser = new DataContractJsonSerializer(
        typeof(ObservableCollection<UserLeaderboards>)); 

     var users = ser.ReadObject(e.Result) 
         as ObservableCollection<UserLeaderboards>; 

     lstbLeaders.ItemsSource = users; 
    } 
    catch (Exception ex) 
    { 
     MessageBox.Show(ex.Message); 
    } 
} 
  • Hãy nhìn vào mô hình MVVM. Nếu bạn muốn làm việc với XAML bạn nên biết về điều này. Nó đơn giản hóa công việc của bạn và tạo mã sạch hơn.

  • Nếu bạn muốn thêm chức năng chỉnh sửa hoặc dữ liệu có thể thay đổi, bạn có thể cần triển khai INotifyPropertyChanged trên lớp Chế độ xem.

  • Bạn có thể sử dụng suy luận kiểu đặc biệt hữu ích khi làm việc với tên lớp cồng kềnh. var list = new ObservableCollection<SomeLongTypeName>() lưu nhiều nội dung nhập và màn hình.

  • Hungary ký hiệu khiến tôi co rúm người lại;)

+0

không có lý do gì để tôi không liên kết trực tiếp với hộp danh sách, kiến ​​thức của tôi không cao về phía XAML của mọi thứ. Tôi đã chỉnh sửa dự án của mình với một người dùng lstbLeaders.ItemsSource = đơn giản; Giữ lớp userview theo bài viết của bạn. Tôi bây giờ chỉ nhận được 00 trên mỗi dòng. – Nathan

+0

XAML của bạn trông như thế nào? Kiểm tra (bằng cách sử dụng trình gỡ rối) nếu các giá trị bộ sưu tập được đặt hoặc nếu quá trình deserializing đưa ra lỗi. Tôi đã thêm một đoạn mã mới vào câu trả lời của tôi, điều chỉnh mã của bạn. XAML của bạn sẽ phải liên kết với các thuộc tính của lớp 'UserLeaderboards' ngay bây giờ:' id', 'username',' score'. – Zebi

+0

thats sắp xếp nó, nhờ sự giúp đỡ của bạn !! – Nathan

1

Tôi nghĩ bạn đã bỏ lỡ ItemTemplate. Hãy thử điều này

<ListBox Height="346" HorizontalAlignment="Left" Margin="5,221,0,0" Name="lstbLeaders"   VerticalAlignment="Top" Width="446"> 
    <ListBox.ItemTemplate> 
     <DataTemplate>         
      <TextBlock Text="{Binding Source=Fusername}" />      
     </DataTemplate> 
    </ListBox.ItemTemplate> 
</ListBox> 
+0

Tôi đã thêm các tab ItemTemplate và nó vẫn không hiển thị bất cứ điều gì. – Nathan

+0

Bạn cũng đã thử đặt ItemSource [lstbLeaders.Itemsource = List ()) trong Mã Phía sau? Có lẽ phông chữ giống như nền. :-) – kanchirk