Programowanie w języku C#

Tworzenie własnych komponentów wizualnych

  • 2013-11-27 22:37
  • 0 komentarzy
  • 7537 odsłon
  • Oceń ten tekst jako pierwszy

Tworzenie biblioteki DLL z projektu własnej kontrolki wykorzystującej grafiki


1. Opis problemu

Stworzenie kontrolki, która ma przypisaną grafikę na stałe, nie jest problemem, gdy chcemy tą kontrolkę przeciągnąć z obszaru ToolBox na formę. Przykładowo, kontrolka dziedzicząca po samym przycisku (Button) z tłem jako pewien obrazek  przenoszona jest na formę bez problemu. Komplikacje pojawiają się w momencie, gdy źródła zewnętrzne mają być ładowane dynamicznie w kontrolce dziedziczącej po, np.  TreeView:

namespace DirTreeViewLibrary
 {
     public class ABC : TreeView
     {
         public ABC
         {
             this.ImageList.Images.Add(Image.FromFile(@"Images\Disk.png"));
             this.ImageList.Images.Add(Image.FromFile(@"Images\FolderClosed.png"));
             this.ImageList.Images.Add(Image.FromFile(@"Images\FolderOpened.png"));

gdzie "Images\..." jest przykładowym katalogiem zawierającym grafiki, z których chcemy korzystać.

Gdy projekt z naszą kontrolką skompilujemy do DLL-a, dołączymy do referencji w innym projekcie oraz dodamy do ToolBox'a, to próba przeciągnięcia tej kontrolki na formę owego projektu zakończy się wyświetleniem komunikatu błędu o treści podobnej do poniższej:

Failed to create component 'ABC'. This error message follows:
    'System.IO.FileNotFoundException:Image\Disk.png
    at System.Drawing.Image.FromFile(String filename, Boolean useEmbededColorManagement)
    at System.Drawing.Image.FromFile(String filename)
    at 'nazwa projektu kontrolki, nazwa klasy i numer linijki wystąpienia błędu'


2. Rozwiązanie

Aby efektywnie przeciągać kontrolkę, należy pozmieniać dowiązania do źródeł w projekcie kontrolki.
Zamiast:

this.ImageList.Images.Add(Image.FromFile(@"Images\Disk.png"));
this.ImageList.Images.Add(Image.FromFile(@"Images\FolderClosed.png"));
this.ImageList.Images.Add(Image.FromFile(@"Images\FolderOpened.png"));

należy napisać:

this.ImageList.Images.Add(global::DirTreeViewLibrary.Properties.Resources.Disk);
this.ImageList.Images.Add(global::DirTreeViewLibrary.Properties.Resources.FolderClosed);
this.ImageList.Images.Add(global::DirTreeViewLibrary.Properties.Resources.FolderOpened);

Używanie kontrolki wtedy powinno umożliwiać przeciąganie jej bezpośrednio na formę.