【问题标题】:Multiple images from folder文件夹中的多个图像
【发布时间】:2017-02-22 18:02:12
【问题描述】:

因为我对 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 等)?

【问题讨论】:

  • 您在一个循环中调用了 151 次 img_ding.Source = carBitmap;。那么你的期望是什么?除此之外,您应该使用 ItemsControl 而不是以编程方式将图像控件添加到 Canvas。
  • 叹息。现在你有三个答案告诉你相同的,他们都仍然有多余的UriKind.Absolute,但没有一个显示如何使用 ItemsControl。如果你有兴趣,我会稍后写一个。您后面的代码将减少到一行。
  • 非常感谢提供。我现在已经找到了解决方案,并且可能会出于培训目的尝试其他建议。另外,我修复了 img_ding.Source = carBitmap;现在行。感谢您的评论!

标签: c# wpf image canvas


【解决方案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>

可能会在 DataTemplate 中的 Image 控件中添加一些 Margin

在后面的代码中,在 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)));
}

然后您可以将 Window 的 DataContext 分配给视图模型的一个实例,并像这样绑定到集合属性:

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

XAML

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

【讨论】:

  • 非常感谢您的评论!我使用@darren 回答完成了所有工作,但出于学习目的,我也会尝试这样做!
  • 如果您要继续使用 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 结尾的路径每次都应该改变;毫无疑问,你可以弄清楚。它是 for 循环中 i 的值,字符串化并用零填充?看起来像这样:

        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:000} 的格式化方式——和padleft 一样吗?
  • @Darren 是的,当然会。
  • 嘿,这不是一堆 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
}

【讨论】:

  • 非常感谢!这种方式非常简单,它完全符合我的要求:)
猜你喜欢
  • 2021-05-28
  • 2020-08-24
  • 2017-10-07
  • 2021-03-06
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-07-25
  • 1970-01-01
相关资源
最近更新 更多