2014-12-07 65 views
1

信息
很簡單,我試圖創建一個應用程序,將顯示用戶的聯繫人。WP8.1 C#綁定聯繫人圖片

我也是一個自學成才的程序員,所以我在某些方面有編程經驗,但是我對數據綁定一般來說比較新。

首先,我有一個ListView控件,它有一個圖像綁定。

<ListView x:Name="ContactsView" ItemsSource="{Binding}"> 
    <ListView.ItemTemplate> 
     <DataTemplate> 
      <Image x:Name="ContactImage" Source="{Binding Converter={StaticResource ContactPictureConverter}, Mode=OneWay}" Height="100" Width="100" Margin="0,0,0,0"/> 
     </DataTemplate> 
    </ListView.ItemTemplate> 
</ListView> 

我也有一個轉換器,獲取聯繫人圖像的IRandomAccessStream並將其作爲BitmapImage返回。如果找不到圖像(空例外),則轉換器將返回聯繫人的默認圖片。

public class ContactPictureConverter : IValueConverter 
{ 
    public object Convert(object value, Type targetType, object parameter, string culture) 
    { 
     Contact c = value as Contact; 

     try 
     { 
      return GetImage(c).Result; 
     } 
     catch (Exception ex) 
     { 
      Debug.WriteLine(ex.Message); 
     } 
     return @"Images/default.jpg"; 
    } 

    async Task<BitmapImage> GetImage(Contact con) 
    { 
     BitmapImage bitmapImage = new BitmapImage(); 
     bitmapImage.DecodePixelHeight = 100; 
     bitmapImage.DecodePixelWidth = 100; 
     using (IRandomAccessStream fileStream = await con.Thumbnail.OpenReadAsync()) 
     { 
      await bitmapImage.SetSourceAsync(fileStream); 
     } 
     return bitmapImage; 
    } 

    public object ConvertBack(object value, Type targetType, object parameter, string culture) 
    { 
     throw new NotImplementedException(); 
    } 
} 

其他信息
的應用程序設置爲Windows Phone的8.1 ​​WinRT的。
爲了獲得聯繫人,我使用了一個ContactStore。

IReadOnlyList<Contact> contacts; //Global Declaration 

ContactStore store = await ContactManager.RequestStoreAsync(); 
contacts = await store.FindContactsAsync(); 
ContactsView.ItemsSource = contacts; 

問題
每個接觸返回默認聯繫人圖像(意味着一些異常時,試圖獲得接觸式圖像發生)。這不應該發生,因爲我的大部分聯繫人都有與他們相關的圖像。

問題
我應該如何得到聯繫人的圖像,並結合,爲Windows Phone的8.1一個ListView內的圖像控制?

+0

您能夠以檢索單個圖像,只是把它作爲一個圖像的源?也不要讓你的代碼同步 - 更好地閱讀[本文](http://msdn.microsoft.com/en-us/magazine/dn605875.aspx),也[此答案](http://stackoverflow.com/a/26150727/2681948)可能會有所幫助。 – Romasz 2014-12-07 10:26:37

回答

1

感謝Romasz和Murven,我能得到我的問題的解決方案。

XAML:

<ListView x:Name="ContactsView" Grid.Row="1" Background="White" ItemsSource="{Binding}"> 
    <ListView.ItemTemplate> 
     <DataTemplate> 
      <Image x:Name="ContactImage" DataContext="{Binding Converter={StaticResource ContactPictureConverter}}" Source="{Binding Result}" Height="100" Width="100" Margin="0,0,0,0"/> 
     </DataTemplate> 
    </ListView.ItemTemplate> 
</ListView> 

轉換器:

using Nito.AsyncEx; 

public class ContactPictureConverter : IValueConverter 
{ 
    public object Convert(object value, Type targetType, object parameter, string language) 
    { 
     try 
     { 
      Contact c = value as Contact; 
      return NotifyTaskCompletion.Create<BitmapImage>(GetImage(c)); 
     } 
     catch (Exception ex) 
     { 
      Debug.WriteLine(ex.Message); 
      return null; 
     } 
    } 

    private async Task<BitmapImage> GetImage(Contact con) 
    { 
     using (var stream = await con.Thumbnail.OpenReadAsync()) 
     { 
      BitmapImage image = new BitmapImage(); 
      image.DecodePixelHeight = 100; 
      image.DecodePixelWidth = 100; 

      image.SetSource(stream); 
      return image; 
     } 
    } 

    public object ConvertBack(object value, Type targetType, object parameter, string culture) 
    { 
     throw new NotImplementedException(); 
    } 
} 

套餐:
從的NuGet

Nito.AsyncEx
0

的問題是,該方法的getImage是異步的,所以你需要等待結果完成:

 Task<BitmapImage> getImageTask = GetImage(c); 
     getImageTask.RunSynchronously(); 
     return getImageTask.Result; 
+0

我收到一個System.InvalidOperationException。 '對於未綁定到委託的任務,例如從異步方法返回的任務,可能不會調用RunSynchronously。 – Tiago 2014-12-07 07:43:13

+0

嘗試使用.Wait()而不是.RunSynchronously()。當我再次在電腦前時,我會嘗試重現這個問題。 – Murven 2014-12-07 19:10:13

-1

你可以做一件事..

您可以從聯繫人類中檢索所有圖像,並將它們存儲在數組或堆棧或BitmapImages列表中。(***我覺得清單將是一個更好的選擇)

Contact c = value as Contact; foreach(var p in c) { q.Add(p.Thumbnail); }

這裏qlist of bitmapmages

1
public static BitmapImage GetImage(Contact con) 
    { 
     if (con == null || con.Thumbnail == null) 
     { 
      return null; 
     } 

     var bitmapImage = new BitmapImage(); 
     bitmapImage.DecodePixelHeight = 256; 
     bitmapImage.DecodePixelWidth = 256; 


     Action load = async() => 
     { 
      using (IRandomAccessStream fileStream = await con.Thumbnail.OpenReadAsync()) 
      { 
       await bitmapImage.SetSourceAsync(fileStream); 
      } 
     }; 

     load(); 

     return bitmapImage; 
    } 
相關問題