2016-10-13 6 views
1

wie ich bin ziemlich neu in C# und WPF Ich kann einfach nicht herausfinden, wie dies zu tun ist. Ich habe ein Formular, das 151 Bilder (alle Pokémon Generation 1 Sprites) in einer Form zeigen soll. So wie ich es jetzt gemacht habe, zeigt es das gleiche Bild 151 mal anstelle aller Bilder nur einmal. Der Code, den ich dafür geschrieben hat, ist wie folgt:Mehrere Bilder von Ordner

public partial class PokeGame : Window 
{ 
    BitmapImage carBitmap = new BitmapImage(new Uri("pack://application:,,,/Images/All_Sprites/001.png", UriKind.Absolute)); 

    { 

     InitializeComponent(); 

     int imgCount = 151; 
     int left = 0; 
     int top = 0; 
     List<Image> imageList = new List<Image>(); 
     for (int i = 0; i < imgCount; i++) 
     { 
      if(i % 10 == 0) 
      { 
       if (i != 0) 
       { 
        top += 175; 
        left = 0; 
       } else 
       { 
        top = 0; 
        left = 0; 
       } 
      } 

      Image img_ding = new Image(); 
      img_ding.Source = carBitmap; 
      img_ding.Height = 150; 
      img_ding.Width = 150; 
      img_ding.Margin = new Thickness(left, top ,0 ,0); 
      imageList.Add(img_ding); 
      left += 175; 
     } 

     int j = 0; 

     foreach (Image img in imageList) 
     { 
      imageCanvas.Children.Add(img); 
      j++; 
     } 

    } 

Wie Sie sehen gibt es wahrscheinlich eine Menge Raum für Verbesserungen in meinem Code. Meine Frage ist jedoch: Wie kann ich es so einrichten, dass es nicht 151 Mal das gleiche Bild anzeigt, sondern alle Bilder (sprite001.png, sprite002.png, sprite003.png usw.)?

+1

Du nennst 'img_ding.Source = carBitmap;' 151 mal in einer Schleife. Also, was erwartest du? Außerdem sollten Sie ein ItemsControl verwenden, anstatt programmgesteuert Bildsteuerelemente zu einem Canvas hinzuzufügen. – Clemens

+2

Seufzer. Jetzt haben Sie drei Antworten, die Ihnen dasselbe sagen, alle haben immer noch das redundante 'UriKind.Absolute', aber keines zeigt, wie man ein ItemsControl benutzt. Ich würde später einen schreiben, wenn Sie interessiert sind. Dein Code dahinter würde auf eine Zeile fallen. – Clemens

+0

Vielen Dank für das Angebot.Ich habe jetzt die Lösung und werde wahrscheinlich auch die anderen Vorschläge ausprobieren. Außerdem habe ich die img_ding.Source = carbitmap behoben; Linie jetzt. Danke für das Kommentieren! –

Antwort

1

Sie müssen Ihre Bitmap innerhalb der Schleife definieren, nicht außerhalb. Dann erstellt jede Iteration eine neue Bitmap mit dem neuen Pfad.

so wie etwas:

for (int i = 0; i < imgCount; i++) 
{ 
    // padding left will give you 001 and 010 and 151 
    string img = i.ToString().PadLeft(3, '0'); 
    BitmapImage carBitmap = new BitmapImage(new Uri("pack://application:,,,/Images/All_Sprites/" + img+".png", UriKind.Absolute)); 
    // the rest of your code 
} 
+0

Vielen Dank! Es ist so einfach und macht genau das, was ich will :) –

4

Sie erstellen carBitmap genau einmal außerhalb der Schleife und verwenden es jedes Mal. Erstellen Sie stattdessen für jedes Bild ein neues Bild.

 Image img_ding = new Image(); 
     BitmapImage carBitmap = new BitmapImage(new Uri("pack://application:,,,/Images/All_Sprites/001.png", UriKind.Absolute)); 
     img_ding.Source = carBitmap; 

gehe ich davon aus, dass der Pfad in 001.jpg enden sollte jedes Mal zu ändern; Zweifellos kannst du das herausfinden. Ist es der Wert von i in der for-Schleife, beschriftet und links aufgefüllt mit Nullen? Das würde wie folgt aussehen:

 Image img_ding = new Image(); 
     var uri = String.Format("pack://application:,,,/Images/All_Sprites/{0:000}.png", i); 
     // N.B. UriKind.Absolute is redundant, sigh 
     BitmapImage carBitmap = new BitmapImage(new Uri(uri, UriKind.Absolute)); 
     img_ding.Source = carBitmap; 

Auch @Clemens wird eine Antwort geben, die Sie zeigen, wie die ganze Sache neu zu schreiben ein ItemsControl verwenden, die viel schöner als dies sein werden. Ich habe heute Morgen schon jemandem einen Haufen XAML geschrieben, also ist er an der Reihe.

+0

oooo. haven; t sah diese Art der Formatierung zuvor mit '{0: 000}' - das gleiche wie padleft? – Darren

+0

@Darren Ja, sicher. –

+0

Schön! jeden Tag ist eine Lerngelegenheit :) – Darren

5

Statt programmatisch Bildkontrollen auf eine Leinwand hinzufügen, schreiben diese XAML:

<ItemsControl x:Name="images"> 
    <ItemsControl.ItemsPanel> 
     <ItemsPanelTemplate> 
      <UniformGrid Columns="10"/> 
     </ItemsPanelTemplate> 
    </ItemsControl.ItemsPanel> 
    <ItemsControl.ItemTemplate> 
     <DataTemplate> 
      <Image Width="150" Height="150" Source="{Binding}"/> 
     </DataTemplate> 
    </ItemsControl.ItemTemplate> 
</ItemsControl> 

Wahrscheinlich in der Datatemplate einige Margin an die Bildsteuerung hinzuzufügen.

In Code-behind, fügen Sie eine Zeile an den Konstruktor Ihres Mainwindow:

using System.Linq; 
... 

public MainWindow() 
{ 
    InitializeComponent(); 

    images.ItemsSource = Enumerable 
     .Range(1, 151) 
     .Select(i => string.Format("pack://application:,,,/Images/{0:000}.png", i)); 
} 

Nun könnte man eine richtige Ansicht Modell erstellen möchten, in dem Sie eine Sammlung Typ Eigenschaft haben, würde für Ihre Bilder, wie

public class ViewModel 
{ 
    public ObservableCollection<string> Images { get; } 
     = new ObservableCollection<string>(Enumerable 
      .Range(1, 151) 
      .Select(i => string.Format("pack://application:,,,/Images/{0:000}.png", i))); 
} 

würden Sie dann die Datacontext auf eine Instanz der view-Modell, das Fenster zuweisen und auf die Sammlung Eigenschaft wie folgt binden:

public MainWindow() 
{ 
    InitializeComponent(); 
    DataContext = new ViewModel(); 
} 

XAML

<ItemsControl ItemsSource="{Binding Images}"> 
    ... 
</ItemsControl> 
+0

Vielen Dank für Ihre Kommentare! Ich habe alles mit @darren Antwort getan, aber ich werde das auch für Lernzwecke versuchen! –

+1

Wenn Sie mit WPF fortfahren, gibt es keinen Weg um XAML, Datenvorlagen und Datenbindung. Je früher Sie anfangen, es richtig zu machen, desto besser. – Clemens