2014-12-07 1 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로 반환하는 변환기도 있습니다. 이미지가 발견되지 않으면 (null 예외), 변환기는 컨택에 대한 기본 그림을 리턴합니다.

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

추가 정보는
이 앱은 윈도우 폰 8.1 WinRT 설정됩니다.
연락처를 받으려면 ContactStore를 사용합니다.

IReadOnlyList<Contact> contacts; //Global Declaration 

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

모든 연락처가 기본 연락처 이미지 반환
문제 (접촉 이미지를 얻을하려고 할 때 몇 가지 예외가 의미가 발생했습니다). 대다수의 내 연락처에 이미지가 연결되어 있기 때문에 이런 일이 발생하지 않아야합니다.

질문
어떻게 연락처의 이미지를 얻을 및 윈도우 폰 8.1의 ListView에 내 이미지 컨트롤에 그 바인딩해야합니까?

+0

입니다 (*** 나는 목록이 더 나은 선택이 될 것이라고 생각) ? 또한 코드를 동기 화하지 마십시오. [이 기사 (http://msdn.microsoft.com/en-us/magazine/dn605875.aspx), [this answer] (http://stackoverflow.com)를 더 잘 읽으십시오./a/26150727/2681948) 조금 도움이 될 수 있습니다. – Romasz

답변

1

감사합니다, 내 문제에 대한 해결책을 얻을 수있었습니다.

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 방법은 비동기입니다, 그래서 당신이 완료 결과를 기다릴 필요가 : Romasz 및 Murven에

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

System.InvalidOperationException을 받았습니다. '비동기 메서드에서 반환 된 작업과 같이 대리인에 바인딩되지 않은 작업에서는 RunSynchronously를 호출 할 수 없습니다.' – Tiago

+0

.RunSynchronously() 대신 .Wait()를 사용해보십시오. 내가 컴퓨터 앞에서 다시 문제를 재현하려고 노력할 것입니다. – Murven

-1

..

연락처 클래스에서 모든 이미지를 가져 와서 배열이나 스택 또는 BitmapImages 목록에 저장할 수 있습니다.당신은 하나의 이미지를 가져 오지 그냥 이미지의 소스로 설정 할 수 있습니까 여기 q

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

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