2011-05-31 84 views
5

我有一些代码从HTTP服务器读取json响应,然后解析并将数据插入到ListBox控件中。使用列表框的数据绑定

我关火下载完成后,该事件是:

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

现在,当我做items.add我相信它只是加入了3个变量,并在ListBox它添加到一列。这工作正常,我看到所有3个项目加入并显示。

我想分开这个,让它看起来更漂亮一点,所以我创建了一些XAML尝试将变量绑定到文本块。以下是绑定用户名。我也有一个公共类,可以获取/设置所有3个变量。

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

当运行上述我什么也没有显示。我有一种感觉,这很简单?

谢谢。

回答

5

要显示一个简单的字符串你的XAML应该是这样的:

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

,你必须提供一个对象,而不是一个简单的字符串,如果你要拆分的属性,使它看起来更好。如果您只是添加Fid + Fusername + Fscore,您将最终得到一个纯字符串。

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

您将需要一个视图类:

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

在后面的代码:

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; 

其它注意事项:

  • 为什么不direcectly绑定ObservableCollection<UserLeaderboards>到列表框?

如果没有理由要转换为其他类型的跳跃代码的foreach一部分,只需设置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); 
    } 
} 
  • 采取看看MVVM模式。如果你想使用XAML,你应该知道这一点。它简化了您的工作并创建了更清晰的代码。

  • 如果您想添加编辑功能或数据可以改变,您可能需要在View类上实现INotifyPropertyChanged

  • 您可以使用类型推断,这在使用繁琐的类名称时特别有用。 var list = new ObservableCollection<SomeLongTypeName>()节省了很多打字和屏幕资源。

  • 匈牙利命名法令我生厌;)

+0

我没有理由不直接绑定到列表框,我的知识不是很高的XAML方面的东西。我用一个简单的lstbLeaders.ItemsSource = users编辑了我的项目;根据你的文章保留userview类。我现在每条线都只有00。 – Nathan 2011-05-31 20:03:25

+0

你的XAML是什么样的?检查(使用调试器)集合值是否已设置,或者反序列化是否引入错误。我添加了一个新的代码片段来适应您的代码。你的XAML将不得不绑定到UserLeaderboard类的属性:'id','username','score'。 – Zebi 2011-05-31 20:37:29

+0

这是谁排序,感谢您的帮助! – Nathan 2011-05-31 22:04:06

1

我想你错过了ItemTemplate。 试试这个

<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

我已经添加了的ItemTemplate标签,它仍然没有显示任何内容。 – Nathan 2011-05-31 19:11:38

+0

您是否也尝试在Code Behind中设置ItemSource [lstbLeaders.Itemsource = List ())?也许字体与背景相同。 :-) – kanchirk 2011-05-31 19:16:18