Tworzenie własnych komponentów wizualnych
Amula
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ę.