Delphi-PRAXiS

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   GUI-Design mit VCL / FireMonkey / Common Controls (https://www.delphipraxis.net/18-gui-design-mit-vcl-firemonkey-common-controls/)
-   -   C# Button.Image (d.h. Bitmap) wird nicht angezeigt (https://www.delphipraxis.net/75627-button-image-d-h-bitmap-wird-nicht-angezeigt.html)

Jürgen Thomas 22. Aug 2006 17:04


Button.Image (d.h. Bitmap) wird nicht angezeigt
 
Hallo,
ich vermisse in meiner Anwendung die Bitmaps auf meinen Buttons. Die Bitmaps werden grundsätzlich über eine ImageList zugeordnet.

Variante 1 funktioniert:
Code:
public class DlgDemo : System.Windows.Forms.Form{
private System.ComponentModel.IContainer components;
private System.Windows.Forms.Button btn;
private System.Windows.Forms.ImageList Bitmaps;
//  usw.
//  in InitializeComponents() steht u.a.:
this.btn.ImageAlign = System.Drawing.ContentAlignment.MiddleLeft;
this.btn.ImageIndex = 11;
this.btn.ImageList = this.Bitmaps;
this.btn.Name = "btn";
this.btn.TabIndex = 5;
this.btn.Text = "&Dialog ausführen";
//  usw. }
Variante 2 a definiert zunächst ein Basisformular zf_Vorlage in einer getrennten Assembly 1 mit Verweis auf eine ImageList in einer Assembly 2:
Code:
public class zf_Vorlage : System.Windows.Forms.Form   {
//  Standardverweise
protected System.Windows.Forms.ImageList gb = null;
//  die ImageList wird im Konstruktor unmittelbar nach InitializeComponents()
//  über eine GetSingleton-Prozedur geholt:
gb = JThomas.Configs.Globale_Instanzen.Get_Bitmap_Liste();
//  usw.
Das eigentliche Formular wird davon abgeleitet. Im Designer (Borland-IDE) kann die Bitmap zugeordnet werden:
Code:
public class zf_Haupteingabe : JThomas.Forms.Vorlage.zf_Vorlage   {
private System.Windows.Forms.Button button1;
//  in InitializeComponents() steht u.a.:
//  gb
this.gb.ImageStream = ((System.Windows.Forms.ImageListStreamer)(resources.GetObject("gb.ImageStream")));
//  button1
this.button1.ImageIndex = 1;
this.button1.ImageList = this.gb;
this.button1.Location = new System.Drawing.Point(344, 287);
this.button1.Name = "button1";
this.button1.Size = new System.Drawing.Size(23, 23);
this.button1.TabIndex = 44;
//  usw.
Im Designer ist die Bitmap auf diesem Button sichtbar, aber zur Laufzeit nicht! Warum nicht?

Variante 2 b erzeugt weitere Buttons zur Laufzeit (d.h. ohne Designer) wie folgt:
Code:
//  im Konstruktor nach InitializeComponents() z.B.:
CreateButton("button2", "", this.groupHaupt, 1, 345, 287, 23, 23, 32);
//  unter Verwendung der folgenden Methode:
private void CreateButton(System.String sName, System.String sText, Control Parent,
    int iImage,   int iLeft, int iTop, int iWidth, int iHeight, int iTabIndex) {
Parent.SuspendLayout();
System.Windows.Forms.Button ctl = new System.Windows.Forms.Button();
Parent.Controls.Add(ctl);
//
//  Eigenschaften zuordnen
ctl.Location = new System.Drawing.Point(iLeft, iTop);
ctl.Name = sName;
ctl.TextAlign = ContentAlignment.MiddleCenter;
ctl.Size = new System.Drawing.Size(iWidth, iHeight);
ctl.TabIndex = iTabIndex;
//
//  Image zuordnen, sofern vorgesehen
if (iImage >= 0) {
   ctl.ImageIndex = iImage;
   ctl.ImageList = this.gb;
   ctl.Refresh();  }
Parent.ResumeLayout();   }
Dabei ist im Designer natürlich nichts zu sehen. Die Buttons werden zur Laufzeit angezeigt, aber die Bitmaps nicht.

Der Debug-Inspektor sagt zur Laufzeit (im letzten Code-Schnipsel bei der Zuordnung "ctl.ImageList = this.gb;"):
Zitat:

gb: ImageList
imageCollection - null reference
Wie kann gb seine Bilder verloren haben (im Designer sind sie vorhanden!), und wie kann ich sie "zur Laufzeit behalten"?

Wer kann mir Hinweise geben? Danke! Jürgen

PS. Ich wünsche keine Diskussion über die Aufteilung in verschiedene Assemblies, die Konstruktion über ein Basisformular, eine allgemein verwendete Bitmap-Liste u.dgl. Über die Konzeption habe ich mir so viele Gedanken gemacht, dass es dabei bleibt. Basta! Mir geht es darum, wann und wie die Bitmaps sichtbar gemacht werden können; nur insofern sind Änderungen an dieser Konzeption möglich.

Jürgen Thomas 23. Aug 2006 10:10

Re: Button.Image (d.h. Bitmap) wird nicht angezeigt
 
Liegt das Problem vielleicht in der Reihenfolge, in der der Initialisierungs-Code abgearbeitet wird?

Ich vermute, dass NET so arbeitet:
Zitat:

1. Konstruktor von zf_Haupteingabe aktiviert den Konstruktor von zf_Vorlage.
2. Konstruktor von zf_Vorlage ruft InitializeComponent().
3. Konstruktor von zf_Vorlage aktiviert die ImageListe:
Code:
gb = JThomas.Configs.Globale_Instanzen.Get_Bitmap_Liste();
4. Konstruktor von zf_Haupteingabe ruft InitializeComponent().
5. Dort werden die Bitmaps zugeordnet:
Code:
this.gb.ImageStream = ((System.Windows.Forms.ImageListStreamer)(resources.GetObject("gb.ImageStream")));
//  keine Änderung liefert:
this.gb.ImageStream = ((System.Windows.Forms.ImageListStreamer)(resources.GetObject("base.gb.ImageStream")));
6. Anschließend greifen die Buttons auf die ImageList zu:
Code:
this.button1.ImageIndex = 1;
this.button1.ImageList = this.gb;

Wenn diese Reihenfolge stimmt, müssten die Bitmaps zur Laufzeit zugeordnet werden können. Da sie nicht angezeigt werden, stimmt darin irgendetwas nicht. Aber was???

Hilfe!!! Jürgen

Nachtrag: Das Problem scheint ganz woanders zu liegen. Ich habe jetzt bei button1 die ImageList entfernt und die Bitmap gezielt geladen. Im Designer wird die Bitmap angezeigt, aber zur Laufzeit nicht. Hilfe!!!

@Mods: Ich habe dies bewusst als neuen Beitrag eingetragen, damit man in der Forums-Übersicht sieht, dass sich jemand Gedanken über das Problem macht (nämlich ich) - in der Hoffnung, dass jemand anderes einen Lösungsweg beisteuert.

Elvis 27. Aug 2006 00:29

Re: Button.Image (d.h. Bitmap) wird nicht angezeigt
 
Liste der Anhänge anzeigen (Anzahl: 1)
Ich habe leider keine 1.1 IDE zur Hand, aber in 2.0 kann ich ein Form nehmen und dort eine imagelist füllen. Diese auf protected setzen und in einem abgeleiteten Form die Bilder benutzen (auch zur Laufzeit).
Wichtig ist dabei den FlatStyle des Buttons nicht auf System zu setzen. Sonst hast du unter XP keine Bildschens. ;-)
Unter .Net 1.1 musst du ein XP Maifest dazulegen um die Buttons mit XP Style und Bild zu bekommen.
Kann auch sein, dass ich das falsch in Erinnerung habe, bin kein versierter GUI-Schrauber und 1.1 ist schon etwas her. ;)

btw: ImageListen sind spätestens mit 2.0 out. Sie sind ziemlich zickig, da sie nur Wrapper um zickige WinAPIs sind, und die ganzen neuen Controls benutzen keine ImageListen mehr. Dort legt man direkt im Designer die Bilder als Resource an und kann auch auf die Resourcen der App zugreifen. Bevor du dich also zu sehr mit ImageLists verausgabst... ;)

Jürgen Thomas 27. Aug 2006 11:49

Re: Button.Image (d.h. Bitmap) wird nicht angezeigt
 
Zitat:

Zitat von Elvis
Wichtig ist dabei den FlatStyle des Buttons nicht auf System zu setzen. Sonst hast du unter XP keine Bildschens.

Danke, aber das kann es nicht sein: Der Debugger zeigt, dass alle Buttons auf FlatStyle = Standard stehen. Außerdem hatte ich in meiner ursprünglichen Frage darauf hingewiesen, dass die Inhalte der ImageList verlorengegangen sind:
Zitat:

Der Debug-Inspektor sagt zur Laufzeit (im letzten Code-Schnipsel bei der Zuordnung "ctl.ImageList = this.gb;"):
gb: ImageList / imageCollection - null reference
Was kann los sein? Jürgen

Zitat:

Zitat von Elvis
btw: ImageListen sind spätestens mit 2.0 out. Sie sind ziemlich zickig, da sie nur Wrapper um zickige WinAPIs sind, und die ganzen neuen Controls benutzen keine ImageListen mehr. Dort legt man direkt im Designer die Bilder als Resource an und kann auch auf die Resourcen der App zugreifen. Bevor du dich also zu sehr mit ImageLists verausgabst... ;)

Noch ein Grund mehr (siehe meine anderen "eigenen" Themen), eine Alternative für 2.0 zu suchen.

mikejn 29. Aug 2007 17:34

Re: Button.Image (d.h. Bitmap) wird nicht angezeigt
 
Folgende Änderungen sollten funktionieren und stilistisch korrekt sein:
  • Member gb als private deklarieren
  • neue Property, z.B. GB einfügen, welche nur einen get-Accessor hat und gb zurückliefert
  • diese neue Property mit dem Attribut DesignerSerializationVisibility(DesignerSerializat ionVisibility.Hidden) versehen
  • ggf. auch noch das Attribut ReadOnly(true), da es sich um eine globale Instanz handelt
Diese Änderungen bewirken, daß in abgeleiteten Formularen kein Code für den Member gb bzw. die
Property GB generiert wird. Dieses ist ja auch nicht erwünscht, da der Member über eine global
Methode im Konstruktor der Basisklasse initialisiert wird.

Falls denoch Änderungen an der ImageList in abgeleiteten Formularen ermöglicht werden sollen, so
kann mit DesignerSerializationVisibility.Content und der zu erstellenden Methode ShouldSerializeGB
gearbeitet werden.

mikejn 30. Aug 2007 18:07

Re: Button.Image (d.h. Bitmap) wird nicht angezeigt
 
Upps, die anderen Postings stammen ja aus August 2006 und nicht August 2007.
Da bin ich wohl etwas zu spät gekommen. :dancer:


Alle Zeitangaben in WEZ +1. Es ist jetzt 10:30 Uhr.

Powered by vBulletin® Copyright ©2000 - 2025, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024 by Thomas Breitkreuz