【问题标题】:How to get Json data into listview for windows phone 8?如何将 Json 数据放入 Windows Phone 8 的列表视图中?
【发布时间】:2013-11-18 07:13:32
【问题描述】:

我有 Json 链接,我需要将数据放入 listview。列表视图由图片、项目名称和价格组成。我正在使用 Newtonsoft.Json。我需要传递标头(用户名、密码、..),然后将 menuitem 链接调用到我的应用程序中以访问 menuitem 数据。我在这个列表视图中有很多项目要显示。下面我只给出一个关于 Json 数据的例子。请建议我任何好的信息,因为我是 json 新手。谢谢。

{"data":[{"Menuitemid":1,"Menucategoryid":1,"Itemname":"麻辣鸡翅","Description":"关于麻辣鸡翅","价格" :12.0,"图片":"http://www.ownboughtearned.com/demo/wp-content/uploads/2012/11/small_thumbnail.png","Thumbnail":null,"Active":true}]}

/

/Listbox binding in xaml

  <ListBox x:Name="lstItems" SelectionChanged="lstItems_SelectionChanged" CharacterSpacing="-1" >
                <ListBox.ItemTemplate>
                    <DataTemplate>
                        <Border BorderThickness="0,0,0,1.2" BorderBrush="Silver" 
                                HorizontalAlignment="Stretch" MinWidth="440">
                            <Grid Margin="0 10 0 10">
                                <Grid.RowDefinitions>
                                    <RowDefinition Height="Auto" />
                                    <!--<RowDefinition Height="*" />-->
                                </Grid.RowDefinitions>
                                <Grid.ColumnDefinitions>
                                    <ColumnDefinition Width="105" />
                                    <ColumnDefinition Width="*" />
                                    <ColumnDefinition Width="70" />
                                    <!--<ColumnDefinition Width="*" />-->
                                </Grid.ColumnDefinitions>
                                <StackPanel  Grid.Column="0" Grid.Row="0">
                                    <Border BorderBrush="Silver" CornerRadius="3" Height="97" 
                                            Width="97" Background="White">
                                        <Image Source="{Binding Path=Picture}" Stretch="Fill"
                                           Height="95" Width="95" />
                                    </Border>
                                </StackPanel>
                                <TextBlock Text="{Binding Path=Itemname}" MaxWidth="290" Margin="13 0 0 0" 
                                           FontSize="25" Foreground="#5b261e" TextWrapping="Wrap" TextTrimming="None" 
                                           Grid.Column="1" Grid.Row="0">

                                </TextBlock>
                                <TextBlock Margin="5" Text="{Binding Path=Price}" 
                                           FontSize="20" Foreground="#5b261e" Grid.Column="2" Grid.Row="1" VerticalAlignment="Center" />

                            </Grid>
                        </Border>
                    </DataTemplate>
                </ListBox.ItemTemplate>
            </ListBox>    

 //MenuRepository.cs
    namespace  MenuInfo.Concrete
{
    public class MenuRepository : IMenuRepository
    {
       public  List<MenuItem> listitems = new List<MenuItem>();
        public List<MenuItem> ListMenus()
        {          
            System.Uri targetUri = new System.Uri("http://xxxxxxxxxx.testshell.net/api/restaurant/menuitems/1");

             System.Net.HttpWebRequest httpWebRequest = (System.Net.HttpWebRequest)System.Net.WebRequest.Create(targetUri);
            httpWebRequest.Method = "GET";
            httpWebRequest.Accept = "application/json";
            httpWebRequest.Headers["username"] = "info@xxxxxxxxxx.com";
            httpWebRequest.Headers["password"] = "xxxxxxxxxxxxxxxxxxxxxxxx";


            httpWebRequest.BeginGetResponse(OnGetResponseCompleted, httpWebRequest);     


            return listitems;
        }
        private async void  OnGetResponseCompleted(IAsyncResult ar)
        {
            try
            {
                var httpWebRequest = (HttpWebRequest)ar.AsyncState;

                var response = httpWebRequest.EndGetResponse(ar);           

                var jsonSerializer = new DataContractJsonSerializer(typeof(MenuItemObject));
                var responseObject = (MenuItemObject)jsonSerializer.ReadObject(response.GetResponseStream());         

                foreach (MenuItem loc in responseObject.data)
                {

                    listitems.Add(loc);

                }

            }
            catch (Exception ex)
            {

            }
        }     

    }
}

【问题讨论】:

  • 如果您确实使用 Newtonsoft.Json,您知道该怎么做吗?我只是能够使用 NuGet 将它添加到一个新的 WP8 项目中。如果遇到问题,您可能需要升级 NuGet 安装程序。
  • 工具 -> 扩展和更新
  • @SeeSharp 宾果游戏!我更新了 NuGet 安装程序。工具 -> 扩展和更新 -> 更新。谢谢你看到夏普。
  • @madhukumar 你能显示你的项目模板吗
  • @madhukumar 你在使用 List 还是 Observable COllection

标签: c# json windows-phone-7 windows-phone-8


【解决方案1】:

您的问题源于您从 ListMenus 方法返回一个空集合。该方法将在它有机会在OnGetResponseCompleted 回调中填充集合之前返回。您可以通过以下两种方式之一解决此问题。第一个是将listitems 变量更改为 ObservableCollection。

public  ICollection<MenuItem> listitems = new ObservableCollection<MenuItem>();

使用这种方法,您将继续返回一个空集合,但是当您在 OnGetResponseCompleted 方法中向其中添加项目时,它会通知 ListBox 添加了一个项目(前提是您将 ITemsSource 设置为ListMenus 方法。这样做会对性能产生负面影响。对于您添加的每个项目,它会通知 UI 进行更新,而不是对所有项目进行一次大更新。它也可能会抛出您正在尝试的异常当不在 UI 线程上时更新 UI 组件。回调 OnGetResponseCompleted 可能在单独的线程上。

另一种更好的方法是使用 async/await 模式返回结果。您可以使用新的 HttpClient 类来执行此操作,但如果您喜欢使用 WebRequest,您仍然可以使用 TaskCompletionSource 来完成此操作。

public Task<IList<MenuItem>> ListMenus()
{
    var completion = new TaskCompletionSource<IList<MenuItem>>();
    System.Uri targetUri = new System.Uri("http://xxxxxxxxxx.testshell.net/api/restaurant/menuitems/1");

    System.Net.HttpWebRequest httpWebRequest = (System.Net.HttpWebRequest)System.Net.WebRequest.Create(targetUri);
    httpWebRequest.Method = "GET";
    httpWebRequest.Accept = "application/json";
    httpWebRequest.Headers["username"] = "info@xxxxxxxxxx.com";
    httpWebRequest.Headers["password"] = "xxxxxxxxxxxxxxxxxxxxxxxx";

    httpWebRequest.BeginGetResponse(ar =>
        {
            try
            {
                using (var response = httpWebRequest.EndGetResponse(ar))
                {
                    using (var reader = new StreamReader(response.GetResponseStream()))
                    {
                        var responseObject =
                            Newtonsoft.Json.JsonConvert.DeserializeObject<MenuItemObject>(reader.ReadToEnd());
                        foreach (MenuItem loc in responseObject.data)
                        {
                            listitems.Add(loc);
                        }
                    }
                }
            }

            catch (Exception ex)
            {

            }
            completion.SetResult(listitems);
        }, null);


    return completion.Task;
}

使用这种方法,您将等待 ListMenus 的结果并从中设置 ItemsSource。

lstItems.ItemsSource = await ListMenus();

现在您可以得到填充的结果,并且不会因为一次添加一项而对性能产生影响。

【讨论】:

    猜你喜欢
    • 2011-02-13
    • 1970-01-01
    • 1970-01-01
    • 2021-01-17
    • 1970-01-01
    • 1970-01-01
    • 2015-05-01
    • 2013-07-27
    • 2013-07-30
    相关资源
    最近更新 更多