Dodawanie picturebox w pętli + skąd pliki obrazków

0

Cześć, chciałbym dodać pictureboxy w pętli i mam do tego kilka pytań:
W którym momencie wykonywania programu to dodać? (bo chyba nie InitializeComponent, czy da się zrobić aby dodane pictureboxy były widoczne w mojej formie w desingerze?)
Gdzie dodać pliki graficzne (do resources? jak tak to jak je w pętli potem ustawić jako picturebox.image? a jak nie to czy jest jakiś inny sposób, dodam że pliki mają różne rozmiary więc chyba odpada Imagelist)?

Proszę o odpowiedź i z góry dziękuję

1

Cześć,

Ad 1) Ważne, żeby nie było przed InitializeComponent() forma, reszta zależy od wymogów, może być zaraz za InitializeComponent() forma, albo na zdarzeniu Load, albo np. dopiero jak klikniesz jakiś przycisk itd. Zależy od Twoich wymogów,

Ad 2) Szczerze mówiąc nie znam się jakoś specjalnie na designer-rze, ale wydaje mi się, że nie ma szans żebyś zobaczył na formie,

Ad 3) Możesz dodać do Resources, PictureBox przyjmuje obiekt Image, możesz trzymać Image-e w Resources albo ładować z dysku (o ile dobrze pamiętam Image.FromFile()) albo np. na starcie programu załadować wszystkie do jakiejś listy np. IList<Image>, a następnie tą listę przekazać do forma i wyświetlić, znów zależy wszystko od Twoich wymogów,

Ad 4) Nie pamiętam już dokładnie niestety (od ponad roku tylko WPF), ale chyba faktycznie ImageList wymaga podania rozmiaru Image-a.

Pozdrawiam.

0

Dzięki za pomoc, udało mi się zrealizować to co chciałem, ale mam jeszcze pytanie. Czy to, że nie projektuję całego programu w Desingerze to jest jakiś błąd? (w sensie niezgodność z jakąś konwencją czy coś)

1

Zawsze lepiej, żeby było w designerze, nieraz jednak zdarza się, że GUI jest generowane dynamicznie (w runtime), w tej sytuacji nic nie poradzisz i musisz wygenerować dynamicznie. Jeżeli coś mogę poradzić to umieść te dynamicznie fragmenty w kontrolce Panel - ja tak zawsze robiłem tj. np. mam MainForm, a w nim MainMenu, poniżej np. jakiś ToolBar i jeszcze niżej Panel, w którym dopiero dynamicznie dodawałem kontrolki, o tyle dobrze, że ten Panel możesz sobie nazwać np. dynamicImagePictureBoxesPanel czy coś takiego, żebyś wiedział że to tam jest, dodatkowo wszystkie współrzędne liczysz wtedy od 0,0 zamiast gdzieś od środka okna. Pozdrawiam.

0

Zmieniam rozwiązanie jednak i mam pytanie, wrzuciłem folder "Colors" do mojej solucji, w folderze znajdują się pliki .png. Chciałbym teraz utworzyć tyle pictureboxów ile jest tych plików (ustawić Image i nazwę), nie wiem jak się do tego zabrać.

1

Mozesz użyć Directory.GetFiles

1

Metoda jest następująca:

  1. Pobierasz listę plików z katalogu Colors, zakładam, że ten katalog znajduje się tam gdzie plik .exe, czyli najpierw musisz się dostać do ścieżki do pliku exe,

string exePath = System.Reflection.Assembly.GetExecutingAssembly().GetName().CodeBase;

potem do katalogu, gdzie jest .exe

string dir = System.IO.Path.GetDirectoryName(exePath);

potem budujesz ścieżkę do katalogu Colors.

string colorsDir = System.IO.Path.Combine(dir, "Colors");

  1. Pobierasz listę plików png z katalogu Colors.

string [] pngFiles = System.IO.Directory.GetFiles(colorsDir, "*.png");

  1. Mamy listę plików png, teraz ładujemy je do listy IList<Image>
IList<Image> images = new List<Image>();
foreach(string pngFile in pngFiles)
{
  images.Add(Image.FromFile(pngFile));
}
  1. Mamy gotową listę Image, teraz musisz w pętli generować PictureBox, ustawiasz Image na element i z images, nazwę na element i z pngFiles, każdy wygenerowany PictureBox dodajesz do Panel, pamiętaj żeby obliczać w pętli współrzędne dla każdego kolejnego PictureBox, tutaj jest trochę zabawy, stąd nie podam Ci gotowego kodu, bo trzeba by nad tym posiedzieć.
0

Dzięki! Z ciekawości, która motoda jest "lepsza" i pod jakim względem, topika czy micha? Mój kod aktualnie wygląda tak i działa:

 string[] imageDirectory = Directory.GetFiles("Types");
            FileInfo imageInfo;
            for (int i = 0; i < this.pictureBoxTypes.Length; i++)
            {
                this.pictureBoxTypes[i] = new PictureBox();
                this.pictureBoxTypes[i].SizeMode = PictureBoxSizeMode.AutoSize;
                this.pictureBoxTypes[i].Image = Image.FromFile(imageDirectory[i]);
                this.pictureBoxTypes[i].BackColor = Color.Gray;
                this.pictureBoxTypes[i].Location = new Point(6, CalculateImageHeightLocation(i));
                this.pictureBoxTypes[i].Click += new EventHandler(this.pictureBox_Click);
                imageInfo = new FileInfo(imageDirectory[i]);
                this.pictureBoxTypes[i].Name = imageInfo.Name;
                this.tabPageType.Controls.Add(pictureBoxTypes[i]);

nie wiem tylko czy zmienić ma metodę topika czy nie? Co w przypadku jeżeli chciałbym "ukryć" pliki przed użytkownikiem (tzn wbudować je w .exe, dodam, że takich "grup" pictureboxów będę miał koło 4-5 więc nie wiem jak miałbym je rozróżniać w resources, bo tam folderu chyba nie załaduję)?

1

Mógłbyś wrzucić do resources jako zip-y.
Link: https://dotnetzip.codeplex.com/

Compression mode ustawiasz na Store, wtedy nie kompresuje, zakładam, że zbytnio nie spowolni to aplikacji.

Czyli podsumowując, w resources trzymasz spakowane grupy zdjęć, dostajesz się do nich w runtime, odpakowujesz do pamięci i ładujesz images.
Trochę zje RAM-u, niestety, ale jest to jakiś sposób na rozwiązanie Twojego problemu, nie twierdzę, że najlepszy.

Musisz zweryfikować jak to faktycznie wyjdzie wydajnościowo.
Może ktoś inny podpowie coś fajniejszego.

0

Mam mały problem, musiałem zmienić sposób topika, ponieważ tworzyło mi w tym folderze plik thumbs.db, po zmianie na sposób micha i kompilacji wyrzuca wyjątek: http://scr.hu/0u0e/yoh3a

1

Spróbuj:

string [] pngFiles = System.IO.Directory.GetFiles(new Uri(colorsDir).LocalPath, "*.png")

1 użytkowników online, w tym zalogowanych: 0, gości: 1