2014-12-07 4 views
1

Информация
Проще говоря, я пытаюсь создать приложение, отображающее контакты для пользователя.WP8.1 C# Binding Contact Image

Я тоже программист-самоучка, поэтому у меня есть опыт программирования в некоторых аспектах, но я относительно новичок в привязке данных в целом.

Для начала у меня есть элемент управления 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; 

Проблема
Каждый контакт возвращается контакт образа по умолчанию (это означает некоторое исключение произошло при попытке получить изображение контакта). Это не должно происходить, поскольку у большинства моих контактов есть связанные с ними изображения.

Вопрос
Как я должен получить изображение контакта и связать, что графический элемент управления внутри ListView для Windows Phone 8.1?

+0

способны retrive одно изображения и просто установить его в качестве источника изображения Вы ? Также не делайте ваш код синхронным - лучше прочитайте [эту статью] (http://msdn.microsoft.com/en-us/magazine/dn605875.aspx), также [этот ответ] (http://stackoverflow.com/a/26150727/2681948) может немного помочь. – Romasz

ответ

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(); 
    } 
} 

Пакеты:
Nito.AsyncEx из NuGet

0

Проблема заключается в том, что метод GetImage является асинхронным, так что вам нужно ждать результата выполнения:

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

Я получил System.InvalidOperationException. «RunSynchronously не может быть вызван задачей, не связанной с делегатом, такой как задача, возвращаемая асинхронным методом». – Tiago

+0

Попробуйте использовать .Wait() вместо.RunSynchronously(). Я попытаюсь воспроизвести проблему, когда снова буду перед компьютером. – Murven

-1

вы можете сделать одну вещь ..

вы можете получить все изображения из класса контактов и сохранить их в массиве или стеке или в списке битмапов.(*** я думаю, что список будет представлять собой лучший вариант)

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

здесь q является list 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; 
    }