2013-03-24 20 views
7

ListView'de bazı görüntüleri görüntülemeye çalışıyorum ve başarılı olamadım. WPF MVVM kullanıyorum ve ListView sadece takım elbise ve rütbe verilerinin gösterilmesinden sorumlu. (İlginizi çekiyorsa, bir önceki yazıma bakın: MVVM in WPF - How to alert ViewModel of changes in Model... or should I?) Yani, ListView'den başka bir şey kullanabilirim (eğer bu bir tavsiyedir) ama yine de, bunu yapılabilir olduğunu farz edersek, ListView ile nasıl yapılacağını bilmek isterim. Ben ViewModel bağlanarak ediyorum Benim özelliktir: my XAML kodundaWPF MVVM'de Görüntü Verme (veya daha iyisi!) 'Daki ​​Görüntülerin Görüntülenmesi

public ObservableCollection<Image> PlayerCardImages{ 
    get{ 
     ObservableCollection<Image> results = new ObservableCollection<Image>(); 
     foreach (CardModel card in PlayerCards) 
     { 
      Image img = new Image(); 
      BitmapImage bi3 = new BitmapImage(); 
      bi3.BeginInit(); 
      // TODO: Pick card based on suit/rank. Just get 1 image working now 
      bi3.UriSource = new Uri("diamond-1.png", UriKind.Relative); 
      bi3.EndInit(); 
      img.Stretch = Stretch.Fill; 
      img.Source = bi3;    
      results.Add(img); 
     } 
     return results; 
    } 
} 

kullanıyorum:

<Window.Resources> 
<DataTemplate x:Key="ImageCell"> 
     <StackPanel Orientation="Horizontal"> 
      <Image Source="{Binding PlayerCardImages}" Width="200" Height="200" Stretch="Fill" ToolTip="Add tooltip"/> 
     </StackPanel> 
    </DataTemplate> 
</Window.Resources> 

<StackPanel Orientation="Vertical"> 
<Label Content="Player Cards"/> 
     <ListView Name="lvwTitles" ItemsSource="{Binding}" 
IsSynchronizedWithCurrentItem="True" 
SelectionMode="Single" ItemTemplate="{StaticResource ImageCell}" Height="59"> 
     </ListView> 
    </StackPanel> 

Bu fikir utanmadan çalındı: Ancak WPF - bind images horizontally to ListView, bu kokan t PlayerCardImages’da vurulmamamdaki kırılma noktamın kanıtladığı gibi bile görünüyor. Benim kesme noktası programın başında isabet ve ürün koleksiyonuna eklenir zaman -

bu kod kesinlikle veri bağlama geçer
<StackPanel Orientation="Vertical"> 
     <Label Content="Player Cards"/> 
     <ListView 

     AlternationCount="2" 
     DataContext="{StaticResource PlayerCardsGroups }" 
     ItemsSource="{Binding}" 
     > 
      <ListView.GroupStyle> 
       <StaticResourceExtension 
       ResourceKey="CardGroupStyle" 
       /> 
      </ListView.GroupStyle> 
      <ListView.View> 
       <GridView> 
        <GridViewColumn> 
       <Image Height="50" Width="40"></Image> 
        </GridViewColumn> 
       </GridView>     
      </ListView.View> 
     </ListView> 
    </StackPanel> 
    <Window.Resources> 
    <CollectionViewSource x:Key="PlayerCardsGroups" 
     Source="{Binding Path=PlayerCardImages}"> 
    </CollectionViewSource> 

    <GroupStyle x:Key="CardGroupStyle"> 
     <GroupStyle.HeaderTemplate> 
      <DataTemplate> 
       <TextBlock 
     x:Name="txt" 
     Background="{StaticResource Brush_HeaderBackground}" 
     FontWeight="Bold" 
     Foreground="White" 
     Margin="1" 
     Padding="4,2,0,2" 
     Text="Cards" 
     /> 
      </DataTemplate> 
     </GroupStyle.HeaderTemplate> 
    </GroupStyle> 

    <Style x:Key="CardItemStyle" TargetType="{x:Type ListViewItem}"> 
     <!-- 
    Stretch the content of each cell so that we can 
    right-align text in the Total Sales column. 
    --> 
     <Setter Property="HorizontalContentAlignment" Value="Stretch" /> 
     <!-- 
    Bind the IsSelected property of a ListViewItem to the 
    IsSelected property of a CustomerViewModel object. 
    --> 
     <Style.Triggers> 
      <MultiTrigger> 
       <MultiTrigger.Conditions> 
        <Condition Property="ItemsControl.AlternationIndex" Value="1" /> 
        <Condition Property="IsSelected" Value="False" /> 
        <Condition Property="IsMouseOver" Value="False" /> 
       </MultiTrigger.Conditions> 
       <Setter Property="Background" Value="#EEEEEEEE" /> 
      </MultiTrigger> 
     </Style.Triggers> 
    </Style> 

    </Window.Resources> 

:

Ben de biraz daha iyi şans ile aşağıdaki XAML çalıştı. Ancak görüntü yok. İşe yaramayan daha fazla XAML ile işkence yapmak yerine, belki de birisinin bir ListView listesine nasıl bir liste eklemesi gerektiğini gösteren bir kod/örnekler/dokümana yönlendirmesini isteyebilirim (veya gerçekten ListView'in olduğunu düşünüyorsanız başka bir kontrol). uygunsuz). Koleksiyonumun bağlayıcı olduğum şeyler olduğuna dikkat edin. Birçok örnekle, bir alt mülkiyete bağlandıklarını fark ettim. Yani Bir albüm koleksiyonuna sahip olabilirler ve her albüm için mülkiyet görüntüsüne bağlanırlar (bkz .: Showing items as images in a WPF ListView).

Herhangi bir fikir veya yardım çok takdir edilecektir.

-Dave

Ek bilgiler.

Clemens tarafından önerilere dayalı, şimdi PlayerCardImages için bu kodu vardır:

public ObservableCollection<ImageSource> PlayerCardImages 
    { 
     get 
     { 
      var results = new ObservableCollection<ImageSource>(); 

      //if (PlayerCards.Count == 0) 
      // return results; 
      //else 
      //{ 
      // results.Add(new BitmapImage(new Uri(@"Images\\" + "diamond-1.png", UriKind.Relative))); 
      //} 
      foreach (var card in PlayerCards) 
      { 
       results.Add(new BitmapImage(new Uri(@"Images\\" + GetCardFileName(card), UriKind.Relative))); 

      } 
      return results; 

     } 

onun tavsiyesine kesin XAML kullandı. Neredeyse işe yarıyor. "Hemen hemen" diyorum çünkü bazen 1 kartın bazen de bazen 2 kart gösterebileceği garip davranışları fark ettim. Dosyalardan ve kartlardan gelen tüm kartlar çalışıyor gibi görünüyor ve son kalan hatanın (ve BIZARRE'nin) anahtarı olduğunu düşündüğüm şeyi takip ettim. Hata ayıklayıcıda sonuçları inceler ve hata ayıklayıcıda sonuçları [0] daha açarsanız, bu kartın görüntülendiğini görüyorum! Aslında çalışmak için [0] (yükseklik, genişlik vb. Hakkında bilgi görüyorsunuz). Ayrıca, [1] 'i açarsam, bu kartın yerine görüntülenmesini sağlarım. Hata ayıklayıcı bilgisini açmanın neden bir etkisi var? Sorulabilecek olanlar için, hata ayıklayıcısında iki kart açıyorsanız, bu işe yaramaz. Bir operasyon zaman aşımına uğradı istisna. Belki de görüntü dosyalarımın büyük olduğunu söyleyeceğim. 10Kbytes - 30 Kbyte. Sorun bu mu? Tahmin edemiyorum ve bu resimlerde ya da ciltlemede okumakta ince bir problem. Ne oluyor? Teşekkürler, Dave

cevap

10

Öncelikle, ViewModel Görüntü kontrollerini kullanmamalısınız: İkinci bloğunda

<Image Source="{Binding}" ... /> 
<ListView Name="lvwTitles" ItemsSource="{Binding PlayerCardImages}" ... /> 

, tümüyle bağlayıcı Kaynak atlanmış. Görüntülemenizin DateTemplate sayfasında zaten bir Görüntü denetimi var. Bu Görüntü denetiminin Source özelliğini bağlamak istiyorsunuz ve bu bağlamanın kaynak özelliği başka bir Resim olamaz.

Bunun yerine ViewModel, ya bu gibi görüntü türü olarak ImageSource (veya BitmapImage gibi türetilmiş bir sınıf) kullanmak:

public ObservableCollection<ImageSource> PlayerCardImages 
{ 
    get 
    { 
     var results = new ObservableCollection<ImageSource>(); 
     foreach (var card in PlayerCards) 
     { 
      results.Add(new BitmapImage(new Uri(card.ImageUrl))); 
     } 
     return results; 
    } 
} 

veya görüntü URI veya yollar, string otomatik bir dönüşüm orada olduğu gibi

public ObservableCollection<string> PlayerCardImages 
{ 
    get 
    { 
     var results = new ObservableCollection<string>(); 
     foreach (var card in PlayerCards) 
     { 
      results.Add(card.ImageUrl); 
     } 
     return results; 
    } 
} 

artık PlayerCardGames koleksiyona listbox en ItemsSource özelliği bağlamak istiyorum ve DataTemplate Bağlayıcı: ImageSource WPF yerleşik doğrudan koleksiyon öğesine. ListView'ın DataContext öğesinin, PlayerCardGames özelliğini tanımlayan nesnenin bir örneğine ayarlanması gerekir.

<ListView ItemsSource="{Binding PlayerCardGames}"> 
    <ListView.ItemTemplate> 
     <DataTemplate> 
      <StackPanel> 
       <Image Source="{Binding}" /> 
      </StackPanel> 
     </DataTemplate> 
    </ListView.ItemTemplate> 
</ListView> 

GÜNCELLEME: görüntü dosyaları yükleme ile ilgili bir sorun var gibi görünüyor gibi, aşağıdaki yöntemi deneyebilirsiniz. Görüntüleri eşzamanlı olarak yükler ve hata ayıklayıcısını kullanarak ilerleyebilirsiniz.

public static ImageSource LoadImage(string fileName) 
{ 
    var image = new BitmapImage(); 

    using (var stream = new FileStream(fileName, FileMode.Open)) 
    { 
     image.BeginInit(); 
     image.CacheOption = BitmapCacheOption.OnLoad; 
     image.StreamSource = stream; 
     image.EndInit(); 
    } 

    return image; 
} 

Böyle senin PlayerCardGames mülkiyet toplamamaddesi bu yöntemi kullanabilirsiniz:

foreach (var card in PlayerCards) 
{ 
    results.Add(LoadImage(@"Images\\" + GetCardFileName(card))); 
} 
+0

Clemens, yanıt için çok teşekkür ederim. Önerilerinizi uygulayıp çok yakın olduğumu düşünüyorum. Orijinal gönderimimin altındaki düzenlemelerime bir göz atabilir misiniz? (Ek kod koymak için yorumlarda yer yoktu). Teşekkürler. Dave – Dave

+0

Neyin yanlış gittiğini söylemek zor ama cevabımı eklediğim yükleme yardımcı yöntemini deneyebilirsiniz. – Clemens

+0

Clemens, Teşekkürler! Teşekkür ederim! Teşekkür ederim! Bu işe yarıyor. Değeri ne olursa olsun, CacheOption hakkındaki satırın anahtarı gibi görünüyor. Bunu yorumladım ve görüntüler görüntülenmedi. Merakla, izleme penceresindeki sonuçları açıp bir kartı incelemekle ilgili hilelerimi kullanarak gösteremedim. Şerefe. – Dave

0

bu çözmekten değilse ben gerçekten sorunu yeniden oluşturmaya çalışın vermedi, ama olacak:

ilk xaml bloğunda, sana bağlamaları karıştı düşünüyorum. Bunu nasıl beklerim, Görüntülerin GözlenebilirKodeksiyonu için ItemsSource, Görüntü için Image kaynağı.

<Image Source="{Binding}" Height="50" Width="40" /> 
İlgili konular