2016-10-13 5 views
1

, поскольку я довольно новичок в C# и WPF. Я просто не могу понять, как это сделать. У меня есть форма, которая должна показать 151 изображение (все спрайты 1 покемона 1) в форме. То, как я сделал это сейчас, состоит в том, что он показывает одно и то же изображение в 151 раз вместо всех изображений только один раз. Код, который я написал для этого выглядит следующим образом:Несколько изображений из папки

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

    } 

Как вы можете видеть, что есть, вероятно, много места для улучшения моего кода. Однако мой вопрос: как я могу сделать это так, чтобы он не отображал одно и то же изображение 151 раз, но все изображения (sprite001.png, sprite002.png, sprite003.png и т. Д.)?

+1

Вы звоните 'img_ding.Source = carBitmap;' 151 раз в цикле. Итак, каково ваше ожидание? Кроме того, вы должны использовать ItemControl вместо того, чтобы программно добавлять элементы управления Image на Canvas. – Clemens

+2

Вздох. Теперь у вас есть три ответа, сообщающие вам то же самое, все они все еще имеют избыточный «UriKind.Absolute», но никто не показывает, как использовать ItemControl. Я напишу позже, если вам интересно. Ваш код позади упадет до одной строки. – Clemens

+0

Спасибо большое за предложение.Сейчас у меня есть решение и, вероятно, попробую другие предложения, а также для тренировочных целей. Кроме того, я исправил img_ding.Source = carBitmap; теперь. Спасибо за комментарий! –

ответ

1

Вам необходимо определить растровое изображение внутри цикла, а не снаружи. Затем каждая итерация создаст новое растровое изображение с новым путем.

так что-то вроде:

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

Спасибо большое! Это так просто, и он делает именно то, что я хочу делать :) –

4

Вы создаете carBitmap ровно один раз, вне цикла, и используйте его каждый раз. Создайте новый для каждого изображения.

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

Я полагаю, что путь, заканчивающийся в 001.jpg должны быть изменения каждый раз; без сомнения, вы можете понять это. Является ли это значение i в цикле for, строковое и левое с нулями? Это было бы выглядеть следующим образом:

 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; 

Кроме того, @Clemens собирается дать ответ, который показывает вам, как переписать все это, используя ItemsControl, который будет намного лучше, чем это. Сегодня я уже написал кому-то кучу XAML, так что это его очередь.

+0

oooo. haven; t видел этот способ форматирования раньше с '{0: 000}' - то же самое, что и padleft? – Darren

+0

@ Даррен Да, конечно. –

+0

Ницца! каждый день - возможность обучения :) – Darren

5

Вместо добавления элементов управления программным способом изображения на холсте, написать этот код 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> 

Возможно добавить Margin к управлению изображения в DataTemplate.

В коде позади, добавьте одну строку в конструкторе MainWindow:

using System.Linq; 
... 

public MainWindow() 
{ 
    InitializeComponent(); 

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

Теперь вы можете создать правильную модель представления, где вы имели бы свойство коллекции типа для вашего изображения, как

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

Вы бы затем присвоить DataContext окна к экземпляру модели представления и привязать к свойству коллекции, как это:

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

XAML

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

Большое спасибо за комментирование! Я все это сделал с помощью ответа @darren, но я попробую это и для учебных целей! –

+1

Если вы собираетесь продолжить работу с WPF, то вокруг XAML, шаблонов данных и привязки данных не будет никакого способа. Чем раньше вы начинаете делать это правильно, тем лучше. – Clemens

Смежные вопросы