Laden...
B
Big Al myCSharp.de - Member
Student Mannheim Dabei seit 25.02.2006 342 Beiträge
Benutzerbeschreibung

Forenbeiträge von Big Al Ingesamt 342 Beiträge

24.04.2008 - 20:03 Uhr

Hallo,
I'm proud to present: ProjectDesigner.NET 2.0 Alpha
Der Download: am Anfang dieses Threads
Die Features:

  • Zoomfunktion
  • Plugins
  • wählbare Verbindungstypen
  • einfacheres Einfügen und auswählen von Membern über die Toolbar
  • Objektfunktionen
  • Mausgestensteuerung

Tipp: Wenn ihr Attribute benutzt und als Argument ein typeof() wollt, dann einfach unter ArgumentType "Type" eingeben.

Ich hoffe auf viel Feedback!
Big Al

05.03.2008 - 13:39 Uhr

Microsoft hat auf CodePlex den Sourcecode des Betriebssystems Singularity veröffentlicht. Das ist ein experimentelles OS, welches in CSharp geschrieben wurde. Der Quellcode steht unter deiner Lizenz, die kommerzielle Nutzung verbietet.
Hier ist der Link:
http://www.codeplex.com/singularity
Quelle:
Heise
//Edit: OK, es gibt ein paar weitere Lizenzbeschränkungen, siehe Beitrag von N1ls.
Danke für die Info!

19.02.2008 - 11:42 Uhr

Unter dem Namen DreamSpark verschenkt Microsoft unter anderem VisualStudio Professional und Expression Studio Studenten.

Original auf
>

DreamSpark is simple, it's all about giving students Microsoft professional-level developer and design tools at no charge so you can chase your dreams and create the next big breakthrough in technology - or just get a head start on your career.

Man kann sich mit der LiveID anmelden und verifizieren, dass man Student ist, allerdings ist das bis jetzt noch nicht so einfach, da in der Liste der Schulen und Universitäten bis jetzt nur 28 Einträge sind. Sie soll aber stetig erweitert werden.
Der Link im Zitat führt direkt zur Startseite.
//edit: nur für Studenten, nicht für Schüler

04.02.2008 - 10:51 Uhr

Hi Herbivore,
also es sieht so aus: In der Hauptassembly gibt es einen abstrakten Typ für Modell-Objekte für Klassendiagramme o.ä., die gezeichnet werden können. Jetzt gibt es eben Plugin-DLLs, die einen Typ enthalten, der von dieser abstrakten Klasse erbt.
Das wäre dann der ExtendedType, der also in der Plugin-Assembly ist.
Nun wird im Hauptprogramm in der Plugin-DLL nach Typen gesucht, die von der Basisklasse für Modellobjekte erben. Dann wird der Konstruktor gesucht und mit Invoke ausgeführt, so bekomme ich eine Instanz des in der Plugin-DLL enthaltenen Typs. Das neue Objekt wird dem Projekt hinzugefügt und dieses wird später zwecks Speicherung serialisiert. Dies geschieht auch wieder mit Hilfe der Plugin-Datei, die verschiedene Typen enthält, die von einer IObjectExporter-Schnittstelle erben.
Von diesen Exportern wird also auch eine Instanz erstellt und die Exporter-Typen befinden sich auch in der Plugin-DLL.
Das Hauptprogramm ruft also Exporter.Export(string filename, BaseModelObject o) auf, um das Objekt zu speichern.
Dann muss die Datei ja auch wieder geöffnet werden, dazu gibt es die IObjectImporter-Schnittstelle und alles läuft wie bei den Exportern ab, nur das jetzt halt die Datei geladen wird und die IObjectImporter.Import(string filename) ein BaseModelObject zurückliefern soll. Auch das funktioniert noch prima. Aber jetzt kommts blöd. Es gibt noch eine Schnittstelle, ICodeGenerator und diese wird von einigen Typen aus der Plugin-DLL implementiert. Alle Typen, die das Interface implementieren werden gesucht, es wird eine Instanz erstellt.
Jetzt hat der ICodeGenerator eine Methode "public bool CanGenerateCode(BaseModelObject o)". In dieser wird überprüft, ob von einem Objekt mit diesem CodeGenerator Sourcecode generiert werden kann. Alle Modell-Objekt-Typen in der Plugin-Assembly implementieren die Schnittstelle ICodeGenerateable, um deutlich zu machen, dass aus ihnen Code generiert werden kann. Die Schnittstelle liegt auch in der Plugin-DLL und wird nur gebraucht, damit die CanGenerateCode-Methode erkennt, ob es sich um das richtige Objekt handelt.
Das sollte einfach so geschehen:


public bool CanGenerateCode(BaseModelObject o)
{
      return o is ICodeGenerateable;
}

Hier wird immer false zurückgegeben und wenn ich zu Testzwecken direkt auf den Typ prüfe, also z.B. "return o is EnumerationModelObject;" kommt auch false raus, obwohl ich, wenn ich den Namen des Typs anzeigen lasse, genau "EnumerationModelObject" angezeigt wird.
So, jetzt glüht der Finger, ich hoffe das war einigermaßen verständlich.
Vielen Dank für die Mühe,
Big Al

03.02.2008 - 19:46 Uhr

Hi,
zu meinem Problem, ich versuche mal alles ganz genau zu schildern, auch wenn einiges vielleicht nicht so wichtig ist:
Ich habe eine abstrakte Klasse, ich nenne sie mal BaseType, welche in der Hauptassembly liegt. Von dieser Klasse erbt eine andere Klasse (ExtendedType), in einer anderen Assembly. Diese Assembly wird als Plugin eingebunden und es wird eine Instanz der Klasse "ExtendedType" erstellt. Diese wird später dann serialisiert.
Wenn ich die Datei nun wieder als "BaseType" deserialisiere und den Typ der deserialisierten Instanz überprüfe, dann kommt heraus, dass die Instanz nicht vom Typ "ExtendedType" ist. Ich habe das mit einer MessageBox überprüft:

obj ist die das deserialisierte Objekt und auf jeden Fall vom Typ "BaseType", müsste aber eigentlich auch ein ExtendedType sein.

MessageBox.Show((obj is ExtendedType).ToString() + " - " + obj.GetType().Name)

Heraus kommt dann:

false - ExtendedType

Der Name des Typs wird also richtig erkannt, nicht jedoch, dass es sich auch um eine Instanz des Typs handelt.
Ich hoffe ihr könnt mir weiterhelfen.

Viele Grüße,
Big Al

30.01.2008 - 11:42 Uhr

Ich glaube der Fehler wurde schon oft genug diskutiert! Benutze die Forumsuche.
Außerdem sollte ein Feld nicht public sein. Benutze Properties.
Big Al

25.01.2008 - 15:03 Uhr

Und hier sieht man, wie viele Leute so einen Bot haben wollen 😁Google Trends
Edit: besonders das hier:

Multi-species herbivore outbreak follows El Niño drought in Panama

Herbivore-Outbreak 😁

25.01.2008 - 11:50 Uhr

wer clever sucht, der kann dem bot herbivore auch ein Gesicht geben

Ach was clever, erster Google-Treffer:
Herbivore
😉

15.01.2008 - 07:48 Uhr

interessant wäre halt eine synchronisierung ohne das der iPod als laufwek erkannt wird. Die vCrad dateien zu erstellen und in den Ordner zu kopieren ist ja nicht so schwierig. Aber nicht jeder möchte seinen iPod als Laufwerk verwenden. ;o) Das geht sicher noch anders, iTunes kann's ja auch.

Genau das finde ich auch, aber vielleicht wird der Ipod ja nur im Arbeitsplatz nicht angezeigt. Ich werde mal ein paar Experimente machen. Der Quellcode von MozPod kann da sicher auch weiterhelfen.
Edit: Hier gibts den Code
Big Al

14.01.2008 - 10:34 Uhr

So, hab jetzt was gefunden.
Die Kontakte werden im VCard-Format gespeichert. Zum generieren einer solchen Card gibt es hier eine Klasse. So sollte es nicht allzu schwierig sein, so eine VCard auf den IPod zu kopieren.
Grüße,
Big Al

14.01.2008 - 07:54 Uhr

@SunboX
Klar, mach ich, bis jetzt gibts aber keine Ergebnisse.

13.01.2008 - 19:06 Uhr

Hi,
also bis jetzt hab ich den Source noch nicht veröffentlicht, der ist nicht so vollständig kommentiert. Vielleicht bei der nächsten Version...
Also das mit dem Verschieben geht so:
Im MouseMove-Ereignis speicherst du immer den Wert der Mausposition
Dann berechnest du aus dem aktuellen und dem vorigen Wert die Verschiebung
also:

xOffset = newMousePosition.X - oldMousePosition.X
yOffset = newMousePosition.Y - oldMousePosition.Y

Diese Werte speicherst du auch.
In der OnPaint-Methode "verschiebst" du dann die Graphics mit TranslateTransform und den Werten von xOffset und yOffset.

Big Al

13.01.2008 - 13:25 Uhr

Hi,
Sorry das ich mich erst jetzt melde!
Ich habe ein Adressbuch-Plugin für meinen ProjectDesigner geschrieben. Da würde ich gerne diese Funktion einbauen. Bei mir wird der IPod nicht als Wechseldatenträger eingebunden, auf jeden Fall sieht man ihn nicht im Arbeitsplatz.
Ich kann bei ITunes auswählen, mit welchem Programm der IPod sein Adressbuch synchronisieren soll.
Also, ich werd mich mal weiter umgucken,
Vielen Dank!
Big Al

13.01.2008 - 13:20 Uhr

Nein, dafür habe ich ein eigenes Control.
Über die Mausereignisse berechne ich die Verschiebung der Fläche.
In der OnPaint-Methode verschiebe ich dann die Graphics per TranslateTransform.
Die Objekte sind keine Controls sondern haben eine Draw(Graphics g) Methode, damit ich sie direkt auf die Fläche zeichnen kann.

12.01.2008 - 14:13 Uhr

Ja, eine Woche kommt hin, aber das war dann doch ziemlich unansehnlich.
Besonders die Erzeugung der CodeDom-Objekte hat etwas gedauert, zuerst hab ich den Code sogar hardcoded erzeugen lassen, bevor ich die Möglichkeiten von CodeDom erkannte.
An der neuen Version sitze ich schon ca. 6 Monate.
Grüße,
Big Al

10.01.2008 - 19:38 Uhr

Oh ja, ich arbeite auf Hochtouren, besonders jetzt in den Ferien.
Wahrscheinlich gibt es bald mal eine "Demo". Ich hab alles von Grund auf neu angelegt und das ganze Programm kann über Plugins erweitert werden.
Man kann dann also Neuronale Netze, Automaten oder Klassenmodelle designen und außerdem hab ich schon ein Adressbuch-Plugin in Arbeit.
Auf ein baldiges Release,
Big Al

10.01.2008 - 19:29 Uhr

Hi,
vielleicht in der Ereignisanzeige der Computerverwaltung?
Rechtsklick auf Arbeitsplatz-->Verwalten-->System-->Ereignisanzeige
Ich weiß nicht, ob da Informationen zum Bluescreen stehen, weil ich schon ewig keinen mehr hatte, aber man kann ja mal schauen.
Grüße,
Big Al

10.01.2008 - 16:27 Uhr

Hi,
Ich hab ein kleines Adressbuch geschrieben und möchte eine Funktion einbauen, die dieses mit dem IPod-Touch synchronisiert. Outlook kann das und ein Plugin für Thunderbird ermöglicht es auch, daher denke ich, dass es auch mit C# geht.
Hat jemand dazu nähere Infos?
Viele Grüße und Danke im Vorraus,
Big Al

01.01.2008 - 19:02 Uhr

Hi,
Visual Studio erstellt eine ausführbare Datei.
Je nach Version unter:
Eigene Dateien/Visual Studio 2005 bzw. 2008/Projects/dein Projektname/bin/Release
Ist es das, was du suchst?
Viele Grüße,
Big Al

19.12.2007 - 08:07 Uhr

Stimmt, kann passieren, aber dann bringt Apple gleich eine Firmware raus, die das wieder unmöglich macht 🙁

19.12.2007 - 07:49 Uhr

Ich glaube kaum, dass das geht, weil
1.: Mono ist für Linux
2.: IPhone und Ipod Touch sind abgeschottete Systeme und Apple will gar nicht, dass da jemand dafür externe Programme programmiert
Big Al

19.12.2007 - 06:26 Uhr

Sieht sehr gut aus! Muss jetzt zwar leider erst mal in die Schule, aber dann werd ichs gleich probieren!
@Andreas.May:
Normalerweise können generische Typen mit dem BinaryFormatter serialisiert werden, das habe ich schon öfter gmacht. Ich glaube du meinst XMLSerializer, oder?
Nochmal vielen Dank,
Big Al

18.12.2007 - 17:25 Uhr

Hi,
ich hab gerade ein ähnliches Problem und es scheint sich abzuzeichnen, dass man generische Typen nicht so leicht deserialisieren kann.
Hier mal der Link:
http://www.mycsharp.de/wbb2/thread.php?postid=260934#post260934
Grüße,
Big Al

18.12.2007 - 17:22 Uhr

Hi,
hab mir das jetzt mal angeguckt, aber leider gibt es ein Problem.
Man müsste für jeden generischen Typ einen eigenen Binder erstellen, was für mich aber blöd ist, da das ganze ja Plugins sind, und ich somit gar nicht weiß, welche Typen da so verwendet werden. Wenn also jemand weitere Vorschläge hat, dann immer her damit.
Big Al

18.12.2007 - 13:18 Uhr

Hi svenson, das sieht genau nach der Lösung aus, zu Hause werd ich mir das gleich mal angucken. Danke für die Hilfe.
Big Al

18.12.2007 - 11:33 Uhr

Hi Leute,
ich hab ein Problem beimn Serialisieren von Objekten.
Ich habe ein Programm, welches wiederum eine Assembly dynamisch lädt.
Diese enthält Exporter für Objekte meines Programms. Diese Objekte sind auch in der dynamisch geladenen Assembly enthalten und haben alle eine Basisklasse in meinem Hauptprogramm. Also ist der Verlauf ungefähr so:1.Hauptprogramm erzeugt Objektinstanz aus dyn. geladener Assembly 1.Objekt wird bearbeitet 1.Objekt soll mit Methode aus dyn. geladener Assembly serialisiert werden 1.Objekt soll mit Methode aus dyn. geladener Assembly deserialisiert und zurückgegeben werden

Nun trat der Fehler auf, dass der Deserializer die "eigene" Assembly nicht fand, da er ja über das Hauptprogramm gestartet wurde. Dieses Problem habe ich über einen überschriebenen SerializationBinder gelöst:


public class Binder : SerializationBinder
{
    public override Type 
        BindToType(string assemblyName, string typeName)
    {
        Type type = null;
        string shortAssem = assemblyName.Split(',')[0];
        Assembly[] assemblies = 
            AppDomain.CurrentDomain.GetAssemblies();

        foreach (Assembly assem in assemblies)
        {
            if (shortAssem == assem.FullName.Split(',')[0])
            {
                type = assem.GetType(typeName);
                break;
            }

        }
        return type;

    }

}

Dies funktioniert soweit auch ganz gut, solange das zu deserialisierende Objekt keine Instanzen generischer Typen enthält. Also z.B. List<string>, Collection<string>...
Dann nämlich wirft der BinaryFormatter eine SerializationException mit der Meldung, der zu deserialisierende Typ List´1<string> o.ä. könne nicht geladen werden.
Weiß jemand, woran das liegt und wie ich das Problem lösen kann?
Bin für alle Hinweise dankbar,
Big Al

//Edit: Bin grade beim Lesen des CP-Newsletters auf diesen Artikel gestoßen:
Generics reflektieren könnte es vielleicht daran liegen, dass der Deserialisierer hier versagt?

11.12.2007 - 11:36 Uhr

Cool, genau sowas habe ich auch schon ewig gesucht und nix Gutes gefunden.
Bei CodeProject gibts zwar Toolboxes, die sind aber nicht so toll.
Werd dein Control zu Hause gleich mal ausprobieren.
Grüße,
Big Al

10.12.2007 - 13:36 Uhr

Also ich finde blödeln auch gut 😁
Man sollte doch nicht alles so ernst nehmen.

30.11.2007 - 10:50 Uhr

Falls du Label1 öffentlich sichtbar gemacht hast, was man aber nicht machen sollte, müsste das eigentlich funktionieren, wenn du aus der 0 ein = machst, aber ich denk mal du hast dich da nur verschrieben. Rufst du eigentlich überhaupt

fff.Show()

auf?
Big Al

28.11.2007 - 13:42 Uhr

Hi,
probiers mal mit ParameterizedThreadStart oder mit dem BackgroundWorker.
Big Al

//edit: mal wieder zu langsam, Mist.

26.11.2007 - 17:07 Uhr

Naja, ist halt noch nicht so wirklich berauschend, was die Präsentation angeht. Bin leider noch nicht dazu gekommen, was besseres zur Verfügung zu stellen.
Hat mal jemand die Komponente an einem eigenen Control ausprobiert?
So gehts mit jedem Control:


GestureProvider provider;

public MyForm()
{
/*Provider für Zeichenfläche der Form, bei gedrückter linken Maustaste wird
Geste gezeichnet*/
provider = new GestureProvider(this, MouseButtons.Left);

//Erstellen einer Z-Geste (rechts/links-unten/rechts)
Gesture gestureZ = new Gesture(
new LineDirections[]{ LineDirections.Right, LineDirections.Left | LineDirections.Down, LineDirections.Right }, "ZGesture");
}

Viele Grüße,
Big Al

22.11.2007 - 21:12 Uhr

Hi,
für den ProjectDesigner.NET hab ich mal ein bisschen mit der Implementierung von Mausgesten rumprobiert und hier sind erste Ergebnisse.
Über den GestureProvider kann einem Control Mausgestenunterstützung hinzugefügt werden.
Es funktionieren nur Gesten, die aus geraden Linien bestehen und sie sollten nicht zu kompliziert sein. Ihr könnt ja mal ein bisschen damit rumexperimentieren.
Hier der Code:


using System;
using System.Collections.Generic;
using System.Text;
using System.Drawing;
using System.Windows.Forms;
using System.Collections.ObjectModel;

namespace AlexanderFillbrunn.Mousegestures
{
    /// <summary>
    /// Stellt Mausgestenerkennung für ein Control zur Verfügung
    /// </summary>
    public class GestureProvider
    {
        //gibt an, ob die Maustaste gedrückt gehalten wird
        bool mouseDown = false;

        //Die Position der Maus auf dem Steuerelement
        System.Drawing.Point mousePosition;

        //Der Startpunkt einer neuen Linie
        System.Drawing.Point start = new System.Drawing.Point(-1, -1);

        //Liste aller Linien einer Geste
        List<Line> lines = new List<Line>();

        //Gibt an, ob die gerade gezeichnete Geste gültig ist
        bool validGesture = false;

        /// <summary>
        /// Erzeugt eine neue Instanz eines GestureProviders
        /// </summary>
        /// <param name="control">Das Steuerelement, auf dem die Mausgesten ausgeführt werden</param>
        /// <param name="mouseButton">Die Maustaste, die gedrückt wird, während die Geste ausgeführt wird</param>
        public GestureProvider(System.Windows.Forms.Control control, MouseButtons mouseButton)
        {
            this.control = control;
            this.button = mouseButton;
            AddHandlers();
        }

        private void AddHandlers()
        {
            if (control != null)
            {
                control.MouseDown += new System.Windows.Forms.MouseEventHandler(control_MouseDown);
                control.MouseUp += new MouseEventHandler(control_MouseUp);
                control.MouseMove += new MouseEventHandler(control_MouseMove);
                if (enableDrawing)
                    control.Paint += new PaintEventHandler(control_Paint);
            }
        }

        private void RemoveHandlers()
        {
            if (control != null)
            {
                control.MouseDown -= new System.Windows.Forms.MouseEventHandler(control_MouseDown);
                control.MouseUp -= new MouseEventHandler(control_MouseUp);
                control.MouseMove -= new MouseEventHandler(control_MouseMove);
                if (enableDrawing)
                    control.Paint -= new PaintEventHandler(control_Paint);
            }
        }

        /// <summary>
        /// Feuert, wenn der Benutzer eine in Gestures enthaltene Mausgeste ausführt
        /// </summary>
        public event EventHandler<GestureEventArgs> GestureRecognized;

        private Collection<Gesture> gestures = new Collection<Gesture>();
        /// <summary>
        /// Die Liste der Gesten, die erkannt werden können
        /// </summary>
        public Collection<Gesture> Gestures
        {
            get { return gestures; }
        }

        private bool enableDrawing = true;
        public bool EnableDrawing
        {
            get { return enableDrawing; }
            set
            {
                if (control != null)
                {
                    bool enable = value && !enableDrawing && (value != enableDrawing);
                    if (enable)
                        control.Paint += new PaintEventHandler(control_Paint);
                    else if (!enable)
                        control.Paint -= new PaintEventHandler(control_Paint);
                    enableDrawing = value;
                }
            }
        }

        private bool checkGestureOnDrawing = true;
        /// <summary>
        /// Gibt an, ob die Geste schon während des Zeichnens überprüftwerden soll, oder legt dies fest 
        /// </summary>
        public bool CheckGestureOnDrawing
        {
            get { return checkGestureOnDrawing; }
            set { checkGestureOnDrawing = value; }
        }

        private System.Windows.Forms.Control control;
        /// <summary>
        /// Das Steuerelement, das die Gesten entgegennimmt
        /// <remarks>
        /// Falls das Steuerelement benutzerdefiniert ist, gehen sie sicher, dass die überschriebenen Methoden
        /// die Methode der Basisklasse aufrufen, damit die Events an den GestureProvider weitergeleitet werden.
        /// Betroffen hiervon sind: OnPaint, OnMouseDown, OnMouseMove und OnMouseUp
        /// In der OnPaint-Methode sollte base.onPaint(e) nach dem benutzerdefinierten Zeichnen aufgerufen werden,
        /// damit der GestureProvider die Geste auf das Steuerelement zeichnen kann. Außerdem setzt dieser alle
        /// Transformationen zurück, damit die Mausgeste an der richtigen Position und mit der richtigen Größe 
        /// gezeichnet wird.
        /// </remarks>
        /// </summary>
        public System.Windows.Forms.Control Control
        {
            get { return control; }
            set
            {
                RemoveHandlers();
                control = value;
                AddHandlers();
            }
        }

        private MouseButtons button;
        /// <summary>
        /// Die Maustaste, die gedrückt wird, während die Geste ausgeführt wird
        /// </summary>
        public MouseButtons Button
        {
            get { return button; }
            set { button = value; }
        }

        private int preciseness = 50;
        /// <summary>
        /// Gibt den Wert der minimalen Länge eines Segments an oder legt diesen fest
        /// Je höher dieser Wert ist, desto länger muss eine Liniengruppe sein, um als Teil der Mausgeste zu gelten
        /// </summary>
        public int Preciseness
        {
            get { return preciseness; }
            set { preciseness = value; }
        }

        void control_Paint(object sender, PaintEventArgs e)
        {
            //Zurücksetzen der Transformationen; Grund: siehe oben bei Property "Control"
            e.Graphics.ResetTransform();

            Color lineColor;
            if (checkGestureOnDrawing)
                lineColor = validGesture ? Color.Green : Color.Red;
            else
                lineColor = Color.Black;

            foreach (Line l in this.lines)
                e.Graphics.DrawLine(new Pen(lineColor, 5.0f), l.StartPoint, l.EndPoint);

            if ((start.X > 0) && (mouseDown))
                e.Graphics.DrawLine(new Pen(lineColor, 5.0f), start, mousePosition);
        }

        void control_MouseMove(object sender, MouseEventArgs e)
        {
            if (mouseDown)
            {
                mousePosition = e.Location;

                Line l = new Line(start, e.Location);
                //Wenn die Linie 20 Pixel lang ist, wird sie der Liste der Linien hinzugefügt
                if (Line.GetLength(l.StartPoint, l.EndPoint) > 20)
                {
                    lines.Add(l);
                    //Überprüfen, ob die geste schon richtig ist
                    if (CheckGestureOnDrawing)
                    {
                        validGesture = false;
                        foreach (Gesture g in this.Gestures)
                            if (CheckGesture(g))
                                validGesture = true;
                    }
                    //Der Startpunkt der neuen Linie ist der Endpunkt der alten
                    start = e.Location;
                }
                control.Invalidate();
            }
        }

        void control_MouseDown(object sender, System.Windows.Forms.MouseEventArgs e)
        {
            if (e.Button == button)
                mouseDown = true;
            mousePosition = e.Location;
            start = e.Location;
            control.Invalidate();
        }

        void control_MouseUp(object sender, MouseEventArgs e)
        {
            if (e.Button == this.button)
            {
                mouseDown = false;
                //Der Liste der Linien wird eine Letzte Linie hinzugefügt, auch wenn diese nicht die
                //erforderliche Länge hat
                lines.Add(new Line(start, e.Location));
                start = new Point(-1, -1);

                if (GestureRecognized != null)
                {
                    foreach (Gesture gesture in this.Gestures)
                    {
                        if (CheckGesture(gesture))
                            GestureRecognized(this, new GestureEventArgs(gesture));
                    }
                }
                control.Invalidate();
                //Linien werden gelöscht
                lines.Clear();
            }
        }

        /// <summary>
        /// Füllt rekursiv eine Liste mit Liniengruppen, die aus der Liste der Linien erzeugt werden.
        /// </summary>
        /// <param name="lineGroups">Die zu füllende Liste</param>
        /// <param name="index">Der Index der ersten Linie der neuen Liniengruppe</param>
        /// <returns>Gibt eine Liste von Liniengruppen zurück</returns>
        private List<LineGroup> GetLineGroups(List<LineGroup> lineGroups, int index)
        {
            LineDirections direction = this.lines[index].Direction;
            int indx = index;
            LineGroup linegroup = new LineGroup();
            linegroup.StartPoint = this.lines[indx].StartPoint;
            linegroup.Direction = direction;

            //wenn die Richtung aufeinanderfolgender Linien gleich ist, gehören sie zu einer Gruppe
            //tmp und direction werden verglichen. Unterscheiden sie sich, beginnt eine neue Liniengruppe.
            LineDirections tmp = direction;
            while ((direction == tmp) && (indx < lines.Count))
            {
                tmp = this.lines[indx].Direction;
                linegroup.EndPoint = this.lines[indx].EndPoint;
                indx++;
            }

            lineGroups.Add(linegroup);

            if (indx == lines.Count)
            {
                //Alle Linien wurden durchlaufen, also Liste zurückgeben
                return lineGroups;
            }
            else
                //rekursiver Aufruf der Methode mit Liste und neuem Index als Parameter
                return GetLineGroups(lineGroups, indx);
        }

        /// <summary>
        /// Überprüft, ob eine Mausgeste aus der Liste ausgeführt wurde
        /// </summary>
        /// <param name="gesture">Die Mausgeste, auf die geprüft werden soll</param>
        /// <returns></returns>
        private bool CheckGesture(Gesture gesture)
        {
            List<LineGroup> linegroups = this.GetLineGroups(new List<LineGroup>(), 0);

            //Überprüfung, ob die Liniengruppe die nötige Länge hat
            for (int c = 0; c < linegroups.Count; c++)
            {
                if (linegroups[c].Length < preciseness)
                    linegroups.RemoveAt(c);
            }

            //Gibt es unterschiedlich viele Liniengruppen und Elemente der Geste, können diese nicht
            //übereinstimmen
            if (linegroups.Count == gesture.GestureDirections.Length)
            {
                for (int x = 0; x < gesture.GestureDirections.Length; x++)
                {
                    //Stimmen die Richtungen nicht überein, sind die Gesten nicht gleich
                    if (!(gesture.GestureDirections[x] == linegroups[x].Direction))
                        return false;
                }
            }
            else
                return false;

            return true;
        }
    }
    //---------------------------------------------------------------------------------------

    /// <summary>
    /// Eine Mausgeste, die vom GestureProvider erkannt werden kann
    /// </summary>
    [Serializable]
    public class Gesture
    {
        /// <summary>
        /// Erzeugt eine neue Instanz einer Mausgeste
        /// </summary>
        /// <param name="gestureDirections">Die Richtungen der Teile der Mausgeste</param>
        /// <param name="name">Der Name der Mausgeste. Wird zum unterscheiden mehrerer Gesten benutzt.</param>
        public Gesture(LineDirections[] gestureDirections, string name)
        {
            this.gestureDirections = gestureDirections;
            this.name = name;
        }

        private string name;
        public string Name
        {
            get { return name; }
            set { name = value; }
        }

        private LineDirections[] gestureDirections = new LineDirections[0];
        /// <summary>
        /// Die Richtungen der Teile der Mausgeste
        /// <example>
        /// Ein Beispiel für eine Mausgeste wäre ( Start bei (S) und Ende bei (E):
        /// 
        ///    /|
        ///   / |
        ///  /  |
        /// /   |
        ///(S) (E)
        /// 
        /// Als Sourcecode:
        /// <code>
        /// Gesture g = new Gesture( new LineDirection[] { LineDirection.up | LineDirection.Right, LineDirection.Down } );
        /// </code>
        /// </example>
        /// </summary>
        public LineDirections[] GestureDirections
        {
            get { return gestureDirections; }
            set { gestureDirections = value; }
        }
    }

    //---------------------------------------------------------------------------------------

    /// <summary>
    /// Beschreibt die Richtung einer Linie.
    /// Die Werte können mit dem '|' (bitweises ODER) Operator verknüpft werden.
    /// "LineDirection.Up | LineDirection.Left" beschreibt eine Linie, die von rechts unten
    /// diagonal nach links oben verläuft.
    /// Es muss aber darauf geachtet werden, dass keine Widersprüche wie 
    /// "LineDirection.Up | LineDirection.Down" auftreten. Dies führt dazu, dass die Geste
    /// nicht erkannt werden kann.
    /// </summary>
    [FlagsAttribute]
    public enum LineDirections
    {
        None = 0,
        Up = 1,
        Down = 2,
        Left = 4,
        Right = 8
    }

    //---------------------------------------------------------------------------------------

    internal class Line
    {
        /// <summary>
        /// Beschreibt eine Linie, deren Winkel zu einer horizontalen Linie
        /// für die Erkennung von Gesten von Bedeutung ist.
        /// </summary>
        /// <param name="start">Der Startpunkt der Linie</param>
        /// <param name="end">Der Endpunkt der Linie</param>
        public Line(Point start, Point end)
        {
            startPoint = start;
            endPoint = end;
            angle = this.GetAngle();
            direction = GetLineDirection();
        }

        private LineDirections direction;
        /// <summary>
        /// Gibt die Richtung dieser Linie zurück oder legt diese fest.
        /// <seealso cref="LineDirection"/>
        /// </summary>
        public LineDirections Direction
        {
            get { return direction; }
        }

        private double angle;
        /// <summary>
        /// Gibt den Winkel dieser Linie zu einer horizontalen Linie zurück.
        /// </summary>
        public double Angle
        {
            get { return angle; }
        }

        private Point startPoint;
        /// <summary>
        /// Gibt den Startpunkt dieser Linie zurück.
        /// </summary>
        public Point StartPoint
        {
            get { return startPoint; }
        }

        private Point endPoint;
        /// <summary>
        /// Gibt den Endpunkt dieser Linie zurück.
        /// </summary>
        public Point EndPoint
        {
            get { return endPoint; }
        }

        /// <summary>
        /// Berechnet die Länge der Linie
        /// </summary>
        /// <returns>Gibt die Länge der Linie als float Gleitkommazahl zurück</returns>
        public static float GetLength(Point start, Point end)
        {
            Point vector = new Point(end.X - start.X, end.Y - start.Y);
            return (float)Math.Sqrt(Math.Pow(vector.X, 2) + Math.Pow(vector.Y, 2));
        }

        private double GetAngle()
        {
            //Vektor einer horizontalen Linie
            Point normVector = new Point(1, 0);
            //Vektor dieser Linie
            Point vector = new Point(endPoint.X - startPoint.X, endPoint.Y - startPoint.Y);

            /*Um den Winkel zweier Vektoren zu berechnen, benutzt man diese Formel:
             * v1  = Vektor 1
             * v2  = Vektor 2
             * | | = Betrag
             * 
             *               |v1 * v2|
             * cos alpha = -------------
             *              |v1| * |v2|
            */

            //Der Zähler des Bruches auf der rechten Seite der Formel
            double a = vector.X * normVector.X;
            if (a < 0)
                a *= -1;

            //Der Nenner des Bruches auf der rechten Seite der Formel
            double b = GetLength(startPoint, endPoint);

            //Der gesamte Bruch
            double cosin = a / b;

            //Berechnung des Winkels im Bogenmaß
            double angle = Math.Acos((double)cosin);

            //Gibt den Winkel in Grad zurück
            return (180 * angle / Math.PI);
        }

        /// <summary>
        /// Bestimmt anhand des Winkels und der Position von Start- und Endpunkt die Richtung der Linie
        /// </summary>
        /// <returns>Gibt die Richtung der Linie zurück</returns>
        private LineDirections GetLineDirection()
        {
            //Linie ist diagonal
            if ((angle > 20) && (angle < 80))
            {
                if ((startPoint.X < endPoint.X) && (startPoint.Y < endPoint.Y))
                    return LineDirections.Right | LineDirections.Down;
                else if ((startPoint.X > endPoint.X) && (startPoint.Y < endPoint.Y))
                    return LineDirections.Left | LineDirections.Down;
                else if ((startPoint.X < endPoint.X) && (startPoint.Y > endPoint.Y))
                    return LineDirections.Right | LineDirections.Up;
                else if ((startPoint.X > endPoint.X) && (startPoint.Y < endPoint.Y))
                    return LineDirections.Left | LineDirections.Up;
            }
            //Linie ist annähernd horizontal
            else if (angle <= 20)
            {
                if (startPoint.X < endPoint.X)
                    return LineDirections.Right;
                else
                    return LineDirections.Left;
            }
            //Linie ist annähernd vertikal
            else if ((angle < 97) && (angle > 80))
            {
                if (startPoint.Y < endPoint.Y)
                    return LineDirections.Down;
                else
                    return LineDirections.Up;
            }
            //sollte eigentlich nicht vorkommen, aber Methode muss immer einen Wert zurückgeben
            return LineDirections.None;
        }
    }

    //---------------------------------------------------------------------------------------

    /// <summary>
    /// Eine Gruppe von Linien mit der gleichen Richtung.
    /// </summary>
    internal struct LineGroup
    {
        private LineDirections direction;
        /// <summary>
        /// Gibt die Richtung der Liniengruppe zurück oder legt diese fest.
        /// <seealso cref="LineDirection"/>
        /// </summary>
        public LineDirections Direction
        {
            get { return direction; }
            set { direction = value; }
        }

        /// <summary>
        /// Gibt die Länge der Liniengruppe zurück oder legt diese fest.
        /// </summary>
        public float Length
        {
            get { return Line.GetLength(startPoint, endPoint); }
        }

        private System.Drawing.Point startPoint;
        /// <summary>
        /// Gibt den Startpunkt der Liniengruppe zurück oder legt diesen fest.
        /// </summary>
        public System.Drawing.Point StartPoint
        {
            get { return startPoint; }
            set { startPoint = value; }
        }

        private System.Drawing.Point endPoint;
        /// <summary>
        /// Gibt den Endpunkt der Liniengruppe zurück oder legt diesen fest.
        /// </summary>
        public System.Drawing.Point EndPoint
        {
            get { return endPoint; }
            set { endPoint = value; }
        }
    }

    //---------------------------------------------------------------------------------------

    public class GestureEventArgs : EventArgs
    {
        private Gesture gesture;
        /// <summary>
        /// Die Mausgeste
        /// </summary>
        public Gesture Gesture
        {
            get { return gesture; }
        }

        /// <summary>
        /// Erzeugt eine neue Instanz von GestureEventArgs
        /// </summary>
        /// <param name="gesture">Die Mausgeste</param>
        public GestureEventArgs(Gesture gesture)
        {
            this.gesture = gesture;
        }
    }
}

Im Anhang nochmal der Sourcecode in einzelnen Dateien und eine Demo.
Viel Spaß,
Big Al

13.11.2007 - 11:23 Uhr

Hi,
ich hab mal für meinen USB-Stick ein Programm geschrieben, das die Lese- und Schreibgeschwindigkeit ermittelt.
Dazu musst du einfach eine Datei auslesen/schreiben und mit Stopwatch messen, wie lange das dauert. Dann die Länge der Datei durch die Zeit teilen und du hast einen Performancewert.
Grüße,
Big Al

25.10.2007 - 13:59 Uhr

Hi,
also ich würde an deiner Stelle TabControl oder mehrere Panels benutzen.
Viele Grüße,
Big Al

05.10.2007 - 11:13 Uhr

Hi,
such mal nach PathGradientBrush, damit geht das.
Viele Grüße,
Big Al

04.10.2007 - 10:34 Uhr

Ich glaube er meint es andersherum, C#-App im Browser ausführen.

13.09.2007 - 13:42 Uhr

Hi,
von WPF hab ich nicht so viel Ahnung, aber die Klasse müsste man doch trotzdem benutzen können, oder?

13.09.2007 - 13:39 Uhr

Hi, es gibt in der Klasse System.Windows.Forms.TextRenderer eine Methode
MeasureText(string text, Font font), die kannst du auch benutzen.
Viele Grüße,
Big Al

11.09.2007 - 12:27 Uhr

Im irgendeinem Magazin (ich glaub DotNet Mag oder so) wurde letztens dieses Buch dazu besprochen:
Release It!
Ich selbst hab es nicht gelesen, die haben aber eigentlich nur gute Sachen darüber geschrieben.
Hoffe ich konnte dir helfen,
Big Al

10.09.2007 - 10:40 Uhr

Na klar, z.B. Type.GetProperties, Type.GetMethods usw.
Viele Grüße,
Big Al

07.09.2007 - 10:58 Uhr

Stimmt natürlich!
Deine Lösung ist dann wohl die beste.
Vielen Dank!!!

07.09.2007 - 10:52 Uhr

Den Typ weiß ich nicht direkt, aber ich kenne ja den Typ des Attributs, und kann vielleicht über Reflection die Typen der Argumente herausfinden.
Allerdings funktioniert das dann nur, wenn es den Attributtyp auch wirklich im Framework gibt. Da das hier für den ProjectDesigner.NET ist, besteht kein Zugriff auf eigene Attribute, die werden ja nicht kompiliert. Hier müsste dann der Typ der Parameter im Propertygrid angegeben werden.
Falls es noch bessere Vorschläge gibt, immer her damit. Ich werde es erstmal wie oben versuchen, oder ich mache die Codegenerierung einfach asynchron.
Danke erstmal,
Big Al

07.09.2007 - 10:41 Uhr

Nein, leider nicht, denn wenn ich den string in object parse, bleibt der ja im Grunde seines Herzens ein string. D.h. er wird auch als string behandelt und heraus kommt dann beim Code:

[Browsable("true")]

Also mit Gänsefüsschen, was ja falsch ist, weil das Attribut bool statt string erwartet.

07.09.2007 - 10:21 Uhr

Hi,
ich brauche das, weil in einem Propertygrid der Wert für ein Argument eines Attributs eingegeben wird. Da in CodeDom Attribut-Argumente aber nur object entgegennehmen, muss ich diesen String dann halt umwandeln.
Ich kann es nicht so machen:


string arg = "true";
CodeAttributeDeclaration decl = new CodeAttributeDeclaration("Browsable");
decl.Arguments.Add(new CodePrimitiveExpression(arg));

Denn dann wird ja der string übergeben.
Ich hoffe das ist jetzt nicht zu kryptisch...

07.09.2007 - 10:11 Uhr

Hi,
der Titel ist vielleicht ungünstig, mir fällt aber nix anderes ein.
Also, ich möchte aus einem String, nennen wir ihn mal <str> ein Objekt machen,
das dann in Pseudocode so generiert würde:

object obj = <str>;

Dass also obj, wenn <str> "4" ist, eine Integer ist.
Wenn <str> z.B. "true" ist, eben ein boolscher Wert.
Zur Zeit löse ich das so:


public static object StringToObject(string str)
        {
            Microsoft.CSharp.CSharpCodeProvider prov = new Microsoft.CSharp.CSharpCodeProvider();
            //Der Sourcecode, der kompiliert wird
            string source =
                "namespace test {\r\n" + 
                "public class StringToObj {\r\n" +
                "public static object GetObject(){\r\n" +
                "return " + str + ";}}}";//Gibt den String als Objekt zurück


            System.CodeDom.Compiler.CompilerParameters par = new System.CodeDom.Compiler.CompilerParameters();
            par.GenerateInMemory = true;
            try
            {
               System.CodeDom.Compiler.CompilerResults res = prov.CompileAssemblyFromSource(par, source);

               System.Reflection.Assembly assem = res.CompiledAssembly;
               foreach (System.Reflection.MethodInfo i in assem.GetModules()[0].GetTypes()[0].GetMethods())
                if(i.Name == "GetObject") //Suche der Methode
                    return i.Invoke(null, new object[] { });
             }
             catch
             {
                  return StringToObject("\"" + str + "\"");
             }
            return null;
        }

Allerdings ist diese Lösung recht langsam, deshalb meine Frage, ob es etwas schnelleres gibt.
Schonmal Danke,
Big Al

26.08.2007 - 10:57 Uhr

Gut,
soll ich dir Sourcecode schicken, der die CodeDom Objekte erzeugt,
oder kennst du dich mit CodeDom aus? Sag mir einfach, was du brauchst.
Leider hab ich noch kein Plugin SDK, also werd ichs mal hier erklären:
das Plugin implementiert das Interface IProjectExporter aus dem Namespace ProjectDesigner.Plugins
So hat es dann u.a. ein Propertie "ExportInFolder" vom Typ bool, das bestimmt, ob das Projekt in ein Ordner, oder, wenn false, als einzelne Datei.
Die ganze Logik kommt in die Export-Methode.
Wenn du Fragen hast, kann ich dir auch mal einen Beispielexporter per E-Mail schicken.
Grüße,
Big Al

25.08.2007 - 20:54 Uhr

Hi,
ist das nicht ein bisschen viel Aufwand für ein einzigen Exporter?
Theoretisch müsste es doch problemlos möglich sein, aus einem CodeDom-Objekt ein NHibernate-Objekt zu machen, da dieses ja Daten wie Name, Attribute und anderes bereitstellt.
Big Al

25.08.2007 - 18:08 Uhr

Also wenn ich das jetzt richtig verstehe, hat dann jedes Objekt ein Tag, der Instanz deiner Klasse mit Informationen für NHibernate enthält. Dieser Tag wird dann in einem PropertyGrid angezeigt. Sowas wäre eigentlich machbar und würde den Objekten eben Zusatzinformationen geben, die beim Exportieren berücksichtigt werden.
Viele Grüße,
Big Al

24.08.2007 - 17:51 Uhr

(Ich muste allerdings einiges verändern, da mein Programm so seine eigene Zeichenlogik hat und es mit Winforms timer geruckelt hat.)

Heißt das, dass deine Version performanter ist? Wenn ja, würde mich das natürlich auch interessieren.
Big Al

24.08.2007 - 10:20 Uhr

Hi,
für den ProjectDesigner.NET habe ich mir so "unendliche Scrollbars" gebstelt, wie es sie u.a. in ähnlicher Form bei Picasa gibt.
Wenn die Scrollbar in eine Richtung gezogen wird, beginnt ein Event zu feuern, das die Entfernung der Bar zur Mitte des Controls als Parameter übergibt (auf EventArgs hab ich der Faulheit halber verzichtet 🙂 ). So kann man dann im Tick-Event bestimmen, was passieren soll.
Viel Spaß damit,
Big Al