Несколько изображений из папки

#c# #wpf #image #canvas

#c# #wpf #изображение #холст

Вопрос:

поскольку я довольно новичок в C # и WPF, я просто не могу понять, как это сделать. У меня есть форма, в которой должно отображаться 151 изображение (все спрайты pokemon поколения 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 раз за цикл. Итак, чего же вы ожидаете? Кроме того, вы должны использовать ItemsControl вместо программного добавления элементов управления изображениями на холст.

2. Вздох. Теперь у вас есть три ответа, говорящих вам то же самое, все они по-прежнему имеют избыточность UriKind.Absolute , но ни один из них не показывает, как использовать ItemsControl . Я напишу один позже, если вам интересно. Ваш исходный код сократится до одной строки.

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

Ответ №1:

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

Комментарии:

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

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

Ответ №2:

Вы создаете 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 предоставит ответ, который покажет вам, как переписать все это с помощью an ItemsControl , что будет намного приятнее, чем это. Я уже написал кому-то кучу XAML этим утром, так что теперь его очередь.

Комментарии:

1. oooo. разве вы раньше не видели такой способ форматирования с {0:000} помощью -, который делает то же самое, что и padleft?

2. @Darren Да, конечно, будет.

3. Эй, это не куча XAML, всего 12 строк 🙂

Ответ №3:

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

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

 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
}
 

Комментарии:

1. Большое спасибо! Это так просто, и он делает именно то, что я хочу, чтобы он делал 🙂