2014-12-07 73 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; 
    }