2014-09-10 2 views
0

Я изо всех сил, чтобы научить себя C#, и долго не прибегая к помощи появился этот ответ:C# WPF Массив вложенных классов с изображением

У меня есть классы Rom, игры и искусства. 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; 
    } 
} 

Я хочу, чтобы создать массив дисков, и заполнить множество вложенных свойств и подклассы из DataTable в цикле. Однако, прежде чем попасть в цикл, я просто хочу получить блок тестового кода для работы. Следующие работы просто отлично:

 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; 

Моя жалоба является то, что, если я ставлю это в цикле, все изображения в массиве будет то же самое - они будут последними изображение, поступающее. Кажется, это выражение «ROMS [0] .Game.Art.Screen.Source = Image_0;» связывает ROMS [0] .Game.Art.Screen.Source с переменной Image_0, вместо того, чтобы просто передавать значение (это кажется мне удивительным поведением, но не стоит беспокоиться). Так что для того, чтобы продолжать заполнять ROMS [j] .Game.Art.Screen.Source, мне нужно создать массив BitmapImages отдельно от массива ROM в качестве ссылки. То, что я бы предпочел, чтобы создавать экземпляры 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(); 

Это не работает. Rom.Game.Art.Screen.Source не является BitMapImage, и я не могу найти методы для назначения ему изображения.

Так что мои вопросы, в частности: 1. Есть ли способ назначить источник изображения ROMS [0] .Game.Art.Screen.Source без создания отдельного BitmapImage, который живет отдельно или это глупо?

  1. Есть ли более разумный способ сделать то, что я пытаюсь сделать?

  2. Есть ли ссылка, чтобы помочь мне понять отношения между бесчисленными классами изображений в C#?

Извините за многословный вопрос и спасибо.

ответ

0

Я думаю, вам стоит сделать обзор DataBinding. Вы сэкономите больше времени.

Вам просто нужно создать что-то вроде модели:

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

myItemSource = ROMS; 

и в конце концов, сделать что-то вроде:

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

Спасибо, что посмотрели на это. Это был именно тот ответ, на который я надеялся, но это не похоже, что у класса Image есть свойство Path. –

+0

Вам не нужно использовать конвертер. Поверьте, вы должны привыкнуть к использованию конвертации, если хотите быть хорошим с xaml: Посмотрите эту тему, и это сэкономит вам жизнь: http://stackoverflow.com/questions/14355489/bind- image-source-in-wpf-to-url –

+0

Хороший лорд. Я могу просто привязать его к строке, и она автоматически преобразует ее. Вся эта чушь с BitmapImages.Uri.Source.Jibberjabber.blahblahblah прокомментирована. –

0

Вам нужно создать новый экземпляр BitmapImage для каждого из вашего элемента массива. C# использует ссылки, если вы назначаете объект переменной.

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

здесь вы создаете ссылку на image_0, если вы сейчас что-то вроде ...

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

оба ромы [0] и ромы [1] .screen.source ссылающегося image_0.Если вы сейчас что-то вроде:

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

обновить image_0 и все ваши rom.screen.source ссылаются на image_0 и обновляются

Если вы хотите использовать image_0 в качестве основы «образа» для всех, что вы можете сделать, это вызвать функцию .Clone() для bitmapImage, которая создает глубокую копию объекта (новый объект вместо ссылки).

Так где-то в начать у вас есть:

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[i].Name = "Congo Bongo"; 
ROMS[i].Game.Art.Screen.Source = Image_0.Clone(); 
ROMS[i].Game.Date = "1983"; 
ROMS[i].Game.Platform = "Intellivision"; 
0

Спасибо большое за глядя на это.

Концепция глубокой копии поучительна и помогает мне на правильном пути. Но до сих пор нет метода, который позволяет мне модифицировать ROMS [i] .Game.Art.Screen.Source (класс этого Is Image.Source). Интересно, что я могу назначить BitmapImage непосредственно на Image.Source, но тогда я не могу изменить BitmapImage, пройдя через гнездо класса. Другими словами

РОМС [1] .Game.Art.Screen.Source.UriSource

не существует, даже если РОМС [1] .Game.Art.Screen.Source был установлен равным BitmapImage, который имеет .UriSource.

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

 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; 

Тем не менее, я должен создавайте новый BitMapImage и Uri каждый раз, когда я изменяю Game.Image.Source. Интересно, что происходит со старыми BitMapImage и Uri, которые даже не имеют имен и не могут быть изменены. Они просто плавают вокруг в памяти на вечность, преследуя живых переменных? Я все еще делаю что-то глупое?