Laden...
Avatar #avatar-2094.gif
progger myCSharp.de - Member
Schüler Nähe von München Dabei seit 05.08.2005 1.271 Beiträge
Benutzerbeschreibung

Forenbeiträge von progger Ingesamt 1.271 Beiträge

28.02.2007 - 18:23 Uhr

Hallo LukeGee,

Wenn ich nach "Visual Studio Orcas screenshots" google, finde ich einiges.

Gruß,
Thomas

PS: Und auf diesen Screenshots ist keine große Differenz zu Visual Studio 2005 zu erkennen.

28.02.2007 - 14:55 Uhr

Hallo heimi,

Mit einer Suche nach "Dokumentation" und ähnlichem findest du noch einige Diskussionen zu diesem Thema.

Hallo zusammen,

Es gibt von NDoc auch ein (inoffizielles) Release (2.0 Alpha), das mit allen sprachlichen Neuerungen von .NET 2.0 zurechtkommt und die Dokumentationen auch im STil der MSDN2 erstellt. Einfach mal danach suchen.

Gruß,
Thomas

PS: Allerdings ist die Frage, ob man auf solche inoffiziellen Versionen, bei denen die Zukunft ungewiss ist, setzen sollte. Vermutlich ist es am besten gleich auf Sandcastle zu setzen, die Dokumentationen sehen auch wunderbar aus, können alles und ist vor allem direkt von Microsoft (lässt sich drüber streiten, ob das so toll ist, aber auf jeden Fall ist damit erstmal die Aktualität gewährleistet).

EDIT: PPS: Wenn du mit der Forumsuche was findest, wäre es natürlich toll, wenn du deine Ergebnisse uns hier mitteilst.

28.02.2007 - 14:45 Uhr

Original von egrath
Generell glaube ich dass je länger man in einer Sprache (und mit einem Framework) arbeitet immer mehr in Richtung händisch erstellen tendiert. Früher (als ich mit C# und .NET angefangen habe ~ 1,5 Jahre ung.) habe ich absolut alles mit dem Designer erstellt da ich schlicht und ergreifend die Backgrounds nicht gekannt habe. Erst im Lauf der Zeit ist es gekommen dass ich immer mehr ohne Designer machte.

War bei mir ganz genauso. Anfangs nur Designer. Inzwischen nehm ich ihn zwar immer noch her, um das Grundgerüst und so zu bauen, mach aber sonst das meiste per Hand, weils mir eben leichter "von der Hand" geht 😉.

23.02.2007 - 14:52 Uhr

Das würde ich sowieso nie machen, auch nicht, wenn ich den Prozessor nicht übertakte. Es gibt viel bessere und leisere Lüfter, die Boxed-Lüfter sind tierisch laut.

23.02.2007 - 12:35 Uhr

Mir ist schon klar, dass man auf keinen Fall so hoch gehen sollte. Man ist ja auch schon mit ~2.5GHz bestens bedient. Ich dachte den Artikel auch nur als Idee, wie man anders noch an ein gutes und günstiges System kommt.

23.02.2007 - 11:51 Uhr

Hallo sputnik07,

Das passt jetzt nicht zu deiner urpsrünglichen Frage, aber vielleicht inetressiert dich Übertakten bis der Arzt kommt: Luftgekühlt von 1.8 GHz auf 3.5 GHz. Lass dich von dem Titel nicht abschrecken, man muss es nicht so stark übertreiben. Aber eine der Zwischenstufen finde ich durchaus empfehlenswert.

Gruß,
Thomas

20.02.2007 - 12:18 Uhr

Hallo zusammen,

@hurricane: Du musst den Namen extra als kursiv schreiben:
[QUOTE][I]Orginal von hurricane[/I]
Ich wollte mal Fragen wie man ein Zitat mit Namen schreiben kann.
[
/QUOTE]

@all: Eine Übersicht findet ihr, wenn ihr im Editor auf das blaue Fragezeichen neben den DropDown-Feldern klickt. Dann gelangt ihr zur BBCode FAQ.

Gruß,
Thomas

20.02.2007 - 11:42 Uhr

Hallo juetho,

Durchgestrichenen Text bekommst du mit den Tags [d]...[/d] hin.

Gruß,
Thomas

18.02.2007 - 13:13 Uhr

Hallo STF-DIR,

Wenn du hier im Forum nach "Setup" oder ähnlichem suchst, wirst du sehr viel zu diesem Thema finden. Andere STichwort sind noch "WiX" und "NSIS".

Gruß,
Thomas

17.02.2007 - 12:10 Uhr

Hallo barzelona,

Hast du schon die http://www.mycsharp.de/wbb2/board.php?boardid=67 gesehen?

Gruß,
Thomas

16.02.2007 - 14:41 Uhr

Hallo zusammen,

Original von VuuRWerK
Ich glaub es gibt eine Möglichkeit einen Wert .NET zubekommen welcher die Höhe x Breite angibt wo schon Taskbar etc abgezogen sind.

Ganz genau! Und zwar gibt es dafür die Eigenschaft WorkingArea der Screen-Klasse.

Gruß,
Thomas

11.02.2007 - 12:09 Uhr

Hallo,

Mir sind jetzt spontan folgende Perlen eingefallen:

Dateiassoziation
[Tutorial] Zeichnen in Windows-Programmen (Paint/OnPaint, PictureBox)
[Tutorial] Alles über Dateien 2.0

Wenn ich noch welche finde, lasse ich sie euch natürlich wissen.

Gruß,
Thomas

02.02.2007 - 14:55 Uhr

Hallo dr4g0n76,

Du sollst doch nicht einfach zusammenfassen, was in meinem (und in herbivore's) Artikel steht. Dann bekomm ich doch keine Hits mehr 😉

Gruß,
Thomas

01.02.2007 - 14:46 Uhr

Hallo BoKat,

Eigentlich kannst du die Neuerungen von .NET 3.0 überhaupt nicht mit Visual Studio 2005 nutzen. Es gibt aber Erweiterungen, mit denen du die neuen Features trotzdem teilweise hernehmen kannst (siehe Microsoft veröffentlicht .NET Framework 3.0 Final), funktioniert aber NICHT für die Express Editionen und du hast da keinen Designer für WPF oder ähnliches. Dafür musst du auf das nächste Visual Studio, Codename "Orcas", warten.

Gruß,
Thomas

01.02.2007 - 14:38 Uhr

Hallo Therion,

Schau dir mal Operator Overloading with Generics und
Using generics for calculations bei Codeproject an.

Gruß,
Thomas

28.01.2007 - 19:52 Uhr

Hallo Quick,

Die csc.exe sowie die benötigten Assemblies sind alle bereits im Framework erhalten und werden bei dessen Installation in den Ordner "\Windows\Microsoft.NET\Framework\v<fw-version>&quot; kopiert.

Gruß,
Thomas

28.01.2007 - 13:06 Uhr

Hallo C#Test,

Ja, ich kann dir einen Hinweis geben: Benutze die Suche bevor du eine Frage stellst 😉. Dann hättest du u.a. Scriptsprache und Mini-Skriptsprache entwickeln gefunden.

Gruß,
Thomas

25.01.2007 - 16:58 Uhr

Hallo Vergaserbirndl,

Das Projekte-Forum ist zum Vorstellen eigener Projekte da.
==> Verschoben nach "Rund um die Programmierung"

Gruß,
Thomas

24.01.2007 - 17:18 Uhr

Hallo BenFire,

Wenn du es wirklich so machen willst: Am besten du fügst den SVG-Code einfach in deinem Programm zusammen. Das kannst du entweder mit einer Klasse machen, der du alle nötigen Informationen gibt und dir dann dein Diagramm bastelt (die geschicktere Variante) oder mit einer einfachen Methode. Die x-Koordinaten würde ich an deiner Stelle in einer Variable speichern und dann immer erhöhen wenn du zum nächsten Balken gehst. Den Rest müsstest du eigentlich selbst zusammenbringen.

Gruß,
Thomas

23.01.2007 - 15:29 Uhr

Hallo BenFire,

Wenn du sowieso eine C#-Anwendung hast, würde ich an deiner Stelle das visualisieren der Daten selbst mit GDI+ übernehmen. Das ist nicht recht viel komplizierter und du sparst dir damit einige Inkompatibilitäten bei der Darstellung von SVG (was zum Beispiel wenn beim Nutzer keine Anwendung zum Betrachten von SVG-Grafiken vorhanden ist? Mitliefern?). Schau dir vielleicht mal [Tutorial] Zeichnen in Windows-Programmen (Paint/OnPaint, PictureBox) an. Das könnte dir helfen.

Gruß,
Thomas

22.01.2007 - 21:00 Uhr

Original von Borg
Soweit ich weiß, kann nur der IE6 kein SVG. Wie es mit dem 7er aussieht, kann ich nicht sagen.

Ich bin mir ziemlich sicher, dass auch in der 7er Version des Internet Explorers keine Unterstützung für SVG ist. Wenn überhaupt kommt dies erst in einer späteren Version. So viel ich weiß ist etwas für IE7.2 geplant. Ich muss dazu aber sagen, dass es auch schon für IE7 geplant war.

22.01.2007 - 18:43 Uhr

Hallo BenFire,

Du musst uns mehr Infos geben: Mit was arbeitest du (außer SVG)? ASP.NET, PHP, JSP, ...? Also ich geh davon aus, dass es um eine Webanwendung geht. Oder lieg ich da falsch?
Ansonsten muss ich dir sagen, dass SVG eigentlich nicht allzu gut geeignet ist: Es gibt noch kaum wirklich gute Umsetzungen, vor allem bei den Browsern. Vielleicht solltest du nochmal überdenken, ob du das nicht anders angehst.

Ich hoffe, ich konnte dir helfen!

Gruß,
Thomas

18.01.2007 - 20:49 Uhr

Hallo ApfeL,

Hast du schon das Das .NET BlogBook ausprobiert?

Gruß,
Thomas

14.01.2007 - 16:54 Uhr

Hallo webstarg,

Dein Code-Beispiel ist für mich verwirrend. Warum versuchst du das Element an der -1. Stelle (die es ja gar nicht gibt) abzufragen?

Und was genau einst du mit "abfragen, ob etwas ausgewählt is oder nicht"?
a) ob überhaupt ein Element ausgewählt wurde: ListView.SelectedIndices/Items.Count != 0
b) ob ein bestimmtes Element ausgewöhlt wurde: ListView.SelectedIndices.Contains(index) oder ListView.SelectedItems.Contains(item)

Ich hoffe ich konnte dir helfen!

Gruß,
Thomas

11.01.2007 - 14:09 Uhr

Hallo outi,

Das von dir geschilderte Verfahren nennt sich ClickOnce. Danach kannst du hier im Forum suchen (wurde schon sehr offt behandelt, auch alle möglichen Fehlrverhalten).
Ansonsten gibt es noch diverse Update-Manager und -Bibliotheken. Kannst auch mal im Forum hier suchen (wenn ich mich recht erinner, gibt es sogar einen im Projekte-Forum).

Gruß,
Thomas

08.01.2007 - 18:34 Uhr

Hallo xxxprod,

Das ist grundsätzlich so und hat nichts mit dem Beispiel hier zu tun. Höchstwahrscheinlich hast du einen Fehler in deinem eigenen Code gemacht. Schau dir am besten mal den FAQ-Beitrag [FAQ] Controls von Thread aktualisieren lassen (Invoke-/TreeView-Beispiel) an.

Gruß,
Thomas

07.01.2007 - 14:49 Uhr

Alles normal.

EDIT: Oh, ich hab deine Antwort übersehen, LastGentleman. Sorry!

02.01.2007 - 11:36 Uhr

Hallo zusammen,

Ich habe mich (bis jetzt) auch noch nie mehr davor geschützt, als Heizung-Anfassen oder ähnliches.
Aber vielen Dank, ich finde diesen Thread und die Beiträge in Was meint Ihr zu dieser PC - Zusammenstellung? sehr hilfreich und werde mir auch eine ESD-Ausrüstung anschaffen. Das kommt bei mir auch gerade richtig, weil ich mir in den nächsten Monaten einen neuen PC anschaffen und diesen auch selbst zusammenbauen will.

Gruß,
Thomas

01.01.2007 - 16:57 Uhr

Hallo Nogger,

Das, was du machen willst, klingt wie eine Art "Ambilight". Lieg ich richtig? 😉

Mir fällt keine Möglichkeit ein, das zu machen. Weil man eben ja immer nur ein schwarzes Bild bekommt. Das liegt an der Overlay-Technik (oder wie hieß das gleich nochmal?), eben wie Videos angezeigt werden: Die Grafikkarte fügt erst anschließend das Bild ein, direkt bei der Ausgabe.

Ich drück dir die Daumen, dass du noch eine Lösung findest. Wennich noch was rausfinden sollte, lasse ich es dich natürlich wissen.

In diesem Sinne: Frohes neues Jahr und viele Grüße,
Thomas

01.01.2007 - 15:47 Uhr

Hallo zusammen,

Ich kann mich nur anschließen und wünsche euch allen ein FROHES NEUES JAHR 2007!!!!!!!!!!!!

VIele Grüße,
Thomas

30.12.2006 - 14:47 Uhr

Hallo Atze,

Dazu gibt es schon einen thread, siehe Visual Studio Erweiterungen.
Dort kannst du auch lesen, welche Erweiterungen ich einsetze 😉.

Gruß,
Thomas

27.12.2006 - 11:24 Uhr

Hallo areopag,

Schau dir dazu mal folgendes Tutorial von herbivore an: [Tutorial] Zeichnen in Windows-Programmen (Paint/OnPaint, PictureBox)

Gruß,
Thomas

25.12.2006 - 11:09 Uhr

Original von Fabian
allerdings könnte es kompliziert werden, 6950 Geschenke zu besorgen 😦.

Oh ja!! Ich hab ja bei 10 Geschenken schon Probleme 😉.

24.12.2006 - 17:59 Uhr

Ich wünsch euch auch allen von Herzen ein frohes Weihnachtsfest!! Und schöne Geschenke 🙂.
Schade, dass wir Weihanchten nicht in unsere ganzen "Familie" feiern können 😉. Und jeder schenkt jedem was 😄.

Viele weihnachtliche Grüße,
Thomas

17.12.2006 - 19:17 Uhr

Oh, Mann!! Ich könnt mich echt ohrfeigen: Jetzt habe ich ausversehen die deutsche Version des SP geladen, obwohl ich das englische VS drauf hab!! X( 🙁
Jetzt darf ich nochmal alles saugen und das bei einem Volumentarif ...

15.12.2006 - 16:08 Uhr

Hallo basi,

Das Trennen und Zusammenfügen der einzelnen Frames musst du wahrscheinlich selbst erledigen. Schau dir dazu am besten mal NGif an.

Gruß,
Thomas

03.12.2006 - 15:14 Uhr

Beispielanwendung

Im Grunde ist mein Beispiel herbivore's sehr ähnlich. Ich hab aber zu dem Rechteck auch noch Kreis und Linie als graphische Objekte hinzugefügt.
In dem Fenster sind drei Buttons, mit denen man zufällig erstellte Objekte hinzufügen kann. Darunter befindet sich eine TextBox und noch ein Button, mit deren Hilfe man Texte hinzufügenkann.
Das Verschieben geht ganz einfach mit der Maus.

Bitte beachtet auch die Kommentare im Code!

using System;
using System.Collections.Generic;
using System.Drawing;
using System.Drawing.Drawing2D;
using System.Windows.Forms;

public abstract class MyGraphicObject {
    /// <summary>
    /// Dieses Pen-Objekt wird verwendet um zu überprüfen, ob ein
    /// Punkt über der Linie des Objekts liegt. Die Farbe ist
    /// hierfür irrelevant. Als Breite hat sich 4 als sinnvoll erwiesen.
    /// </summary>
    static Pen HitTestPen = new Pen(Brushes.Black, 4);
    Pen _pen;
    bool _bVisible = true;
    GraphicsPath _path = new GraphicsPath();

    public MyGraphicObject(Pen pen) {
        _pen = pen;
    }

    protected GraphicsPath Path {
        get { return _path; }
    }

    public Pen Pen {
        get { return _pen; }
    }

    public bool Visible {
        get { return _bVisible; }
        set { _bVisible = value; }
    }

    /// <summary>
    /// Befindet sich der angegebene Punkt über der Linie des Objekts?
    /// </summary>
    public virtual bool Hit(Point pt) {
        return _path.IsOutlineVisible(pt, HitTestPen);
    }

    /// <summary>
    /// Befindet sich der angegebene Punkt innerhalb des Objekts?
    /// </summary>
    public virtual bool Contains(Point pt) {
        return _path.IsVisible(pt);
    }

    public virtual void Draw(Graphics g) {
        g.DrawPath(_pen, _path);
    }

    /// <summary>
    /// Bewegt das Objekt um deltaX in x-Richtung und deltaY in y-Richtung.
    /// </summary>
    public virtual void Move(int deltaX, int deltaY) {
        Matrix mat = new Matrix();
        mat.Translate(deltaX, deltaY);
        _path.Transform(mat);
    }
}

public class MyRectangle : MyGraphicObject {
    public MyRectangle(Pen pen, Rectangle rect)
        : base(pen) {
        Path.AddRectangle(rect);
    }
}

public class MyCircle : MyGraphicObject {
    public MyCircle(Pen pen, Point center, int radius)
        : base(pen) {
        Path.AddEllipse(center.X - radius, center.Y - radius, 2 * radius, 2 * radius);
    }
}

public class MyLine : MyGraphicObject {
    public MyLine(Pen pen, Point start, Point end)
        : base(pen) {
        Path.AddLine(start, end);
    }
}

public class MyText : MyGraphicObject {
    public MyText(Pen pen, string text, FontFamily family, FontStyle style, float emSize, Point origin)
        : base(pen) {
        Path.AddString(text, family, (int)style, emSize, origin, null);
    }

    public override void Draw(Graphics g) {
        g.FillPath(Pen.Brush, Path);
    }

    public override bool Hit(Point pt) {
        return Contains(pt) || base.Hit(pt);
    }
}

public class MainForm : Form {
    Button _btnAddRectangle;
    Button _btnAddCircle;
    Button _btnAddLine;
    Button _btnAddText;
    TextBox _txtText;
    Label _lblMouseLocation;
    List<MyGraphicObject> _graphicObjects = new List<MyGraphicObject>();
    Rectangle _canvas;
    Random _random = new Random();

    public MainForm() {
        InitializeComponent();
    }

    private void InitializeComponent() {
        _lblMouseLocation = new Label();
        _btnAddCircle = new Button();
        _btnAddLine = new Button();
        _btnAddRectangle = new Button();
        _btnAddText = new Button();
        _txtText = new TextBox();

        // Label, das die Maus-Position anzeigt
        _lblMouseLocation.AutoSize = true;
        _lblMouseLocation.Location = new Point(10, 195);
        _lblMouseLocation.Anchor = AnchorStyles.Left | AnchorStyles.Bottom;

        // Button um einen zufälligen Kreis hinzuzufügen
        _btnAddCircle.Text = "Add Circle";
        _btnAddCircle.Width = 100;
        _btnAddCircle.Location = new Point(10, 210);
        _btnAddCircle.Anchor = AnchorStyles.Left | AnchorStyles.Bottom;
        _btnAddCircle.Click += new EventHandler(AddCircle);

        // Button um eine zufällige Linie hinzuzufügen
        _btnAddLine.Text = "Add Line";
        _btnAddLine.Width = 100;
        _btnAddLine.Location = new Point(120, 210);
        _btnAddLine.Anchor = AnchorStyles.Left | AnchorStyles.Bottom;
        _btnAddLine.Click += new EventHandler(AddLine);

        // Button um ein zufälliges Rechteck hinzuzufügen
        _btnAddRectangle.Text = "Add Rectangle";
        _btnAddRectangle.Width = 100;
        _btnAddRectangle.Location = new Point(230, 210);
        _btnAddRectangle.Anchor = AnchorStyles.Left | AnchorStyles.Bottom;
        _btnAddRectangle.Click += new EventHandler(AddRectangle);

        // Button um Text an einer zufälligen Position hinzuzufügen
        _btnAddText.Text = "Add Text";
        _btnAddText.Width = 100;
        _btnAddText.Location = new Point(120, 235);
        _btnAddText.Anchor = AnchorStyles.Left | AnchorStyles.Bottom;
        _btnAddText.Click += new EventHandler(AddText);

        // TextBox, in die man den text eingeben kann der durch _btnAddText hinzugefügt wird
        _txtText.Text = "Text";
        _txtText.Width = 100;
        _txtText.Location = new Point(10, 237);
        _txtText.Anchor = AnchorStyles.Left | AnchorStyles.Bottom;

        this.Controls.Add(_lblMouseLocation);
        this.Controls.Add(_btnAddCircle);
        this.Controls.Add(_btnAddLine);
        this.Controls.Add(_btnAddRectangle);
        this.Controls.Add(_btnAddText);
        this.Controls.Add(_txtText);
        this.Size = new Size(400, 320);
        // Damit geht das Neuzeichnen viel flüssiger
        this.DoubleBuffered = true;
    }

    protected override void OnPaint(PaintEventArgs e) {
        base.OnPaint(e);
        e.Graphics.SmoothingMode = SmoothingMode.HighQuality;
        // Der Bereich, der neugezeichnet werden soll, wird auf die Zeichenfläche
        // beschränkt, damit Objekte, die darüber hinausschauen abgeschnitten werden.
        Region clip = new Region(_canvas);
        clip.Intersect(e.Graphics.Clip);
        e.Graphics.Clip = clip;
        e.Graphics.Clear(Color.White);
        foreach (MyGraphicObject go in _graphicObjects) {
            go.Draw(e.Graphics);
        }
    }

    Point _lastMouseLocation;
    MyGraphicObject _movingGraphicObject;

    protected override void OnMouseDown(MouseEventArgs e) {
        base.OnMouseDown(e);
        // Wenn die Maus außerhalb der Zeichenfläche gedrückt wurde, wird abgebrochen.
        if (!_canvas.Contains(e.Location)) return;
        // Anderenfalls wird die Liste mit den gezeichneten Objekten von hinten (damit
        // das oberste Objekte gefunden wird) durchgegangen und geprüft, über welchem
        // Objekt die Maus sich befindet. 
        for (int i = _graphicObjects.Count - 1; i >= 0; i--) {
            MyGraphicObject go = _graphicObjects[i];
            if (go.Hit(e.Location)) {
                _movingGraphicObject = go;
                break;
            }
        }
        _lastMouseLocation = e.Location;
    }

    protected override void OnMouseMove(MouseEventArgs e) {
        base.OnMouseMove(e);
        if (_movingGraphicObject != null) {
            // Wenn gerade ein Objekt verschoben werden soll, wird die Differenz zur letzten
            // Mausposition ausgerechnet und das Objekt um diese verschoben.
            _movingGraphicObject.Move(e.X - _lastMouseLocation.X, e.Y - _lastMouseLocation.Y);
            _lastMouseLocation = e.Location;
            // Hier könnte man noch optimieren, indem man immer nur den Bereich
            // neuzeichnet, in dem das Objekt bewegt wurde.
            this.Invalidate();
        }
        if (_canvas.Contains(e.Location)) {
            _lblMouseLocation.Text = string.Format("x = {0}; y= {1}", e.X, e.Y);
        }
    }

    protected override void OnMouseUp(MouseEventArgs e) {
        base.OnMouseUp(e);
        _movingGraphicObject = null;
    }

    protected override void OnSizeChanged(EventArgs e) {
        base.OnSizeChanged(e);
        // Wenn sich die Größe des Fensters ändert, wird die Größe der Zeichenfläche angepasst.
        _canvas = new Rectangle(new Point(0, 0),
            new Size(this.ClientSize.Width, this.ClientSize.Height - 70));
        this.Invalidate();
    }

    void AddCircle(object sender, EventArgs e) {
        // Erstellt einen Kreis mit zufälligen Werten für Mittelpunkt, Radius 
        // (mindestens 10 Pixel) und Farbe, der komplett zu sehen ist.
        int x = _random.Next(0, _canvas.Width);
        int y = _random.Next(0, _canvas.Height);
        int radius = _random.Next(10, Math.Max(11, Math.Min(Math.Min(_canvas.Width - x, x),
            Math.Min(_canvas.Height - y, y))));
        Pen p = new Pen(Color.FromArgb(_random.Next(0, 256), _random.Next(0, 256), _random.Next(0, 256)), 1);
        _graphicObjects.Add(new MyCircle(p, new Point(x, y), radius));
        this.Invalidate();
    }

    void AddLine(object sender, EventArgs e) {
        // Erstellt eine Linie mit zufälligen Werten für Start-, Endpunkt und
        // Farbe, die komplett zu sehen ist.
        int x1 = _random.Next(0, _canvas.Width);
        int x2 = _random.Next(0, _canvas.Width);
        int y1 = _random.Next(0, _canvas.Height);
        int y2 = _random.Next(0, _canvas.Height);
        Pen p = new Pen(Color.FromArgb(_random.Next(0, 256), _random.Next(0, 256), _random.Next(0, 256)), 1);
        _graphicObjects.Add(new MyLine(p, new Point(x1, y1), new Point(x2, y2)));
        this.Invalidate();
    }

    void AddRectangle(object sender, EventArgs e) {
        // Erstellt ein Rechteck mit zufälligen Werten für Position, Breite/Höhe 
        // (mindestens 15 Pixel) und Farbe, das komplett zu sehen ist.
        int x = _random.Next(0, _canvas.Width);
        int y = _random.Next(0, _canvas.Height);
        int w = _random.Next(15, Math.Max(16, _canvas.Width - x));
        int h = _random.Next(15, Math.Max(16, _canvas.Height - x));
        Pen p = new Pen(Color.FromArgb(_random.Next(0, 256), _random.Next(0, 256), _random.Next(0, 256)), 1);
        _graphicObjects.Add(new MyRectangle(p, new Rectangle(x, y, w, h)));
        this.Invalidate();
    }

    void AddText(object sender, EventArgs e) {
        // Erstellt ein Text-Objekt mit dem eingegebenen Text und zufälligen 
        // Werten für Position und Farbe.
        if (string.IsNullOrEmpty(_txtText.Text)) return;
        int x = _random.Next(0, _canvas.Width - 30);
        int y = _random.Next(0, _canvas.Height - 30);
        int size = _random.Next(10, 75);
        Pen p = new Pen(Color.FromArgb(_random.Next(0, 256), _random.Next(0, 256), _random.Next(0, 256)), 1);
        _graphicObjects.Add(new MyText(p, _txtText.Text, FontFamily.GenericSerif, FontStyle.Regular, size, new Point(x, y)));
        this.Invalidate();
    }
}

static class Program {
    [STAThread]
    static void Main() {
        Application.EnableVisualStyles();
        Application.SetCompatibleTextRenderingDefault(false);
        Application.Run(new MainForm());
    }
}
03.12.2006 - 15:14 Uhr

Vielen Dank an die Poweruser fürs Probelesen!

In seinem Tutorial Zeichnen in Windows-Programmen (Paint/OnPaint, PictureBox) hat herbivore beschrieben, wie man in einer Windows-Anwendung zeichnen sollte.
Ich möchte das ganze jetzt weiterführen und erklären, wie man mit Hilfe der Maus gezeichnete Objekte, wie Rechtecke, Linien und Kreise, verschieben und verändern kann.
Das ganze basiert auf herbivore's Anleitung, die man also gelesen haben sollte.

Wie finde ich heraus, ob die Maus über einem gezeichneten Objekt ist?

Dafür kann man die Klasse GraphicsPath im System.Drawing.Drawing2D-Namespace verwenden. Diese speichert geometrische Figuren in Form von Linien und Kurven zwischen bestimmten Punkten.
Wir fügen der MyGraphicObject-Basisklasse eine Eigenschaft für den GraphicsPath hinzu:

GraphicsPath _path;

protected GraphicsPath Path {
    get { return _path; }
}

Mit der Methode IsOutlineVisible kann man feststellen, ob ein angegebener Punkt auf der Linie, die das Objekt umgibt, liegt, wenn man diese mit dem angegebenen Pen-Objekt gezeichnet hat.
Dazu fügen wir der Basisklasse eine Methode Hit hinzu:

public virtual bool Hit(Point pt) {
    return Path.IsOutlineVisible(pt, _pen);
}

Wenn man diese Methode so verwendet, fällt einem schnell auf, wie schwer es ist, die Maus genau so über eine Linie zu bewegen, dass Hit true zurückgibt. Deswegen behaupten wir nun die Linie mit einem dickeren Pen-Objekt gezeichnet zu haben. Dann ist der Bereich, in den man die Maus bewegen muss um true zu erhalten um einiges größer.
Für die IsOutlineVisible-Methode wird nur die Breite des angegebenen Pen-Objekts verwendet, somit ist die Farbe irrelevant. Als Breite habe ich mit dem Wert 4 ganz gute Ergebnisse erzielt. Am besten spielt man mit dem Parameter ein bisschen rum, um das gewünschte Ergebnis zu erzielen.

Pen _hitTestPen = new Pen(Brushes.Black, 4);

public virtual bool Hit(Point pt) {
    return Path.IsOutlineVisible(pt, _hitTestPen);
}

Ob ein Punkt innerhalb eines Objekts liegt, kann man mit Hilfe der IsVisible-Methode herausfinden.
Ich habe der Beispielanwendung auch eine Methode Contains hinzugefügt, diese spielt für den Rest aber keine Rolle mehr:

public virtual bool Contains(Point pt) {
    return Path.IsVisible(pt);
}

Woher bekomme ich für meine Objekte einen GraphicsPath?

Die GraphicsPath-Klasse bietet verschiedene Methoden an (beginnen alle mit "Add" , z.B. AddLine oder AddRectangle), mit denen man geometrische Objekte, z.B. Rechteck, Ellipse, zu dem Pfad hinzufügen kann.
Anstatt sich bei jedem MyGraphicObject die Daten als Koordinaten, Rectangle-Struktur oder Ähnlichem zu merken, fügt man sie zu einem GraphicsPath hinzu.
Hier z.B. die Änderung am Konstruktor von herbivore’s MyRectangle-Klasse:

public MyRectangle(Pen pen, Rectangle rect) : base (pen) {
    Path.AddRectangle(rect);
}

Ist das mit dem GraphicsPath nicht viel komplizierter?

Nein, ist es nicht. Im Gegenteil: Da man nicht mehr lauter einzelne Strukturen und Integer-Variablen braucht, um die Angaben zu den einzelnen Objekten zu speichern, geht einiges viel leichter.
Bei herbivore’s Beispielanwendung mussten noch alle Objekte die Draw-Methode der Basisklasse implementieren. Dies ist nun nicht mehr nötig, da man schon in der Basisklasse den GraphicsPath zeichnen kann:

public virtual void Draw(Graphics g) {
    g.DrawPath(_pen, _path);
}

Auch Hit und Contains können direkt in der Basisklasse implementiert werden. Das Verschieben wird auch um einiges erleichtert, da man einen GraphicsPath ganz einfach mit einer Matrix transformieren kann. So arbeitet auch die Move-Methode, die wir der Basisklasse hinzufügen:

public virtual void Move(int deltaX, int deltaY) {
    Matrix mat = new Matrix();
    mat.Translate(deltaX, deltaY);
    _path.Transform(mat);
}

Und wie kann ich jetzt ein Objekt mit der Maus verschieben?

Dazu brauchen wir folgende Maus-Ereignisse unseres Formulars: MouseDown, MouseMove und MouseUp.
Das Verschieben läuft nun wie folgt ab:*Im MouseDownEventHandler testen wir, ob die Maus sich auf einem Objekt befindet. Wenn ja merken wir es uns und auch die Position der Maus. *Im MouseMoveEventHandler prüfen wir zuerst, ob wir uns ein Objekt zum Verschieben gemerkt haben (sprich, ob wir im Moment ein Objekt verschieben wollen). Wenn dies der Fall ist, rechnen wir den Unterschied zwischen der aktuellen Maus-Position und der letzten aus und verschieben das Objekt um diese Differenz. Dann speichern wir die Maus-Position als die letzte und zum Schluss lassen wir das Formular noch neu zeichnen, damit die Änderungen auch sichtbar werden. *Im MouseUpEventHandler setzen wir einfach die Variable, in der wir das Objekt zum Verschieben speichern, gleich null.

Lange Rede, kurzer Sinn: Hier ist der Code dazu:

Point _lastMouseLocation;
MyGraphicObject _movingGraphicObject;

protected override void OnMouseDown(MouseEventArgs e) {
    base.OnMouseDown(e);
    // Wenn die Maus außerhalb der Zeichenfläche gedrückt wurde, wird abgebrochen.
    if (!_canvas.Contains(e.Location)) return;
    // Anderenfalls wird die Liste mit den gezeichneten Objekten von hinten (damit
    // das oberste Objekte gefunden wird) durchgegangen und geprüft, über welchem
    // Objekt die Maus sich befindet. 
    for (int i = _graphicObjects.Count - 1; i >= 0; i--) {
        MyGraphicObject go = _graphicObjects[i];
        if (go.Hit(e.Location)) {
            _movingGraphicObject = go;
            break;
        }
    }
    _lastMouseLocation = e.Location;
}

protected override void OnMouseMove(MouseEventArgs e) {
    base.OnMouseMove(e);
    if (_movingGraphicObject != null) {
        // Wenn gerade ein Objekt verschoben werden soll, wird die Differenz zur letzten
        // Mausposition ausgerechnet und das Objekt um diese verschoben.
        _movingGraphicObject.Move(e.X - _lastMouseLocation.X, e.Y - _lastMouseLocation.Y);
        _lastMouseLocation = e.Location;
        // Hier könnte man noch optimieren, indem man immer nur den Bereich
        // neuzeichnet, in dem das Objekt bewegt wurde.
        this.Invalidate();
    }
}

protected override void OnMouseUp(MouseEventArgs e) {
    base.OnMouseUp(e);
    _movingGraphicObject = null;
}

Funktioniert das auch für Text?

Ja. Die GraphicsPath-Klasse besitzt eine Methode AddString. Dabei wird der angegebene Text in Linien und Kurven umgewandelt, die in dem Pfad gespeichert werden. Dabei werden auch unterschiedliche Schriftarten sowie Stile (fett, kursiv, usw.) berücksichtigt.
Wir fügen dem Beispiel eine Klasse MyText hinzu. Nun müssen wir einige Implementierungen der Basisklasse verändern:*Draw: Bei den anderen Objekten haben wir nur die Linie gezeichnet, die das Objekt umgibt (z.B. die Kreislinie). Das kann man bei Text auch machen und bekommt dann eine Outline-Schrift. Hier wollen wir aber den Text normal (also ausgefüllt) zeichnen und verwenden daher FillPath statt DrawPath. Wenn man beides kombinieren würde, könnte man z.B. eine blau gefüllte Schrift mit einer schwarzen Umrandung zeichnen.

public override void Draw(Graphics g) {
    g.FillPath(Pen.Brush, Path);
}

*Hit: Wir überfahren die Schrift nicht nur, wenn wir die Maus über die Linie bewegen, sondern auch, wenn wir uns über dem Inneren befinden. Das heißt Hit sollte nun true zurückliefern, wenn die Maus sich entweder über der Linie oder über dem Inneren befindet:

public override bool Hit(Point pt) {
    return Contains(pt) || base.Hit(pt);
}

Wie kann ich das Zeichnen optimieren, wenn der Bildaufbau beim Verschieben zu langsam ist?

Eine z.T. erhebliche Beschleunigung der Zeichnung lässt sich erreichen, wenn pro Zeichenvorgang nicht das gesamte Control neu gezeichnet wird, sondern nur die Bereiche, wo sich tatsächlich Zeichnungsobjekte befinden bzw. nur die Bereiche, die sich überhaupt geändert haben. Dieses Konzept wird im Snippet "Gezieltes OwnerDrawing" - schnelles Zeichnen bewegter Objekte von ErfinderDesRades umgesetzt.

Ende

Dieser Artikel zeigt eine Methode auf, mit der man mit Hilfe der Maus mit gezeichneten Objekten interagieren kann.

Wer sich weiter mit dem Thema beschäftigen möchte, sollte mal ein Blick auf folgende Diskussionen aus diesem Forum werfen:

30.11.2006 - 20:24 Uhr

Hallo Seikilos,

Im .NET-Framework ist nichts enthalten. Schau am besten mal bei Codeproject nach, da gibt es viele solche Komponenten, die können teiwleise auch noch um einiges mehr.

Gruß,
Thomas

26.11.2006 - 13:42 Uhr

Hallo okoman,

Schau dir mal Xqgene's Einfache ToolBar an. Bei der wird der Desktopbereich verkleinert.

Gruß,
Thomas

22.11.2006 - 19:42 Uhr

Hallo LukeGee,

Ja, so könnte man es ausdrücken. Siehe dazu Windows Presentation Foundation (kurz WPF) und dazu vielleicht auch Einführung in die WPF(Windows Presentation Foundation) - aktuell Teil 3: Beispielanwendung.

Gruß,
Thomas

21.11.2006 - 14:47 Uhr

Hallo smoovn,

Was ist denn genau deine Anforderung? Ohne diese können wir dir nicht so gut helfen.
Wenn ich deinen Thread-Titel lese, fällt mir schon eine "Alternative zu MDI" ein: Docking ==> Forumsuche.

Gruß,
Thomas

20.11.2006 - 18:41 Uhr

Hallo Seikilos,

Ich glaub du hast mich falsch verstanden. Du musst nicht einfach so zweimal auf TAB klicken, sondern über IntelliSense gehen (wenns nicht automatisch aufklappt, musst du STRG+SPACE klicken). Dann gibtst du "prop" ein und zum Einfügen des Snippets klickst du nicht einmal auf TAB, wie für Methoden/Eigenschaften/..., sondern zweimal.

Gruß,
Thomas

20.11.2006 - 18:20 Uhr

Hallo Seikilos,

Ich weiß ehrlich gesagt nicht genau, was du mit den Accessoren meinst. Meinst du get und set?
Wenn ja: Die kannst du dir über das Snippet prop (get und set) bzw. propr (readonly, also nur get) generieren lassen (Achtung: Zum Einfügen musst du zweimal auf TAB klicken!).
Ich hoffe ich konnte dir helfen.

Gruß,
Thomas

16.11.2006 - 14:46 Uhr

Hallo rennsemmel,

Du weißt der PictureBox.Image-Eigeschaft einfach das neue Bild zu.

Gruß,
Thomas

16.11.2006 - 14:42 Uhr

Hallo Bix,

Sowas kannst du dem Compiler nicht beibringen (eigentlich müsstest du das eh VS beibringen). Es ist nicht möglich sowas zu kompilieren:
A ist abhängig von B, B von C und C wieder von A. Wo würdest du anfangen zu kompilieren? Genau, du hast keine Ahnung. Du musst versuchen die Abhängigkeiten irgendwie aufzulösen, tüftel am besten mal ein bisschen rum.

Gruß,
Thomas

15.11.2006 - 13:48 Uhr

Hallo alex309,

Schau dir vielleicht auch mal VB .Net Projekt zu C#konvertieren? an.

Gruß,
progger

14.11.2006 - 17:16 Uhr

ACHTUNG
theSpoke-Premium wurde deaktiviert!! Siehe dazu http://thespoke.net/forums/972941/ShowPost.aspx.
Wie es weitergehen wird, weiß ich nicht. Sieht aber so aus, als ob es wirklich aus damit wäre, was wirklich schade ist. Nirgendwo anders bekommt man als Nicht-Student eine Schülerversion von Visual Studio. Oder kennt ihr irgendwelche Alternativen?

Gruß,
Thomas

11.11.2006 - 14:44 Uhr

Hallo der_andre,

Was meinst du genau mit den "Sections bei XP-Fenstern"? Meinst du das beim Windows-Explorer mit "Datei- und Ordneraufgaben" usw.?
Du musst schon genauer erklären, dass wir dir helfen können.

Gruß,
Thomas

Nachtrag: Ich habs genauso verstanden wie sbertl000.

10.11.2006 - 19:17 Uhr

@frisch:

Original von frisch
Vista-Inspirant-Theme

Kann sein, dass das Vista Inspirat heißt, also ohne n?