2016-04-26 77 views
1

我正在開發Windows應用商店應用的銷售應用。我想爲我的產品模塊應用延遲加載。如何將延遲加載應用到Windows Store應用程序中的ListView?

當產品頁面打開時,它從後端獲取產品並顯示在ListBox控件中。 每次加載都需要時間。我認爲主要原因是當我檢查給定的網址上存在的圖像。

這裏是我的代碼和類:

private async Task getAllProductDetails() 
{ 
    var resultproductlist = await client.PostAsync(session.Values["URL"] + "/magemobpos/product/getProductList", contents); 
    if (resultproductlist.IsSuccessStatusCode) 
    { 
     string trys = resultproductlist.Content.ReadAsStringAsync().Result; 
     List<Productlistdata> objProducts = JsonConvert.DeserializeObject<ProductlistResponse>(trys).productlistdata; 
     Productlistdata Product; 

     //all product are in objProducts 
     foreach (var item in objProducts) 
     { 
      bool imageexist = false; 
      //check if image exist on given url or not 
      try 
      { 
       HttpWebRequest request = (HttpWebRequest)WebRequest.Create(new Uri(item.image.ToString())); 
       using (var response = (HttpWebResponse)(await Task<WebResponse>.Factory.FromAsync(request.BeginGetResponse, request.EndGetResponse, null))) 
       { 

        int imagelength = Convert.ToInt32(response.ContentLength); 
        if (imagelength > 0) 
         imageexist = true; 
        else 
         imageexist = false; 
       } 
      } 
      catch (Exception) 
      { 
       imageexist = false; 
      } 

      //if image not exist, it get default image 
      if (item.image.ToString().ToLower().Equals("n/a") || imageexist == false) 
      { 
       item.image = "Images/NoDataImages/ico-no-orders.png"; 
      } 

      Product = new Productlistdata() 
      { 
       image = item.image, 
       name = item.name, 
       price = item.price, 
       sku = item.sku, 
       type = item.type[0], 
       id = item.id 
      }; 
      //add all product in lstProduct. lstProduct is ListBox Control 
      lstProduct.Items.Add(Product);  
     } 
    } 
} 

類:

public class Productlistdata 
{ 
    public string id { get; set; } 
    public string sku { get; set; } 
    public string name { get; set; } 
    public string status { get; set; } 
    public string qty { get; set; } 
    public string price { get; set; } 
    public string image { get; set; } 
    public string type { get; set; } 
    public string full_productname { get; set; } 
} 

可有人建議我如何申請延遲加載?我不完全知道,但我認爲它可以應用於列表加載後綁定圖像。

+0

我還沒有在windowsRT或UWP應用程序上工作,但是兩者都基於WPF/Silverlight並且默認情況下會進行延遲加載,在這種情況下問題在於你的模型 – MikeT

+0

@MikeT它不是WPF或Silverlight應用程序。這是Windows Store應用程序。你能否在我的代碼中建議我改變模型並調用'imageexist'? –

+0

Windows Store應用程序使用windowsRT或UWP,具體取決於它們是基於Windows 8還是基於Windows 10,並且它們都使用WPF和Silverlight的變體。我的觀點是,雖然我還沒有具體的知識,你正在使用的變化,但我可以提供一般信息,將希望海爾 – MikeT

回答

0

我知道你不力要求它,但我會強烈建議你看看Bindings我相信它會幫助你很多想你想要建立的東西。所以我將開始通過使用綁定來更改一些代碼,然後轉到真正的解決方案。

這裏是你可以嘗試這樣做:

首先刪除此代碼:

bool imageexist = false; 
     //check if image exist on given url or not 
     try 
     { 
      HttpWebRequest request = (HttpWebRequest)WebRequest.Create(new Uri(item.image.ToString())); 
      using (var response = (HttpWebResponse)(await Task<WebResponse>.Factory.FromAsync(request.BeginGetResponse, request.EndGetResponse, null))) 
      { 

       int imagelength = Convert.ToInt32(response.ContentLength); 
       if (imagelength > 0) 
        imageexist = true; 
       else 
        imageexist = false; 
      } 
     } 
     catch (Exception) 
     { 
      imageexist = false; 
     } 

第二步是擺脫這種代碼

//add all product in lstProduct. lstProduct is ListBox Control 
lstProduct.Items.Add(Product); 

的現在加上頂部你page.xaml。CS一個ObservableCollection

private ObservableCollection<Productlistdata> productlist = new ObservableCollection<Productlistdata>(); 

    public ObservableCollection<Productlistdata> Productlist 
    { 
     get { return productlist ?? (productlist= new ObservableCollection<Productlistdata>()); } 
     set { productlist= value; } 
    } 

現在你要麼綁定該列表在列表框中這樣

<ListBox ItemsSource="{Binding Productlist}"/> 

或在網頁的承包商做

lstProduct.ItemsSource = Productlist; 

這樣產品列表被綁定到你的列表框,當你添加或刪除項目將自動更新。

現在,您可以跳過上述所有內容,但我建議您查看Bindings它強大的功能,並在您瞭解其工作原理時解決您的許多問題。

現在,我們將增加我們去掉了第一個代碼在你ProductListdata

public class Productlistdata 
{ 
    public string id { get; set; } 
    public string sku { get; set; } 
    public string name { get; set; } 
    public string status { get; set; } 
    public string qty { get; set; } 
    public string price { get; set; } 
    public string image { get; set; } 
    public string type { get; set; } 
    public string full_productname { get; set; } 

    public async void CheckImage() 
    { 
     bool imageexist = false; 
     try 
     { 
      HttpWebRequest request = (HttpWebRequest)WebRequest.Create(new Uri(image)); 
      using (var response = (HttpWebResponse)(await Task<WebResponse>.Factory.FromAsync(request.BeginGetResponse, request.EndGetResponse, null))) 
      { 

       int imagelength = Convert.ToInt32(response.ContentLength); 
       if (imagelength > 0) 
        imageexist = true; 
       else 
        imageexist = false; 
      } 
     } 
     catch (Exception) 
     { 
      imageexist = false; 
     } 
     if (!imageexist) 
     { 
      image = "Images/NoDataImages/ico-no-orders.png"; 
     } 
    } 
} 

並填充列表

private async Task getAllProductDetails() 
    { 
     var resultproductlist = await client.PostAsync(session.Values["URL"] + "/magemobpos/product/getProductList", contents); 
     if (resultproductlist.IsSuccessStatusCode) 
     { 
      string trys = resultproductlist.Content.ReadAsStringAsync().Result; 
      List<Productlistdata> objProducts = JsonConvert.DeserializeObject<ProductlistResponse>(trys).productlistdata; 


      //all product are in objProducts 
      foreach (var item in objProducts) 
      { 
       Productlistdata Product = new Productlistdata() 
       { 
        image = item.image, 
        name = item.name, 
        price = item.price, 
        sku = item.sku, 
        type = item.type[0], 
        id = item.id 
       }; 
       Product.CheckImage(); 
       Productlist.Add(Product); 
      } 
     } 
    } 

Product.CheckImage();不會等待。所以列表中的Items將會加載得非常快,因爲在foreach循環中沒有任何東西在等待。 Product.CheckImage();將在稍後的時間在另一個線程上運行。

最後,因爲圖像可能會在ListBoxa上加載數據後發生變化(當圖像未達到時),您將不得不通知UI屬性已更改。要做到這一點,你將不得不使用INotifyPropertyChanged。你可以看看我的其他答案如何做到這一點here

+0

Stamos,它工作的快速以後不會更改圖像。 –

+0

@NinjiMange在我的答案中閱讀了最後一段。這就是爲什麼我強烈建議你使用綁定與'INotifyPropertChanged' – Stamos

0

我建議改變你的查詢,

的首先不是getAllProductDetails做getAllProductID 所以,你必須

 var resultproductlist = await client.PostAsync(session.Values["URL"] + "/magemobpos/product/getProductList", contents); 
     if (resultproductlist.IsSuccessStatusCode) 
     { 
      string trys = resultproductlist.Content.ReadAsStringAsync().Result; 
      List<Productlistdata> objProducts = JsonConvert.DeserializeObject<ProductlistResponse>(trys).productlistdata; 
      Productlistdata Product; 

你會做

 var resultproductlist = await client.PostAsync(session.Values["URL"] + "/magemobpos/product/getProductID", contents); 
     if (resultproductlist.IsSuccessStatusCode) 
     { 
      string trys = resultproductlist.Content.ReadAsStringAsync().Result; 
      List<int> objProducts = JsonConvert.DeserializeObject<ProductlistResponse>(trys).productlistdata; 
      LazyProductlistdata Product; 

其次創建一個包裝

public LazyProductlistdata 
{ 
    public string id { get; set; } 
    private Lazy<Productlistdata> data = new Lazy<Productlistdata>(()=>Productlistdata.CreateFromID(id)); 
    public Productlistdata Data 
    { 
     get{return data.Value;} 
    } 
} 

擴大這一所以包裝包含排序

終於改變構造或創建Productlistdata工廠,使其從源頭獲取單個記錄

public class Productlistdata 
{ 
    public static Productlistdata CreateFromID(int id) 
    { 
     //Return single Productlistdata from webservice 
    } 
} 

注所需的信息:延遲加載將增加整體加載時間,優點是,而不是它是一個巨大的時間塊其幾個較小的一個

+0

您能否建議我更改getAllProductID()和getAllProductDetails()的調用流程? –

+0

很難準確,因爲大部分更改都在您沒有提供的網絡服務中 – MikeT

+0

嗯,我剛剛收到呼叫清單。我只能提供參數和調用結果。讓我試試你的方法。 –

0

我會建議使用轉換器提供佔位符see here

您也可以裝飾Image.Source與IsAsync =真正的結合 - 讓主線程不會被阻塞

0

您可以使用ImageFailed事件來分配圖像佔位符

foreach (var item in objProducts) 
{ 
var bitmap = new BitmapImage(); 
bitmap.ImageFailed += (s, e) => bitmap.UriSource = defaultImageUri; 
bitmap.UriSource = new Uri(item.image); 
item.Add(bitmap); 
//set decodepixelwidth and dicodepixelheight correctly to avoid outofmemory exception 
} 
相關問題