简体   繁体   English

C#WPF带有图像的嵌套类的数组

[英]C# WPF Array of nested classes with image

I am struggling to teach myself C#, and long googling has not turned up this answer: 我正在努力地教自己C#,并且长时间使用Google搜索并没有出现以下答案:

I have a classes Rom, Game and Art. 我上了Rom,Game和Art课程。 Rom.Game.Art is for images and is defined thus: Rom.Game.Art用于图像,因此定义为:

public class art
{
    public Image Screen { get; set; }
    public Image Marquis { get; set; }
    public Image Logo { get; set; }

    public art ()
    {
        BitmapImage Default_image = new BitmapImage();
        Default_image.BeginInit();
        Default_image.UriSource = new Uri(@"C:\Users\Major Major\Documents\Visual Studio 2013\Projects\Robin\Robin\images\bee_ace.png", UriKind.Absolute);
        Default_image.EndInit();

        this.Screen = new Image();
        this.Screen.Source = Default_image;
        this.Marquis = new Image();
        this.Marquis.Source = Default_image;
        this.Logo = new Image();
        this.Logo.Source = Default_image;
    }
}

I want to create an array of Roms, and populate the many nested properties and subclasses from a DataTable in a loop. 我想创建一个Roms数组,并在一个循环中填充DataTable中的许多嵌套属性和子类。 Before I get into the loop, though, I just want to get a block of test code to work. 不过,在进入循环之前,我只想获取一块测试代码即可工作。 The following works just fine: 以下工作正常:

        InitializeComponent();
        BitmapImage Image_0 = new BitmapImage();

        Image_0.BeginInit();
        Image_0.UriSource = new Uri(@"E:\Arcade\Art\Box\Intellivision\Congo Bongo.jpg", UriKind.Absolute);
        Image_0.EndInit();

        ROMS.Insert(0, new Rom());

        ROMS[0].Name = "Congo Bongo";
        ROMS[0].Game.Art.Screen.Source = Image_0;
        ROMS[0].Game.Date = "1983";
        ROMS[0].Game.Platform = "Intellivision";

        ROM_list.ItemsSource = ROMS;

My complaint is that, if I put this in a loop, all of the images in the array will be the same--they will be the last image entered. 我的抱怨是,如果我将其循环放置,数组中的所有图像都将相同-它们将是最后输入的图像。 It seems the expression "ROMS[0].Game.Art.Screen.Source = Image_0;" 似乎表达为“ ROMS [0] .Game.Art.Screen.Source = Image_0;” ties ROMS[0].Game.Art.Screen.Source to the variable Image_0, rather than just transferring the value (this seems like surprising behavior to me, but no worries). 将ROMS [0] .Game.Art.Screen.Source与变量Image_0关联,而不是仅仅传递值(这对我来说似乎是令人惊讶的行为,但无后顾之忧)。 So that in order to keep populating ROMS[j].Game.Art.Screen.Source, I have to create an array of BitmapImages separate from the ROM array as a reference. 为了保持ROMS [j] .Game.Art.Screen.Source的填充,我必须创建一个与ROM数组分开的BitmapImages数组作为参考。 What I'd prefer is to instantiate(?) the BitmapImages within the array, like this: 我更喜欢在数组中实例化(?)BitmapImages,如下所示:

        ROMS[0].Game.Art.Screen.Source = new BitmapImage();
        InitializeComponent();
        ROMS[0].Game.Art.Screen.Source.BeginInit();
        ROMS[0].Game.Art.Screen.Source.UriSource = new Uri(@"E:\Arcade\Art\Box\Intellivision\Congo Bongo.jpg", UriKind.Absolute);
        ROMS[0].Game.Art.Screen.Source.EndInit();

This doesn't work. 这行不通。 Rom.Game.Art.Screen.Source is not a BitMapImage, and I cannot find the methods to assign an image to it. Rom.Game.Art.Screen.Source不是BitMapImage,并且我找不到分配图像的方法。

So my questions, specifically: 1. Is there a way to assign an image source to ROMS[0].Game.Art.Screen.Source without creating a separate BitmapImage that lives on separately, or is that stupid? 因此,我的问题特别是:1.是否有一种方法可以将图像源分配给ROMS [0] .Game.Art.Screen.Source,而无需创建单独存在的BitmapImage,还是那么愚蠢?

  1. Is there a smarter way to do what I'm trying to do? 有没有更聪明的方式来做我想做的事情?

  2. Is there a reference to help me understand the relationships between the myriad image classes in C#? 是否有参考可帮助我理解C#中无数图像类之间的关系?

Sorry for the wordy question, and thanks. 对不起罗word的问题,谢谢。

I think you should do some review about DataBinding. 我认为您应该对DataBinding做一些评论。 You will save more time. 您将节省更多时间。

You just need create something like the models: 您只需要创建类似模型的内容:

ROM.Game.Art.Screen.Path ="meuPath.Jpg"; ROM.Game.Art.Screen.Path =“ meuPath.Jpg”;

myItemSource = ROMS;

and in the end, do something like: 最后,执行以下操作:

            <ItemsControl x:Name="myItemSource">
                    <TextBlock Text="{Binding ROM.Game.Art.Screen.Name}"/>
                    <Image Source="{Binding ROM.Game.Art.Screen.Path,Converter=MyConverterImageToPath"/>
            </ItemsControl>

You need to create a new instance of the BitMapImage for each of your array member. 您需要为每个数组成员创建一个BitMapImage的新实例。 C# uses references if you assign an object to a variable. 如果将对象分配给变量,C#将使用引用。

ROMS[0].Game.Art.Screen.Source = Image_0;

here you are creating a reference to Image_0, if you do now something like ... 如果您现在执行类似...的操作,则在此处创建对Image_0的引用。

ROMS[1].Game.Art.Screen.Source = Image_0;

both roms[0] and roms[1] .screen.source referencing Image_0. roms [0]和roms [1] .screen.source都引用了Image_0。 If you do now something like: 如果现在执行以下操作:

ROMS[0].Game.Art.Screen.Source.UriSource = new Uri(@"E:\Arcade\Art\Box\Intellivision\Congo Bongo.jpg", UriKind.Absolute);

you update Image_0 and all your rom.screen.source are referencing to Image_0 and are updated 您更新了Image_0,并且您所有的rom.screen.source都引用了Image_0并进行了更新

If you want to use Image_0 as base "image" for all, what you could do is call the .Clone() function of the bitmapImage, which creates a deep copy of the object (a new object, instead of a reference). 如果要全部使用Image_0作为基本“图像”,则可以调用bitmapImage的.Clone()函数,该函数将创建对象的深层副本(新对象,而不是引用)。

So somewhere in the begin you have: 因此,在开始的某个地方,您将拥有:

InitializeComponent();
BitmapImage Image_0 = new BitmapImage();

Image_0.BeginInit();
Image_0.UriSource = new Uri(@"E:\Arcade\Art\Box\Intellivision\Congo Bongo.jpg", UriKind.Absolute);
Image_0.EndInit();

in your loop you have then 在你的循环中

ROMS[i].Name = "Congo Bongo";
ROMS[i].Game.Art.Screen.Source = Image_0.Clone();
ROMS[i].Game.Date = "1983";
ROMS[i].Game.Platform = "Intellivision";

Thanks a lot for looking at this. 非常感谢您对此的关注。

The deep copy concept is instructive, and gets me on the right track. 深层复制概念很有启发性,可让我步入正轨。 But there is still no method that lets me modify ROMS[i].Game.Art.Screen.Source (the class of this Is Image.Source). 但是仍然没有方法可以让我修改ROM​​S [i] .Game.Art.Screen.Source(此类是Image.Source)。 It's interesting that I can assign a BitmapImage directly to an Image.Source, but then I cannot alter the BitmapImage by going through the class nest. 可以将BitmapImage直接分配给Image.Source很有意思,但是随后我无法通过类嵌套来更改BitmapImage。 In other words 换一种说法

ROMS[1].Game.Art.Screen.Source.UriSource ROMS [1] .Game.Art.Screen.Source.UriSource

does not exist, even though ROMS[1].Game.Art.Screen.Source was set equal to a BitmapImage, which has a .UriSource. 即使ROMS [1] .Game.Art.Screen.Source设置为等于具有.UriSource的BitmapImage,也不存在。

So, using you comments as a starting point, I came up with the following, which will work in a loop, obviously with loop variables in place of each string: 因此,以您的注释为起点,我提出了以下内容,它们将在循环中工作,显然是用循环变量代替了每个字符串:

        InitializeComponent();

        ROMS.Insert(0, new Rom());
        ROMS.Insert(1, new Rom());

        ROMS[0].Name = "Congo Bongo";
        ROMS[0].Game.Art.Screen.Source = new BitmapImage(new Uri(@"E:\Arcade\Art\Box\Intellivision\Congo Bongo.jpg", UriKind.Absolute));
        ROMS[0].Game.Date = "1983";
        ROMS[0].Game.Platform = "Intellivision";

        ROMS[1].Name = "Donkey Kong";
        ROMS[1].Game.Art.Screen.Source = new BitmapImage(new Uri(@"E:\Arcade\Art\Box\Intellivision\Donkey Kong.jpg", UriKind.Absolute));
        ROMS[1].Game.Date = "1982";
        ROMS[1].Game.Platform = "Intellivision";

        ROM_list.ItemsSource = ROMS;

Still, I have to create a new BitMapImage and Uri every time I modify Game.Image.Source. 尽管如此,每次修改Game.Image.Source时,我都必须创建一个新的BitMapImage和Uri。 I wonder what happens to the old BitMapImage and Uri, which don't even have names and can't be modified. 我不知道旧的BitMapImage和Uri会发生什么,它们甚至都没有名称并且无法修改。 Do they just float around in memory for eternity, haunting the living variables? 他们只是为了永恒而漂浮在记忆中,困扰着生活变量吗? Am I still doing something silly? 我还在做傻事吗?

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM