Willkommen auf myCSharp.de! Anmelden | kostenlos registrieren
 | Suche | FAQ

Hauptmenü
myCSharp.de
» Startseite
» Forum
» Suche
» Regeln
» Wie poste ich richtig?

Mitglieder
» Liste / Suche
» Wer ist online?

Ressourcen
» FAQ
» Artikel
» C#-Snippets
» Jobbörse
» Microsoft Docs

Team
» Kontakt
» Cookies
» Spenden
» Datenschutz
» Impressum

  • »
  • Portal
  • |
  • Mitglieder
Beiträge von psy
Thema: WindowsForm fixiert auf dem Desktop
Am im Forum: GUI: Windows-Forms

Hi designerfreak,

zu 3.) Autostart von Windows
zu 4.)

mit


      protected override void WndProc(ref Message m)
      {
         const int WM_NCHITTEST = 0x84;
         const int HTCAPTION = 0x02;
         const int HTCLIENT = 0x01;

         base.WndProc(ref m);
         if (m.Msg == WM_NCHITTEST && (int)m.Result == HTCAPTION) 
         {
            m.Result = (IntPtr)HTCLIENT;
         }
      }

wird die form fixiert.


Grüße,

psy

Thema: Custom Control Attribute Problem?
Am im Forum: GUI: Windows-Forms

Hi kpatrickk,

du musst das Attribute DesignerSerializationVisibility auf

[DesignerSerializationVisibility(DesignerSerializationVisibility.Visible)]

setzen.


Grüße,

psy

Thema: Austausch von Grafik / zu hohe Przessorlast
Am im Forum: Grafik und Sound

Hi Thomas Wüst,

die Hintergrundgrafik nicht über OnPaint und DrawImage zeichnen, sondern
einfach als BackgroundImage der Form setzen.


Grüße,

psy

Thema: gridItem in PropertyGrid ein IsChanged-Attribut hinzufügen
Am im Forum: GUI: Windows-Forms

Hi JunkyXL,


ich glaube er wollte auch Änderungen zum Momentan- und nicht Standardwert haben.
Zudem gibt es Properties die kein DefaultValue haben können (zumindest nicht über das Attribute).
Und da ist die Variante, die ich beschrieben habe, zwar kompliziert, aber wesentlich flexibler.


Grüße,

psy

Thema: gridItem in PropertyGrid ein IsChanged-Attribut hinzufügen
Am im Forum: GUI: Windows-Forms

Hi antoschka,

Erstmal ein Attribute anlegen:


   [AttributeUsage(AttributeTargets.Property)]
   public class ValueChangedAttribute : Attribute
   {
      private bool itsIsChanged = false;

      public bool IsChanged
      {
         get
         {
            return itsIsChanged;
         }
         set
         {
            itsIsChanged = value;
         }
      }


      public ValueChangedAttribute()
      {
      }
   }

Dann eine kleine Testklasse zur Demonstration

 
   public class TestClass
   {
      private int itsTestValue = 0;


      [ValueChangedAttribute()]
      public int TestValue
      {
         get
         {
            return itsTestValue;
         }
         set
         {
            itsTestValue = value;
         }
      }



      public TestClass()
      {
      }
   }


Und eine kleine Test-Anwendung


      // Anmelden
      private void button1_Click(object sender, System.EventArgs e)
      {
         propertyGrid1.SelectedObject = itsTestClass;

         propertyGrid1.PropertyValueChanged += new PropertyValueChangedEventHandler(propertyGrid1_PropertyValueChanged);
      }

      // Value Changed setzen
      private void propertyGrid1_PropertyValueChanged(object s, PropertyValueChangedEventArgs e)
      {                  
         object aAttribute = e.ChangedItem.PropertyDescriptor.Attributes[typeof(ValueChangedAttribute)];
         if (aAttribute != null)
         {
            ((ValueChangedAttribute)aAttribute).IsChanged = true;
         }
      }

      // Abfrage
      private void button2_Click(object sender, System.EventArgs e)
      {
         string aText = "";

         PropertyDescriptorCollection aCol = TypeDescriptor.GetProperties(itsTestClass);
         foreach (PropertyDescriptor aProp in aCol)
         {
            object aAttribute = aProp.Attributes[typeof(ValueChangedAttribute)];
            if (aAttribute != null)
            {
               aText += aProp.Name + ", changed: " +  ((ValueChangedAttribute)aAttribute).IsChanged.ToString() + "\r\n";
            }
         }

         MessageBox.Show(aText);
      }


Zuerst mal das Objekt (eine TestClass) dem Grid übergeben, dabei (EINMAL) an den Event (PropertyValueChanged) anmelden.
Dann erscheint die Klasse im Grid.
Solltest du jetzt den Status abfragen, ist dieser "false" (also nix geändert).
Änderst du jetzt das TestValue im Grid (zb von 0 auf 1) und fragst wieder ab,
bekommst du die Information dass der Status "true" ist, das Property wurde also geändert.


Grüße,

psy

Thema: Picturebox Kordinaten mit der Maus bestimmen?
Am im Forum: Grafik und Sound

Hi Herzog,

der Code im Beispiel ist beim besten Willen nicht zu kompliziert.
Wenn du damit Probleme hast, siehts eh schlecht mit C#-Programmierung aus

Aber der Ablauf ist ganz einfach:

- bei der PictureBox den MouseDownEvent anmelden
- wenn der Event ausgelößt wird, bekommst du in den MouseEventArgs (Parameter der Funktion) die X- / Y-Koordinaten.
- diese einfach merken und nutzen

Fertsch


Grüße,

psy

Thema: LinearGradientBrush nur Start- und Endpunkt ändern
Am im Forum: Grafik und Sound

Hi Schnueggel,

Matrixtransformierung ist genau das Stichwort.

Folgender Code zeigt wie einfach es geht


         Image aImage = new Bitmap(pictureBox1.Width, pictureBox1.Height);
         Graphics aGraphics = Graphics.FromImage(aImage);
         aGraphics.Clear(Color.White);

         Rectangle aRect = new Rectangle(0, 0, 50, 50);
         LinearGradientBrush aBrush = new LinearGradientBrush(aRect, Color.Black, Color.Blue, 0.0f);

         aBrush.TranslateTransform(20, 20);
         aGraphics.FillRectangle(aBrush, new Rectangle(20, 20, 50, 50));

         aBrush.TranslateTransform(80, 0);
         aGraphics.FillRectangle(aBrush, new Rectangle(100, 20, 50, 50));

         pictureBox1.Image = aImage;        
         aGraphics.Dispose();

Wenn du also zb nur den Start und Endpunkt ändern willst, reicht ne Translation.


Grüße,

psy


PS: Thema bitte nach Grafik und Sound verschieben.

Thema: PropertyGrid Farbe bei ReadOnly und anderes
Am im Forum: GUI: Windows-Forms

Hi Term!nX,

zu 3.) Wie Programmierhans schon sagte, muss Refresh vom GUI-Thread kommen.
Also entweder BeginInvoke oder Windows.Forms.Timer

RefreshProperties wird dein Problem nicht lösen, da dieses Attribute nur ein Repaint auslößt wenn sich ein Property im GRID ändert (und nicht in der Klasse selbst).


Grüße,

psy

Thema: GDI+ & OutOfMemoryException
Am im Forum: Grafik und Sound

Hallo,


es geht noch speicherschonender, wenn du bei den Pens nur Farbe und Breite änderst und bei den Brushs nur die Farbe änderst. Dabei musst du aber deine Zeichenreihenfolge beachten.
Denn genau diese Properties kann du ändern, ohne das GDI-Objekt neu instanziieren zu müssen (im Gegensatz zum Font.Size, etc).
Du kannst also nur einen globalen Pen und einen globalen Brush anlegen und deine Get-Funktionen entsprechend anpassen.


        /// <summary>
        /// Übergibt ein Pen-Objekt
        /// </summary>
        /// <param name="color">Farbe des Pens</param>
        /// <returns>der Pen</returns>
        public Pen GetPen(Color color)
        {
            itsGlobalPen.Color = color;

            return itsGlobalPen;
        }

        /// <summary>
        /// Übergibt ein Pen-Objekt
        /// </summary>
        /// <param name="color">Farbe des Pens</param>
        /// <param name="size">Größe des Pens</param>
        /// <returns>der Pen</returns>
        public Pen GetPen(Color color, float size)
        {
            itsGlobalPen.Color = color;
            itsGlobalPen.Width = size;

            return itsGlobalPen;
        }

Der Nachteil:

Pen aRedPen = GetPen(Color.Red)
Pen aGreenPen = GetPen(Color.Green)

und dann zeichnen mit beiden Stiften geht NICHT. (beide wären grün)
Du musst deine Reihefolge beachten und immer den Pen neu holen, falls du mit einer anderen Farbe zeichnen willst.

Grüße,

psy

Thema: Schlieren bei LinearGradientBrush minimieren?
Am im Forum: Grafik und Sound

Hi bear99,

Zitat
Wenn ich ein Dialogfenster (Einstellungen, Info, ...) über der Main Form Bewege dann sieht man deutlich das Neuzeichnen, darum ging es mir

probiere doch einfach mal mein Beispiel aus ... es wird nix neugezeichnet, auch wenn ein Dialog drüber geschoben wird. Warum das so ist, habe ich ja schon erwähnt ...

Grüße,

psy

Thema: GDI+ & OutOfMemoryException
Am im Forum: Grafik und Sound

ich habe mit den neune Listen-Klassen noch nicht gearbeitet, deswegen weiß ich nicht ob die generischen Listen Dispose haben und für ihre enthaltenen Objekte auf IDisposable prüfen und ggfs aufrufen ....

Auf Nummer Sicher gehst du aber auf jedenfall, wenn du selbst die Listen-Elemente durchläufst und selbst Dispose für jedes einzelne Element aufrufst.

EDIT: unmanaged Code kann ich auch net erkenne

Grüße,

psy

Thema: Schlieren bei LinearGradientBrush minimieren?
Am im Forum: Grafik und Sound

Echt?

using System;
using System.Drawing;
using System.Drawing.Drawing2D;
using System.Collections;
using System.ComponentModel;
using System.Windows.Forms;
using System.Data;

namespace WindowsApplication1
{
	public class Form1 : System.Windows.Forms.Form
	{
      private System.Windows.Forms.PictureBox pictureBox1;
		private System.ComponentModel.Container components = null;

		public Form1()
		{
			InitializeComponent();

         DrawBackGround();
		}

		/// <summary>
		/// Die verwendeten Ressourcen bereinigen.
		/// </summary>
		protected override void Dispose( bool disposing )
		{
			if( disposing )
			{
				if (components != null) 
				{
					components.Dispose();
				}
			}
			base.Dispose( disposing );
		}

		#region Vom Windows Form-Designer generierter Code
		/// <summary>
		/// Erforderliche Methode für die Designerunterstützung. 
		/// Der Inhalt der Methode darf nicht mit dem Code-Editor geändert werden.
		/// </summary>
		private void InitializeComponent()
		{
         this.pictureBox1 = new System.Windows.Forms.PictureBox();
         this.SuspendLayout();
         // 
         // pictureBox1
         // 
         this.pictureBox1.Dock = System.Windows.Forms.DockStyle.Fill;
         this.pictureBox1.Location = new System.Drawing.Point(0, 0);
         this.pictureBox1.Name = "pictureBox1";
         this.pictureBox1.Size = new System.Drawing.Size(728, 525);
         this.pictureBox1.TabIndex = 0;
         this.pictureBox1.TabStop = false;
         this.pictureBox1.SizeChanged += new System.EventHandler(this.pictureBox1_SizeChanged);
         this.pictureBox1.Layout += new System.Windows.Forms.LayoutEventHandler(this.pictureBox1_Layout);
         // 
         // Form1
         // 
         this.AutoScaleBaseSize = new System.Drawing.Size(5, 13);
         this.ClientSize = new System.Drawing.Size(728, 525);
         this.Controls.Add(this.pictureBox1);
         this.Name = "Form1";
         this.Text = "Form1";
         this.ResumeLayout(false);

      }
		#endregion

		/// <summary>
		/// Der Haupteinstiegspunkt für die Anwendung.
		/// </summary>
		[STAThread]
		static void Main() 
		{
			Application.Run(new Form1());
		}

      private void pictureBox1_Layout(object sender, System.Windows.Forms.LayoutEventArgs e)
      {
      DrawBackGround();
      }

      private void pictureBox1_SizeChanged(object sender, System.EventArgs e)
      {
      DrawBackGround();
      }

      private void DrawBackGround()
      {
         Image aImage = new Bitmap(pictureBox1.Width, pictureBox1.Height);
         Graphics aGraphics = Graphics.FromImage(aImage);
         Rectangle aRect = new Rectangle(0, 0, pictureBox1.Width, pictureBox1.Height);

         LinearGradientBrush aBrush = new LinearGradientBrush(aRect, Color.Red, Color.Yellow, 0.0f);
         aGraphics.FillRectangle(aBrush, aRect);

         pictureBox1.Image = aImage;

         aGraphics.Dispose();
         aBrush.Dispose();
      }
	}
}


keine schlieren ... nix.

Grüße,

psy

Thema: GDI+ & OutOfMemoryException
Am im Forum: Grafik und Sound

Hi PhilHol,

Zitat
oh ja eine Frage hab ich noch... Wenn ich GDI Objekte innerhalb von einer Funktion erstelle, werden diese bei beendigung der funktion auch wieder zerstört ? oder soll ich auch da dispose vorher aufrufen ?

Dispose MUSS aufgerufen werden, wenn du Using nicht verwendest... auch innerhalb einer Funktion.
Normalfall ist sehr relativ ... du musst dir das so vorstellen. Wenn du zb new Pen sagst, trägt sich dieser Pen im hintergrund in einer Art Table ein um schnellen zugriff zu sichern und Speicher zu reservieren. Sagst du nun NICHT Dispose bleibt dieser Pen während der Laufzeit ewig in dieser Table ....

Zitat
Bzw. Würde mir die IDisposable Implementierung eigentlich leider nichts bringen, da die GDI Objekte ja alle immer nur innerhalb von Funktionen gültig sind .. Oder seh ich das Falsch ? .. d.h. besser wäre es, wenn ich using verwende immer innerhalb der funktionen

Also ich habe selbst eine komplexe GDI Anwendung geschrieben und nach einigem Testen bin ich auf folgende Lösung was ZeichenObjekte wie Pens und Brushs angeht gekommen:

- Instanziieren von Zeichen Objekten kosten recht viel Zeit, Speicher und Dispose muss beachtet werden: alle diese Probleme lösst eine statische BackroundHasttable.

Diese wird bei Programmstart instaziiert, bei Programmende verworfen. Während der Ausführung brauchen verschiedene Objekte zu verschiedenen Zeiten verschieden Pens / Brushes. Dazu gibt es dann die statische Methode GetBrushByColor(Color theColor). Diese macht nix anderes, als in der hashtable über die Color (==key) zu schauen ob der Eintrag existiert und im erfolgfalls das Objekt (== Brush) zurückzuliefern oder wenn diese nicht existiert, einen neue Eintrag in der Hashtable zu machen, wo ein neuer Brush instaziiert wird (mit der entsprechenden Farbe). Der Vorteil: wenn verschiedene Objekte einen Brush zb mit der Farbe Blau benötigen, wird dieser Brush genau EINMAL instanziiert. danach erfolgt der Zugriff Just-In-Time. Über das Dispose brauchst du dir auch keine Gedanken zu machen, da dies ja erst zur Programmbeendigung nötig ist. Zudem wird ja nur eine definierte Anzahl von Objekten erstellt, welche du ggfs wiederverwendest.
Diese Methode ist äußerst effektiv, wenn du sichergehen kann, dass nur eine bestimmte Zahl von verschiedenfarbigen Brushes / Pens benötig wird. Zeichnest du mit 1000 verschiedenen farben, musst du dir selbst was einfallen lassen
Zitat
Bezüglich Exception .. Ich bin ein sehr "ängstlicher" Mensch und habe zumindest in jeder Funktion, die mit GDI+ Elementen arbeitet ein try-catch eingebaut .. Ist das sinnlos ? Soll ich annehmen dass sowas immer klappt oder doch drinnen lassen ?

theoreitsch sollte es reichen, wenn du in der Hauptzeichenroutine gehst und dort mit try-catch arbeitest.


Grüße,

psy

Thema: Font Ascend, Descend und Leading
Am im Forum: Grafik und Sound

13 Jahre altes Programm portieren ....

Na dann viel Spaß noch

Thema: Font Ascend, Descend und Leading
Am im Forum: Grafik und Sound

Hmm ich will dich ja nicht nerven, aber selbst zum Zeichnen einer Table
brauchst du das nicht.
Ich habe mal quick'n'dirty etwas Code geschrieben und ein Bild angehangen.

Sollte das nicht reichen?


         // Table erstellen
         DataTable aTable = new DataTable();
         aTable.Columns.Add(new DataColumn("Spalte 1"));
         aTable.Columns.Add(new DataColumn("Spalte 2"));
         aTable.Columns.Add(new DataColumn("Spalte 3"));
         aTable.Rows.Add(new object[] {"Wert 1", "Wert 2", "Wert 3"});
         aTable.Rows.Add(new object[] {"Wert 4", "Wert 5", "Wert 6"});
         aTable.Rows.Add(new object[] {"Wert 7", "Wert 8", "Wert 9"});        

         // Bild
         Image aImage = new Bitmap(pictureBox1.Width, pictureBox1.Height);

         // Graphics zum Zeichnen
         Graphics aGraphics = Graphics.FromImage(aImage);
         aGraphics.SmoothingMode = SmoothingMode.HighQuality;

         // StringFormat
         StringFormat aStringFormat = new StringFormat();
         aStringFormat.Alignment = StringAlignment.Center;
         aStringFormat.LineAlignment = StringAlignment.Center;

         // Font
         Font aFont = new Font("Arial", 11.0f);

         // BorderPen
         Pen aBorderPen = new Pen(Color.Blue, 2.0f);

         // FontBrush
         SolidBrush aFontBrush = new SolidBrush(Color.Black);

         // StartPos
         Point aPos = new Point(10, 10);

         // Cells
         foreach (DataRow aDataRow in aTable.Rows)
         {
            object[] aRow = aDataRow.ItemArray;

            Rectangle aRect = new Rectangle(0, 0, 1, 1);
            foreach (object aRowEntry in aRow)
            {
               Size aSize = aGraphics.MeasureString(aRowEntry.ToString(), aFont, 500, aStringFormat).ToSize();
               aRect = new Rectangle(aPos, aSize);

               // Celle vergrößern, damit Text etwas mehr Platz hat
               aRect.Inflate(5, 5);

               aGraphics.DrawString(aRowEntry.ToString(), aFont, aFontBrush, aRect, aStringFormat);
               aGraphics.DrawRectangle(aBorderPen, aRect);

               aPos.X += aRect.Width + 5; // Zwischenraum X-Richtung
            }

            aPos.X = 10;
            aPos.Y += aRect.Height + 5; // Zwischenraum Y-Richtung
         }

         // Zuweisung
         pictureBox1.Image = aImage;
         // Dispose
         aGraphics.Dispose();
         aStringFormat.Dispose();
         aFont.Dispose();
         aBorderPen.Dispose();
         aFontBrush.Dispose();

Grüße,

psy

Thema: Font Ascend, Descend und Leading
Am im Forum: Grafik und Sound

Hi KenshinX,


ja, jetzt bin ich wohl schlauer . Die Frage ist aber nach wie vor, ob
du diese Werte überhaupt brauchst. Und zum Ausrichten brauchst du sie halt nicht.

Grüße,

psy

Thema: Font Ascend, Descend und Leading
Am im Forum: Grafik und Sound

Hallo,


was meint ihr denn mit "Ausrichten"?
Wenn es darum geht, einen Text in einem Bereich (Rectangle) auszurichten, gibt es
die Klasse StringFormat.


Grüße,

psy

Thema: PropertyGrid Farbe bei ReadOnly und anderes
Am im Forum: GUI: Windows-Forms

Hallo Term!nX,

zu 1. Ein leerer Setter


Grüße,

psy

Thema: RichTextBox Schrift mehrfarbig
Am im Forum: GUI: Windows-Forms

Hi Dr.Z,


ok, dann erkläre ich es ganz genau:

- du fügt eine neue Zeile mit "+=" hinzu
- die TextBox verwirft alle Formatierungen, es passiert aber nix, da ja noch kein Text vorhanden ist
- die markierte Zeile (== die neue Zeile) wird schwarz markiert (SelectionColor = Color.Black)
[Bis hierhin alles super]
- du fügst wieder eine neue Zeile hinzu
- wieder verwirft die TextBox alle Formatierungen, dh alle Texte bekommen den Standard-Font und die Standard-Farbe (welche Defaultmäßig schwarz ist).
- die erste Zeile verliert also die Formatierung und wird mit Standard-Einstellungen gezeichnet (== Schwarz).
- die markierte Zeile (== neue Zeile == 2. Zeile) wird grün markiert
[Hier hat bereits der Fehler stattgefunden, du hast es nur nicht gemerkt, da deine Formatierung der ersten Zeile gleich der Standard-Formatierung ist]
- jetzt kommt Zeile 3 und es geht genauso fröhlich weiter (also alle Formatierungen werden gelöscht == alle Zeilen im Standard-Format) und die neue Zeile bekommt die gesetzte Farbe.

ich hoffe alle Fragen sind geklärt.


Grüße,

psy

Thema: RichTextBox Schrift mehrfarbig
Am im Forum: GUI: Windows-Forms

Hallo Dr.Z,


wenn du einer RichTextBox neuen Text mit

richTextBox1.Text += aLine;

zufügst, dann registiert dies die TextBox als würde der komplett neuer Text gesetzt werden. (+= ruft zuerst GETTER dann SETTER des Properties ab, und im SETTER wird der neue Text, welcher aus alter Text + aLine besteht, gesetzt).
Dadurch verfallen sämtliche Formatierungen!

Dadurch entweder Methode 1: den ganzen Text checken und neu formatieren (diese Methode ist Pflicht, falls komplexe Änderungen stattfinden)
oder Methode 2: du fügst den String per "AppendText"-Funktion hinzu. Mit dieser Funktion registriert die TextBox lediglich einen hinzugefügten Teil-String, welcher die aktuelle Formatierung bekommt (hast du also vorher SelectionColor auf Blue gesetzt, bekommt auch dieser neue String eine blaue Farbe). Diese Methode ist natürlich wesentlich schneller, aber unflexibler.


Grüße,

psy

Thema: RichTextBox Schrift mehrfarbig
Am im Forum: GUI: Windows-Forms

Hi Dr.Z,


probiere mal folgendes:


      private void button1_Click(object sender, EventArgs e)
      {
         string aLine = "Dies ist ein Test\r\n";

         richTextBox1.Text += aLine;
      }

      private void richTextBox1_TextChanged(object sender, EventArgs e)
      {
         string aSeperator = "\r\n";
         string[] aSplittedString = richTextBox1.Text.Split(aSeperator.ToCharArray());

         int aStart = 0;
         for (int i = 0; i < aSplittedString.Length; i++)
         {
            richTextBox1.SelectionStart = aStart;
            richTextBox1.SelectionLength = aSplittedString[i].Length + 1;

            if (i%2 == 0)
               richTextBox1.SelectionColor = Color.Black;
            else
               richTextBox1.SelectionColor = Color.Green;

            aStart += aSplittedString[i].Length + 1;
         }
      } 

Logik: Der kompletter Text wird aufgrund eines Trennzeichens ("\r\n" == NEWLINE) gesplittet. Die einzelnen Zeilen werden durchlaufen und in jeder Zeile eine bestimmte farbe gesetzt (hier: einfach jede 2. Grün).

Grüße,

Psy

Thema: Forms-Anwendung mit mehreren Fenster. Wie am besten anzeigen?
Am im Forum: GUI: Windows-Forms

Hallo cptjmiller,

also wenn ich dich richtig verstanden habe, willst du eigentlich nur von deinem Hauptfenster aus ein "Unterfenster" öffnen, sodass dies sichtbar ist, aber dein Hauptfenster soll weiterhin aktiv bleiben ....

dann versuch mal nur "Show" statts "ShowDialog".
Wenn du dann willst, dass das "Unterfenster" noch sichtbar ist, auch wenn die Hauptform aktiv ist (wie zb bei der Suchfunktion in Visual Studio) dann musst du im "Unterfenster "das Property "TopMost" auf "true" setzen.


Grüße,

Psy

Thema: Usercontrols erst bei Gebrauch instanzieren
Am im Forum: GUI: Windows-Forms

Hallo ziescharpfrischling,

Instanzen von untypisierten Objekten zu erstellen ist eine ehr schlechte Idee .
es gibt mehrere Möglichkeiten und "CreateInstance" ist eine davon. Da du der keine Parameter übergibst, können auch nur UserControls erstellt werden, die parameterfreie Kontruktoren enthalten .... nicht sehr flexibel.
Eine flexiblere Variante sind Interfaces. Diese beinhalten zb eine Funktion namens "CreateDefaultInstance" (oder was auch immer ) und liefert ein "UserControl" zurück.
Jedes deiner komplexen UserControls (welche dann auch von Windows.Forms.UserControl abgeleitet sein müssen!), implementiert dieses Interface, und liefert in der Funktion eben eine neue Instanz von sich selbst zurück. In deiner Funktion "OpenUserControl" checkst du, ob dieser Interface implementiert ist (is-Operator) castest und rufst die Funktion "CreateDefaultInstance"auf.

Aber ganz im Ernst: du solltest dich fragen, ob dieser Aufwand wirklich nötig ist.
Warum willst du denn die Controls erst "OnDemand" instanziieren?


Grüße,

Psy

Thema: Schlieren bei LinearGradientBrush minimieren?
Am im Forum: Grafik und Sound

Hallo baer999,


die einfachste möglichkeit ist, einfach NICHT jedes mal neuzuzeichnen. Und die erreichst du beispielsweise mit Bitmaps.
Momentan hängst du dich in den OnPaintEvent rein oder?
Verwerfe das, und versuche folgende Schritte:
- einmalig (zb im Load-Event) ein Background-Bitmap mit deinem LinearGradientBrush erstellen
- dazu new Bitmap (in der Größe des Panels), dann über Graphics.FormImage() das Graphics-Objekt erstellen, dann über das Graphics-Objekt den Farbverlauf in das Bitmaps zeichnen, dann Graphics disposen und das Bitmap dem Panel als backgroundimage übergeben

jetzt wird der farbverlauf nicht mehr andauernd neugezeichnet. Der Nachteil ist halt, dass dieser auch nicht mehr neugezeichnet wird, wenn sich die Form (oder Panel) in der Größe ändert. Ist dies nötig, musst du dich in den SizeChangedEvent reinhängen und die selbe Funktion aufrufen.


Grüße,

Psy

Thema: [gelöst] Bitmap-Randproblem beim Verkleinern mit InterpolationMode.HighQualityBilinear
Am im Forum: Grafik und Sound

Hallo herbivore,


probier mal folgendes

ImageAttributes aImageAtt = new ImageAttributes();
aImageAtt.SetWrapMode(WrapMode.Clamp);

Rectangle aDestRect = new Rectangle(0, 0, bmpOutput.Width, bmpOutput.Height);
gOutput.DrawImage (bmpInput, aDestRect, 0, 0, bmpInput.Width, bmpInput.Height, GraphicsUnit.Pixel, aImageAtt);

Der WrapMode gibt ja den Umbruchbereich an für zu große (und auch für zu kleine Bitmaps).
Mit Clamp sagst du halt, dass ein möglicher Farbverlauf nicht über die Objekt-Grenze hinweg berechnet wird.


Grüße,

psy

Thema: Dynamisch veränderbarer Graph
Am im Forum: Grafik und Sound

Hi RitterChristian,


warum so umständlich? Es gibt doch für das Zeichnen von Graphen schon die sehr gute Bibliothek von ZedGraph.
Diese ist mächtig genug, damit du deine Probleme damit lösen kannst.

hier hast den Source und ein Wiki.


Grüße,

psy

Thema: .NET CF 2 : BMP zu JPEG, gaanz schwer :/
Am im Forum: Grafik und Sound

Ok, jetzt verstehe ich


vielleicht findest du ja hier eine freie Bibliothek für sowas (ist aber alles Java).


Grüße,

psy

Thema: .NET CF 2 : BMP zu JPEG, gaanz schwer :/
Am im Forum: Grafik und Sound

Hi Fabian,


bmp zu jpeg geht recht einfach, wenn du mit Image.FromFile das bmp lädst und danach
mit Image.Save als jpeg wieder speicherst (einfach Endung setzen oder ImageFormat).
Dies geht im normalen Framework super. Sollte dies vom "OPENnetCF Smart Device Framework" nicht unterstützt sein, musst du wohl einen komplett anderen Weg gehen.

Resize eines Bilder ist ähnlich einfach.
- per Image.FromFile das Original laden
- mit new Bitmap(new Width, new Height) das neue (kleinere) Bild anlegen
- Graphics auf das neue Bild legen (Graphics.FromImage)
- mit Graphics das große Bild ins kleine Bild zeichnen (aGraphics.DrawImage)
- Graphics schließen / verwerfen
- das kleine Bild speichern (Image.Save)


Grüße,

psy

Thema: Probleme mit Zed Graph - Diagramm verschoben zeichnen
Am im Forum: Grafik und Sound

Hui .. lange Suche kurzer Text ...

du musst myCurve.IsOverrideOrdinal auf true setzen.
dann sollte es gehen.


Grüße,

Psy

Thema: Probleme mit Zed Graph - Diagramm verschoben zeichnen
Am im Forum: Grafik und Sound

Hi Waldi,

die Punkte, welche du übergibst, haben nur einen Wert, in dem Fall: Y.
Ohne dazugehörige X-Werte, werden die Kurven nicht korrekt dargestellt.

Dazu einfach eine PunkteListe erstellen

PointPairList aList = new PointPairList();

diese füttern

aList.Add(new PointPair(X, Y));

dann dein CurveItem erstellen


            LineItem aCurve = new LineItem(aLegend, aList, 
            aColor, ZedGraph.SymbolType.Circle);

und adden

itsGraphControl.GraphPane.CurveList.Add(aCurve);

wenn du jetzt manuell die X-Werte auf TextLabels umbaust, zb so


         itsGraphControl.GraphPane.XAxis.Type = AxisType.Text;      
         itsGraphControl.GraphPane.XAxis.TextLabels = aXTextList;

dann sollte es funktionieren (sieht Anhang).

Grüße,

Psy