【问题标题】:Databinding with a listbox使用列表框进行数据绑定
【发布时间】:2011-09-05 16:41:30
【问题描述】:

我有一段代码可以从 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>

运行上面的代码时,我什么也没有显示。我觉得这很简单?

谢谢。

【问题讨论】:

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


    【解决方案1】:

    要显示一个简单的字符串,您的 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&lt;UserLeaderboards&gt;绑定到列表框?

    如果没有理由转换为其他类型,请跳过代码中的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&lt;SomeLongTypeName&gt;() 节省了大量打字和屏幕空间。

    • 匈牙利符号让我畏缩;)

    【讨论】:

    • 我没有理由不直接绑定到列表框,我对 XAML 方面的知识不是很高。我用一个简单的 lstbLeaders.ItemsSource = users; 编辑了我的项目。根据您的帖子保留用户视图类。我现在每行只得到 00。
    • 您的 XAML 是什么样的?检查(使用调试器)是否设置了集合值或反序列化是否引入了错误。我在调整您的代码的答案中添加了一个新代码 sn-p。您的 XAML 现在必须绑定到 UserLeaderboards 类的属性:idusernamescore
    【解决方案2】:

    我认为您错过了 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> 
    

    【讨论】:

    • 我添加了 itemTemplate 选项卡,但它仍然没有显示任何内容。
    • 您是否也尝试在 Code Behind 中设置 ItemSource [lstbLeaders.Itemsource = List()) ?也许字体与背景相同。 :-)
    猜你喜欢
    • 2016-11-14
    • 2011-01-28
    • 1970-01-01
    • 2016-11-12
    • 2012-10-26
    • 2010-10-23
    • 2012-10-12
    • 2010-11-24
    • 1970-01-01
    相关资源
    最近更新 更多