使用列表框进行数据绑定

时间:2011-05-31 17:50:30

标签: c# xaml data-binding windows-phone-7 listbox

我有一些代码从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来尝试将变量绑定到textblocks。以下只是绑定用户名。我还有一个公共类来获取/设置所有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>

运行上面的内容时,我什么都没显示。我觉得这很简单吗?

感谢。

2 个答案:

答案 0 :(得分: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;

补充说明:

  • 为什么不直接将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>()可以节省大量打字和屏幕空间。

  • 匈牙利表示法让我感到畏缩;)

答案 1 :(得分: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>