BigBasti's Blog About Me & my Digital Lifestyle

17Aug/101

Add-On Perle: Visual Studio Productivity Power Tools

Wer mit Visual Studio 2010 arbeitet und Visual Studio Productivity Power Tools noch nicht kennt sollte schnellst möglich handeln und sich dieses Add-On installieren, denn es macht die Arbeit mit Visual Studio sehr viel angenehmer (kaum zu glauben dass das eigentlich möglich ist ;-) )

Diese Power Tools verbessern hierbei viele Kleinigkeiten, die den Arbeitsprozess angenehmer machen. Hier ein paar Beispiele:

  • STRG+Mausklick auf eine Variable befördert euch zu der Klasse
  • STRG+1/2/3 Bringen bequeme Sprungmöglichkeiten innerhalb der markierten Klasse
  • ALT+Pfeil hoch/runter verschiebt den markierten Text
  • Ein neuer Solution navigator
  • Ein verbesserter "Verweis hinzufügen" Dialog mit Suchfunktion
  • Farbige und pinnbare Tabs
  • und und und

Schnell laden, installieren und genießen! Ich kann schon jetzt nicht mehr ohne! :-)

VN:F [1.9.3_1094]
Rating: 0.0/10 (0 votes cast)
20Jul/101

Windows Aero Glas in eigenen Projekten Nutzen Teil 5 – Der letzte Versuch

In den letzten Tagen habe ich mal wieder ein wenig mit der Windows API herumgespielt, speziell mit der Aero Glas API (DWMAPI). Ich habe euch ja auch noch versprochen einen Beitrag über Steuerelemente in Verbindung mit Glas nachzuliefern. Nunja hier ist er :)

Bild 1: Probleme mit der Transparenz

In Bild 1 sehen wir das Problem, viele der Windows Forms Steuerelemente nutzen GDI zur Darstellung und haben deswegen keinen Alpha-Kanal, der aber für die Darstellung auf Glas benötigt wird. Deswegen nutzen wir die Schwarze Farbe um unsere Fläche in Glas zu verwandeln, leider denkt der DWM dann, dass auch die Texte auf unseren Steuerelementen zu Glas werden sollen.

Ich habe mich nun ein wenig im Internet umgehört und verschiedene Ansätze gefunden und diverse Hacks mit der Windows32API Ausprobiert, die aber alle leider nicht mehr funktionieren. So will ich euch heute zwei Möglichkeiten vorstellen wie man es doch hinkriegen könnte.

1. Owner Drawing

Da die Steuerelemente mit GDI gerendert werden haben wir ein kleines Problem wie man oben sieht. Also müssen wir die Darstellung der Steuerelemente selbst in die Hand nehmen. Dieser Vorgang nennt sich OwnerDrawing und bedeutet soviel wie "SelberZeichnen". Ich will das Ganze mal anhand einer Textbox demonstrieren.

Und genauso ist auch das Vorgehen. Wir erstellen eine neue Klasse und nennen Sie "AeroTextBox". Diese Klasse erbt nun von der Original TextBox. Nun müssen wir ein paar kleine Änderungen an der Klasse vornehmen in Bezug auf die Darstellung, also des WM_PAINT Ereignisses.

Da wir das Zeichnen des Steuerelements selbst in die Hand nehmen wollen müssen wir die WM_PAINT Message abfangen und auf unsere eigene Methode umleiten:

C#


    protected override void WndProc(ref System.Windows.Forms.Message m)
    {
        base.WndProc( ref m);

        switch (m.Msg)
        {
            case 0xf: //WM_PAINT
                RedrawControlAsBitmap(this.Handle);
                break;
        }
    }

VB.NET


 Protected Overrides Sub WndProc(ByRef m As System.Windows.Forms.Message)
	MyBase.WndProc(m)

	Select Case m.Msg
		Case &Hf 'WM_PAINT
			RedrawControlAsBitmap(Me.Handle)
			Exit Select
	End Select
End Sub

Wie man sieht fangen wir hier die Message ab und rufen unsere eigene Methode auf, die das Zeichnen übernehmen wird:

C#


    public void RedrawControlAsBitmap(IntPtr hwnd)
    {
        Control c = Control.FromHandle(hwnd);
        using (Bitmap bm = new Bitmap(c.Width, c.Height))
        {
            c.DrawToBitmap(bm, c.ClientRectangle);
            using (Graphics g = c.CreateGraphics())
            {
                g.DrawImage(bm, new Point(-1, -1));
            }
        }
        c = null;
    }

VB.NET


Public Sub RedrawControlAsBitmap(hwnd As IntPtr)
	Dim c As Control = Control.FromHandle(hwnd)

	Using bm As New Bitmap(c.Width, c.Height)
		c.DrawToBitmap(bm, c.ClientRectangle)

		Using g As Graphics = c.CreateGraphics()
			g.DrawImage(bm, New Point(-1, -1))
		End Using
	End Using
	c = Nothing
End Sub

Was hier passiert ist eigentlich sehr simpel, wir zeichnen das Control neu und legen das gezeichnete Bild nun über das Control drüber. Nur diesmal machen wir das ganze mit einem Alpha Kanal, sodass der DWM uns die Darstellung nicht versaut!

Nun bleibt noch ein kleines Problem, nämlich dass bei manchen Aktionen des Benutzers wie zB. bei MouseOver oder KeyPress Events das Steuerelement neugezeichnet wird und unsere Funktion da oben nicht greift. Hier müssen wir manuell dafür sorgen, dass Windows erneut die WM_PAINT Message versendet. Das erreichen wir indem wir die einzelnen Events überschreiben und die Invalidate()-Methode aufrufen. Diese Methode erklärt die ganze Oberfläche des Steuerelements für ungültig und bewirkt, dass das Steuerelement neu gezeichnet wird.

C#


    protected override void OnMouseClick(System.Windows.Forms.MouseEventArgs e)
    {
        base.OnMouseClick(e);
        Invalidate();
    }

    protected override void OnMouseMove(System.Windows.Forms.MouseEventArgs e)
    {
        base.OnMouseMove(e);
        Invalidate();
    }

    protected override void OnTextChanged(System.EventArgs e)
    {
        base.OnTextChanged(e);
        Invalidate();
    }

    protected override void OnMouseEnter(System.EventArgs e)
    {
        base.OnMouseEnter(e);
        Invalidate();
    }

VB.NET


Protected Overrides Sub OnMouseClick(e As System.Windows.Forms.MouseEventArgs)
	MyBase.OnMouseClick(e)
	Invalidate()
End Sub

Protected Overrides Sub OnMouseMove(e As System.Windows.Forms.MouseEventArgs)
	MyBase.OnMouseMove(e)
	Invalidate()
End Sub

Protected Overrides Sub OnTextChanged(e As System.EventArgs)
	MyBase.OnTextChanged(e)
	Invalidate()
End Sub

Protected Overrides Sub OnMouseEnter(e As System.EventArgs)
	MyBase.OnMouseEnter(e)
	Invalidate()
End Sub

Nun wird das Control richtig dargestellt. Wie ihr vielleicht auch gesehen habt haben wir in unserer Methode, die für das Neuzeichnen verantwortlich ist nicht TextBox sondern die Superklasse Control benutzt. Das bedeutet für uns, dass wir mit diesem Code jedes Steuerelement ableiten und auf diese Weise neuzeichnen können mit mehr oder weniger viel Erfolg. Ich habe mal ein paar Klassen abgeleitet und für euch auf dem Glass-Form platziert:

Bild 2: Die OwnerDrawn Steuerelemente

Wie man sieht ist das schon eine sehr vielversprechende Verbesserung der Darstellung, wenn auch nicht perfekt. Aber natürlich steht es euch noch frei die Darstellung weiter zu verbessern und auf die einzelnen Steuerelemente anzupassen.

Nachdem ihr die selbst erstellten Klassen die von den einzelnen Steuerelementen erben einmal kompiliert habt, wird Visual Studio dies bemerken und euch diese neuen Steuerelemente zusammen mit den anderen in der Toolbox anbieten. Diese können dann wie gewohnt per Drag & Drop auf das Formular gezogen werden.

Bild 3: Bequemer Gehts nicht

Wie ihr euch vorstellen könnt ist es ein ziemlicher Aufwand jedes Steuerelement noch mal neu anzulegen und dessen komplette Darstellung zu übernehmen. Es ist wirklich sehr frickelig! Deswegen wird dieser Ansatz auch eher selten verwendet! Die Demo dazu könnt ihr euch übrigens am Ende des Artikels herunterladen.

Variante 2. "The Microsoft Way"

Natürlich stolpert man irgendwann bei der Recherche über das Windows API SDK in dem es einige Beispiele dazu gibt wie man die neuen Funktionen in Windows benutzt, darunter natürlich auch Glas.

Der Ansatz den Microsoft da aber nach ihrer eigenen Best Practise verwendet ist aber eher ernüchternd. Hier geht es nach dem Motto, platziert einfach keine Steuerelemente auf dem Glas! - Super nicht?

In dem einzigen Beispiel das Microsoft da aufführt wird eine Form gezeigt, dessen Rahmen in das Formular bis zum darauf liegendem Panel erweitert wurde, nicht wirklich spannend. Aber wenn ich so überlege, fällt mit spontan auch kein Windows Programm auf, bei dem irgendwelche Steuerelemente auf dem Glas liegen - kennt ihr welche? In dem meisten Programmen liegen fast nur Grafiken auf dem Glas oder so ähnliche Controls wie die im Windows Explorer.

Also sage ich es mal Microsofts Worten: lasst die Controls vom Glas weg oder benutzt WPF! ;-)

Hier noch die Demo zu der Variante 1: Download [VS 2008 Projekt]

Zur zweiten Variante habe ich keine Demo gemacht, ihr könnt euch ja das Windows API SDK herunterladen und dort im Aero Ordner nachgucken.

<< Teil 4 des Tutorials

VN:F [1.9.3_1094]
Rating: 0.0/10 (0 votes cast)
15Jul/101

Microsoft SQL CE: Blobs Speichern und auslesen

In diesem kleinem Tutorial möchte ich euch zeigen, wie man BLOBs (Binary Large Objects) in die Compact Edition vom Microsofts SQL Server speichern und wieder laden kann. Dies soll  eine Art Weiterführung von dem letzten Einstiegspost sein. Ich kann euch aber nicht versprechen, dass noch weitere Beiträge zu dem Thema kommen werden.

Auch wen Relationale Datenbanken überwiegend dazu benutzt werden um Text-Basierte Informationen zu speichern, wie Benutzernamen, IP Adressen oder andere Texte, kommt es doch häufiger vor, dass man auch Dateien wie Bilder in eine Datenbank legen möchte. Dies ist zB. nützlich wenn man eine Benutzerdatenbank hat und zu jedem Benutzer ein Bild hinterlegen will.

Das Vorgehen an Sich ist dabei sehr ähnlich, ihr erstellt ein SqlCeCommand und fügt dem wie gewohnt einige Parameter hinzu:


                using (SqlCeConnection con = new SqlCeConnection(conString)) {
                    con.Open();
                    using (SqlCeCommand com = new SqlCeCommand
                        ("INSERT INTO cp_image (date, image) VALUES (@Date, @Filename)", con)) {

                        com.Parameters.AddWithValue("@Date", DateTime.Now.ToString());
                        com.Parameters.AddWithValue("@Filename",
                                System.IO.File.ReadAllBytes(filename)).SqlDbType = SqlDbType.Image;
                        com.ExecuteNonQuery();
                    }
                }

Absolut nichts neues wie ihr sehen könnt, wir geben die Datei, die wir anhängen wollen einfach als byte-Array als Parameter mit.

Sehr wichtig ist hierbei folgende Stelle in Zeile 8:


.SqlDbType = SqlDbType.Image;

Wenn ihr diese Information nicht mit angebt, werdet ihr Probleme bekommen, sobald ihr eine Datei in die Datenbank schreiben wollt die größer ist als 8 KB!!! Denn wenn man einen Parameter angibt ohne dessen Typ mit anzugeben versucht SQLCE den Typ selbst zu bestimmen und wählt dazu dann den Typ varbinary, dessen Größe auf 8000 Byte beschränkt ist!

Mit dem Ausführen des SqlCeCommands sollte die Datei bzw. das Bild in diesem Fall dann in eure Datenbank Datei wandern.

Das Auslesen der Datei aus der Datenbank gestaltet sich ebenfalls nicht kompliziert. Hier meine Funktion um ein Bild aus der Datenbank zu lesen:


        public Image getImageFromDB(int id) {
            Image img;
            byte[] imgData = null;

            using (SqlCeConnection con = new SqlCeConnection(conString)) {
                con.Open();
                using (SqlCeCommand com = new SqlCeCommand
                    ("SELECT image FROM cp_image WHERE id = '" + id.ToString() + "'", con)) {

                    using (SqlCeDataReader dr = com.ExecuteReader()) {
                        while (dr.Read()) {
                            imgData = (byte[])dr["image"];
                        }
                    }
                }
            }

            if (imgData != null) {
                //Es wurde ein Bild geladen
                MemoryStream ms = new MemoryStream(imgData);
                img = Image.FromStream(ms);
                return img;
            }
            return null;
        }

Dazu benutze ich einfach nur einen gewöhnlichen DataAdapter, mit dem ich aus der Spalte namens "image" die Bildinformationen auslese, diese müssen noch in ein byte-Array gecastet werden, da diese als Object geliefert werden.

Zum Schluss wird noch das Byte-Array in ein System.Drawing.Image verwandelt und zurückgegeben. Dies kann man dann zB. direkt in eine PictureBox laden.

Hier ist die Tabelle, die ich in diesem Beispiel benutzt habe:

Bild 1: Tabelleninformationen

Wie ihr eine Verbindung zur Datenbank herstellt und normale Select- und Insert-Befehle benutzt könnt ihr im Ersten Teil nachlesen.

<< Zu Teil 1

VN:F [1.9.3_1094]
Rating: 0.0/10 (0 votes cast)
8Jul/101

Microsoft SQL Server Compact Edition – Eine Einfuehrung

Oft müssen Clientprogramme große Datenmangen speichern, und in den meisten Fällen wird dazu eine Datenbank eingesetzt. Wenn man eine Internetverbindung voraussetzt kann man einen mächtigen Datenbank Server anbinden und die Daten in der Cloud sichern. Doch oft ist eine Offline Lösung viel einfacher und effektiver.

Inzwischen gibt es auch viele verschiedene lokale Datenbanksysteme wie zB. SQLite, DB4O oder auch MS SQL Server Compact Edition. Alle diese Serversysteme haben auch den Vorteil, dass diese auf den mobilen Systemen problemlos eingesetzt werden können, haben aber auch den Nachteil, dass sie meist nicht den Vollen Feature Umfang eines echten SQL Servers bieten können.

Vorbereitung

In diesem Artikel soll es um den SQL Server Compact Edition von Microsoft gehen, diesen wollte ich schon immer mal testen und nun hatte ich mal die Zeit dazu.

Sofern ihr es noch nicht habt könnt ihr den SQL CE Server kostenlos bei Microsoft herunterladen. Nach der Installation arbeiten wir wie gewohnt im Visual Studio.

Implementierung

Die ganze Implementierung der Datenbank, Erzeugung der Tabellen sowie die Anbindung erfolgt aus Visual Studio heraus. Die Funktionen die man dort hat sind aber auch  stark von dem Provider abhängig, so bieten verschiedene Provider mehr oder weniger Funktionalität.

Um eine Datenbank zu einem Projekt hinzuzufügen öffnet einfach den Projektmappen-Explorer (Ansicht->Projektmappen-Explorer) und Klickt mit der rechten Maustaste auf euer Projekt und dann auf "Hinzufügen"->"Komponente..." und wählt eine Lokale Datenbank aus. In dem Datenbank Assistent Fenster klickt nun 2 Mal auf "Zurück" um auf die erste Seite des Assistenten zu gelangen.

Klickt nun auf "Neue Verbindung". In dem folgendem Fenster sollte man darauf achten, dass als Datenquelle "Microsoft SQL Server Compact 3.5" ausgewählt ist.

Bild 1: Datenbank Konfiguration

Klickt nun auf "Erstellen..." nun solltet ihr das Fenster aus Bild 1 sehen. Wählt oben den Speicherort eurer Datenbank und legt wenn nötig ein Passwort fest um die Datenbank zu verschlüsseln. Bestätigt das Ganze noch zwei Mal mit OK. Visual Studio sollte euch dann darauf hinweisen, dass ihr vorhabt eine Lokale Datenbank zu verwenden und schlägt euch vor diese in euer Projekt zu importieren - das nehmen wir gerne an.

Visual Studio fügt die neu erzeugte Datenbank Datei dem Projekt hinzu und setzt auch die nötigen Verweise auf System.Data und auf System.Data.SqlServerCe.

Anlegen der Tabellen

Beim Anlegen der Tabellen in unserer Datenbank ist uns Visual Studio natürlich ebenfalls sehr behilflich. Öffnet einfach den Server-Explorer (Ansicht->Server-Explorer) und erweitert eure frisch angelegte Datenbank. (Eventuell müsst ihr auch ein Passwort angeben wenn ihr die Datenbank verschlüsselt habt)

Klickt nun mit der rechten Maustaste auf Tabellen und wählt "Tabelle erstellen" um den Tabellen Assistenten zu starten.

Bild 2: Tabellen Assistent

Hier könnt ihr eure Tabelle anlegen und konfigurieren. Wenn ihr die nun fertige Tabelle im Server-Explorer rechts anklickt und dann "Tabelleneigenschaften" wählt bekommt ihr noch mehr Konfigurationsmöglichkeiten wie etwa Beziehungen.

Bereits beim Erstellen der Tabellen ist es euch vielleicht schon aufgefallen, dass es nicht so viele Datentypen zur Auswahl gibt wie in einem richtigen SQL Server aber das sind nicht die einzigen Einschränkungen...

Arbeiten mit der Datenbank

Das Arbeiten mit der Datenbank gestaltet sich nicht anders als mit anderen Datenbanken. Die Objekte die man dafür benötigt heißen sogar fast gleich. Alle Klasse die man nutzt haben noch den Zusatz "Ce", also statt "SqlCommand" heißt es nun "SqlCeCommand".

Und auch die Nutzung unterscheidet sich nur geringfügig:

Datenbank Verbindung herstellen:


        private SqlCeConnection con;
        private string dbLocation = Environment.CurrentDirectory + "\\clipboard.sdf";
        private string conString;

        private void connectDB(){
            conString = "Data Source=\"" + dbLocation + "\"; Password=\"bigbasti.com\"; Encrypt=True";
            con = new SqlCeConnection(conString);
            con.Open();
        }

Eine Select Abfrage durchführen:


        ///
        /// Führt einen Select Befehl auf der Datenbank aus und gibt das ergebnis in einer DataTable zurück
        ///
        ///Der auszuführende Befehl
        /// Return: Ein DataTable mit den ausgelesenen Daten
        public DataTable executeSelect(string query) {
            connectDB();
            DataTable dt = new DataTable();
            SqlCeCommand com = new SqlCeCommand(query, con);
            SqlCeDataAdapter sad = new SqlCeDataAdapter(com);

            sad.Fill(dt);
            con.Close();
            return dt;
        }

        public int checkDouble(string link, string date) {
            int retVal;
            using (SqlCeConnection con = new SqlCeConnection(conString)) {
                con.Open();

                //Doppelte Einträge verhindern
                DataTable dt = executeSelect("SELECT * FROM cp_link WHERE link LIKE '" + link + "'");
                if (dt.Rows.Count > 0) {
                    executeNonQuery("DELETE FROM cp_link WHERE link LIKE '" + link + "'");
                }
            }
            return retVal;
        }

UPDATE, DELETE und INSERT:


        ///
        /// Executes an SQL statement against the SqlCeConnection and returns
        /// the number of rows affected.You also can use ExecuteNonQuery to
        /// change the data in a database without using a DataSet by executing
        /// UPDATE, INSERT, or DELETE statements.
        ///
        ///Der Befehl der ausgeführt werden soll
        /// The number of rows affected.
        public int executeNonQuery(string q) {
            int retVal;
            using (SqlCeConnection con = new SqlCeConnection(conString)) {
                con.Open();
                using (SqlCeCommand com = new SqlCeCommand(q, con)) {
                    retVal = com.ExecuteNonQuery();
                }
            }
            return retVal;
        }
        public int doSomeInsert(string link, string date) {
            int retVal;
            using (SqlCeConnection con = new SqlCeConnection(conString)) {
                con.Open();
                using (SqlCeCommand com = new SqlCeCommand("INSERT INTO cp_link  (link, date) VALUES (@link, @date )", con)) {
                    com.Parameters.AddWithValue("@link", link);
                    com.Parameters.AddWithValue("@date", date);
                    retVal = com.ExecuteNonQuery();
                }
            }
            return retVal;
        }

Hier gibts eigentlich nichts besonderes. Leider hat man hier, da es eine Compact Edition ist nicht so viele Befehle zur Verfügung wie im Original. So fehlt zB. auch der TRUNCAT Befehl wie ich erstaunt feststellen musste. Ich habe da nicht noch weiter recherchiert was noch alles fehlt, da ich für das was ich gemacht habe keine besonderen Aktionen benötigte.

Deployment

Wenn ihr das Projekt über ein Setup-Projekt deployen wollt dann sollte da eigentlich nichts schief gehen. Ihr könnt aber natürlich auch ohne ein extra Setup-Projekt deployen, dazu solltet ihr folgende Schritte machen:

  1. Öffnet die Eigenschaften eures Projekts
  2. Öffnet dort den "Veröffentlichen" (Publish) Tab
  3. Klickt auf den Knopf "Erforderliche Komponenten"
  4. Sucht den Eintrag "SQL Server Compact Edition 3.5" und entfernt das Häkchen und schließt die Eigenschaften
  5. Nun benötigen wir die erforderlichen DLL Dateien, diese liegen in "C:\Programe\Microsoft SQL Server Compact Edition\"
  6. Es sind 7 oder auch mehr Dateien, abhängig davon wie viele Sprachen installiert sind (siehe Bild links)
  7. Markiert diese DLLs und zieht diese direkt in den Projektmappen-Explorer, da mit diese DLLs dem Projekt hinzugefügt werden
  8. Markiert die neuen DLLs in dem Projektmappen-Explorer -> klickt mit der rechten Maustaste darauf und wählt "Eigenschaften"
  9. Setzt die Eigenschaft "In Ausgabeverzeichnis kopieren" auf "Kopieren, wenn neuer" damit ihr immer die Aktuelle Version im Build Verzeichnis habt
  10. Klickt im Projektmappen-Explorer mit der rechten Maustaste auf System.Data.SqlServerCe und wählt Eigenschaften
  11. Setzt hier die Eigenschaft "Lokale Kopie" auf True. Dieser Schritt ist nötig damit das Programm lokal nach der DLL sucht und nicht versucht sich diese aus dem GAC (Global Assembly Cache) zu holen.

Und das war es eigentlich schon. Nun könnt ihr das Projekt problemlos deployen.

VN:F [1.9.3_1094]
Rating: 10.0/10 (3 votes cast)
17Jun/101

.NET: Charts und Diagramme mit MSChart erstellen

Vor Kurzem musste ich für einen Kunden eine Datenauswertung in einer .NET Applikation realisieren und wollte dazu ein schönes Diagramm erstellen. Leider musste ich (zu meinem Erstaunen) feststellen, dass das .NET Framework über kein eigenes Control für solche Zwecke verfügt, zumindest nicht im Framework 3.5!

Nach ein wenig googlen bin ich dann auf die Charting Controls von Microsoft gestoßen, diese können hier heruntergeladen werden und für das Framework 3.5 nachinstalliert werden. Das Framework 4.0 bringt es gleich mit.

Nach der Installation steht euch der Namespace "System.Windows.Forms.DataVisualization.Charting" zur Verfügung, der wirklich alles woran man so denken kann mitbringt, und das völlig kostenlos! Dieses Control kann man auch in ASP.NET Projekten benutzen.

Die eigentlich Benutzung ist auch sehr einfach gehalten, so können wir mit diesem Code einen einfachen Graphen erstellen und anzeigen:


using System.Windows.Forms.DataVisualization.Charting;

        private void Form1_Load(object sender, EventArgs e) {
            chart1.Series.Add("Balcken");
            chart1.Series.Add("Area");

            //Ausssehen festlegen
            chart1.Series["Balcken"].ChartType = SeriesChartType.Column;
            chart1.Series["Linien"].ChartType = SeriesChartType.Line;
            chart1.Series["Area"].ChartType = SeriesChartType.Area;

            //Zufällige Werte generieren
            Random random = new Random();

            for (int pointIndex = 0; pointIndex < 10; pointIndex++) {

                chart1.Series["Area"].Points.AddY(random.Next(20, 50));
            }

            for (int pointIndex = 0; pointIndex < 10; pointIndex++) {

                chart1.Series["Balcken"].Points.AddY(random.Next(50, 100));
            }

            for (int pointIndex = 0; pointIndex < 10; pointIndex++) {

                chart1.Series["Linien"].Points.AddY(random.Next(70, 100));
            }
        }

Wie ihr sehen könnt ist es alles sehr sehr simpel aufgebaut und man hat mit nur wenigen Zeilen Code ein schönes Diagramm gemacht:

Bild 1: Schöne Diagramme schnell gemacht

Wie oben bereits erwähnt seid ihr nicht auf diese Diagrammtypen beschränkt, sondern habt eine ziemlich große Auswahl an verschiedenen Diagrammtypen, darunter auch welche mit Farbverläufen und auch in 3D!

Bild 2: Eine breite Auswahl an verschiedenen Visualisierungen

Bei der Auslieferung eurer App solltet ihr darauf achten, dass ihr die System.Windows.Forms.DataVisualization.dll mit ausliefert, da der Benutzer sonst die Anwendung nicht starten kann, da diese DLL nicht Bestandteil von Framework 3.5 ist. Wenn ihr aber mit Sicherheit wisst, dass der Benutzer das Framework in der Version 4.0 installiert hat könnt ihr euch diesen Schritt sparen!

Weitere Informationen findet ihr im MSDN. Ein Demoprojekt gibts hier:

VN:F [1.9.3_1094]
Rating: 0.0/10 (0 votes cast)
19Mrz/100

.NET: Taskleiste und Start Button ausblenden

Vor einer Weile habe ich einen Artikel geschrieben, in dem ich zeige wie man die Windows Taskleiste ausblenden kann, sodass nur der Startbutton übrig bleibt. Nun wollen wir auch noch den Startbutton entfernen, sodass von der Taskleiste nichts mehr übrig bleibt!

Das Vorgehen ist hierbei fast das gleiche, der Unterschied besteht nur darin, dass der Prozess, der für die Anzeige des Start-Buttons verwendet wird etwas schwerer zu finden ist! Diesen Prozess werdet ihr vergeblich in der Process.getProcesses() Übersicht des .NET Frameworks suchen.

Hier müssen wir so vorgehen wie in dem Beitrag "Alle Sichtbaren Prozesse auflisten" und benutzen deshalb die Windows Funktion "EnumWindows" die uns alle Fensterprozesse liefert, inklusive dem Start-Button Prozess.

Suchen müssen wir hier den Prozess mit dem Titel "Start" und von der Klasse "Button". Ich habe hier um die Arbeit zu erleichtern 2 kleine Klassen geschrieben. (Ich werde bald eine Library veröffentlichen mit weiteren Funktionen)


            ProcessListDemo.Windows windows = new ProcessListDemo.Windows();

            foreach (ProcessListDemo.Window w in windows.lstWindows)
            {
                if (w.winTitle == "Start" &amp;amp;&amp;amp; w.winClass == "Button" &amp;amp;&amp;amp; w.winVisible == true)
                {
                    sbHandle = w.winHandle;
                    if (sbHandle != IntPtr.Zero)
                    {
                        ShowWindow(sbHandle, 0);
                    }
                    else
                    {
                        //Fehler
                    }
                }
            }

Wenn man nun das Handle des Startbuttons hat kann man mit der Windows Funktion ShowWindow das Fenster bzw. den Button ausblenden.

Bild 1: Demoanwendung kann nun auch den Startbutton verschwinden lassen

Wundert euch nicht, dass der Button nicht verschwindet wenn ihr den Code ausführt, denn erst wenn auch die Taskleiste verschwunden ist ist auch der Button weg. Also kann man nur den Button anzeigen oder Taskleiste und Button. Nur die Taskleiste (also ohne den Start Knopf) Geht leider nicht!

Probiert es einfach mit der Demoanwendung aus:

.

.

VN:F [1.9.3_1094]
Rating: 0.0/10 (0 votes cast)
10Mrz/100

101 LINQ Beispiele fuer C# Programmierer

Wer Datenbankprogrammierung mit C# betreibt wird früher oder später nicht an LINQ vorbeikommen. Wer sich damit etwas auseinandersetzt wird schnell merken, dass diese Queries schnell recht komplex werden.

Hier bietet Mocrosofts MSDN eine tolle Beispielsammlung an, in der fast alle Anwendungsfälle beschrieben sind. Das ganze findet ihr im MSDN Visual C# Developer Center.

VN:F [1.9.3_1094]
Rating: 10.0/10 (1 vote cast)
7Mrz/104

.NET: Projekte fuer Mobile Geraete koennen auf dem Desktop ausgefuehrt werden

Ich denke, dass viele von euch es schon längst gewusst haben, aber heute habe ich zufällig entdeckt, dass man die Projekte, die für Smartphones mit Windows Mobile programmiert wurden direkt auf dem Desktop ausführen kann.

Dabei bedarf es keinerlei Anpassung oder Modifikation des Codes. Einfach doppelklicken und ab geht's!

mobileApp_thumb
Bild 1: Das selbe Programm auf beiden Plattformen (Bild von Tom Wendel)

Das ist (so weit ich weiß) einzigartig in der Programmierwelt oder? Denn Java Programme können nicht direkt auf den Desktop ausgeführt werden, und genauso iPhone Apps!

Ich bin mal gespannt, wie lange es dauert bis das Ganze auch umgekehrt möglich ist! :)

Wirklich genial!

VN:F [1.9.3_1094]
Rating: 5.0/10 (2 votes cast)
25Dez/090

.NET Administratorrechte fuer eigenes Programm einfordern

Wenn man mit .NET entwickelt wird man schnell feststellen, dass man zur Laufzeit bestimmte Ordner nicht öffnen kann, bestimmte Dateien nicht löschen oderbestimmte Systemfunktionen nicht ausführen kann!

Das liegt daran, dass dem Programm die nötigen Rechte fehlen, denn seit Windows Vista werden alle Programme ohne Administratorrechte ausgeführt. Braucht ein Programm dann aber doch diese Rechte sieht man diesen wenig gemochten Dialog von Windows:

Bild 1: Windows Benutzerkontensteuerung in Aktion

Das Angezeigte unterscheidet sich dann natürlich je nach Programm, aber sobald man hier auf Zulassen geklickt hat wird das Programm mit den Vollen Rechten gestartet.

Aber woran kann ich erkennen, dass ich volle Rechte benötige? - Ganz einfach, wenn man Fehlermeldungen erhält, die besagen, dass man keine Rechte besitzt um auf die Dienste zuzugreifen, oder wenn Systemfunktionen (zB. WMI) nicht mehr korrekt ausgeführt werden.

Wie sorge ich nun dafür, dass mein Programm Adminrechte erhält? - Hier gibt es zwei Möglichkeiten. Die erste ist es das Programm mit rechter Maustaste anzuklicken und dann "Als Administrator ausführen" zu wählen:

Bild 2: So kann man jedem Programm Administratorrechte geben

Natürlich kann man die Adminrechte direkt in unserem Programm beantragen, in dem man in den Projekteinstellungen im Tab "Anwendung" auf den Button "Einstellungen für die Benutzerkonstensteuerung anzeigen" klickt. Dazu wird die Datei "app.manifest" im Projektordner generiert, die dann folgende Einstellungen beinhaltet:


        <!-- UAC-Manifestoptionen

             Wenn Sie die Ebene der Benutzerkontensteuerung für Windows ändern

             möchten, ersetzen Sie den Knoten "requestedExecutionLevel" wie folgt:

        <requestedExecutionLevel  level="asInvoker" uiAccess="false" />

        <requestedExecutionLevel  level="requireAdministrator" uiAccess="false" />

        <requestedExecutionLevel  level="highestAvailable" uiAccess="false" />

         Wenn Sie aus Gründen der Abwärtskompatibilität Datei- und Registrierungsvirtualisierung

         verwenden möchten, löschen Sie den Knoten "requestedExecutionLevel".

        -->

Wie man in dem Grünen Kommentarblock erkennen kann, gibt es drei verschiedene Einstellungsmöglichkeiten, nämlich level="asInvoker" (welcher voreingestellt ist), level="requireAdministrator" und level="highestAvailable".


  requestedExecutionLevel  level="requireAdministrator" uiAccess="false"

Wenn man nun den unter dem Kommentarblock stehenden Eintrag requestedExecutionLevel auf requireAdministrator ändert, wird unser Programm bei jedem Start automatisch Administratorrechte einfordern, und man wird bei jedem Start diesen unschönen Windows Dialog aus Bild 1 zu sehen bekommen.

Wie ihr euch sicher grade denkt ist das sehr unangenehm für den Benutzer, der später mit der Software arbeiten muss. Dieser muss jedes Mal die Ausführung dieses Programms bestätigen. Außerdem sollte man im Hinterkopf behalten, dass Microsoft diesen Dialog nicht zum Spaß eingeführt hat.

So sollte man immer versuchen seine Software so zu gestalten, dass man auch ohne Administratorreche auskommt. Sollte es aber nicht anders gehen, sollte man den Teil, der diese Rechte benötigt stets aus dem Programm auslagern, sodass dieser Spezielle Fall dann gesondert aufgerufen werden kann und man den Benutzer ggf darauf vorbereiten kann, dass gleich eine Meldung von Windows kommt.

Das Hauptprogramm kann und sollte dann auch weiterhin mit dem geminderten Rechten laufen. So verwirrt man den Benutzer nicht und kann Fehlerquellen später besser eingrenzen.

VN:F [1.9.3_1094]
Rating: 10.0/10 (2 votes cast)
11Dez/091

Programmfortschritt in der Windows Taskleiste anzeigen

Wenn ihr Windows 7 bereits verwendet, werden euch sicherlich einige Neuerungen aufgefallen sein. Einige von denen ist die neue Funktion der Taskleiste den Fortschritt eines Programms darzustellen.

Ihr werdet dies beobachten, wenn ihr z.B. eine Datei mit dem Internet Explorer 8 herunterladet oder eine Datei kopiert. Das Programm zeigt den eigenen Fortschritt dann unter dem Eigenen Symbol in der Taskleiste an.

Diese Funktion ist extrem praktisch, so kann man sie benutzen um den Benutzer immer aktuell zu halten, ohne dass er das eigentliche Programm offen hat. Mögliche Anwendungsfälle wären Dateidownloads, Kopiervorgänge, Bildererzeugung und allgemeine Vorgänge, die etwas Zeit in Anspruch nehmen.

Natürlich können auch wir diese Funktionen in unseren Projekten nutzen. Leider werden die Aufrufe an das Betriebssystem unmanaged gestartet, was bedeutet, dass diese Aufrufe umgewandelt (gewrapped) werden müssen. Da das ein sehr komplexer Vorgang ist hat Microsoft uns diesen gespart und schon einige vorgefertigte Klasse angefertigt auf die wir zurückgreifen können.

Diese Librarys finden wir im MSDN in der .NET Interop Sample Library. Diese Beispielsammlung enthällt viele weitere Beispiele. Wir betrachten hier nur das was mit dem Fortschrittsbalken in der Taskleiste zu tun hat.

Deswegen brauchen wir auch nicht alle Klassen, sondern nur diese:

Vista Bridge Sample Library
Windows7.DesktopIntegration
Windows7.DesktopIntegration. Registration.

Windows7.DesktopIntegration enthält hierbei die Klasse WindowsFormsExtensions, welche uns die nötigen "Extensions"-Funktionen zur Verfügung stellt um das Aussehen der Taskleiste ändern zu können.

In unserem (einfachen) Fall werden wir nur die beiden Methoden benötigen:

SetTaskbarProgress(float percent)
SetTaskbarProgressState(ThumbnailProgressState state)

Mit der Ersten Methode können wir den Fortschritt der Progressbar steuern, und mit der zweiten das Aussehen. Für die zweite Funktion müssen wir neben dem Zustands Parameters auch das Handle des Fensters angeben, für das die Aktion ausgeführt wird.

So könnten die Aufrufe folgendermaßen aussehen:


WindowsFormsExtensions.SetTaskbarProgress(Me.ProgressBar1)
WindowsFormsExtensions.SetTaskbarProgressState(Me, _
                         Windows7Taskbar.ThumbnailProgressState.Error)

Garnicht mal so kompliziert oder?

Dabei kann das Taskleistensymbol unseres Programms 5 verschiedene Werte annehmen:

progresstaskbarBild 1: Cool oder?

Wenn wir nun also ein neues Windows Forms Projekt erstellen müssen wir ersteinmal die drei oben erwähnten Class Librarys importieren. Das machen wir in dem wir über Datei->Hinzufügen->Vorhandenes Projekt wählen

progresstaskbar3Bild 2: Projekte hinzufügen

Auf diese Weise fügen wir alle drei oben erwähnten Projekte dem unseren hinzu. Wenn das geschafft ist müssen wir noch die nötigen Verweise hinzufügen. Dazu wählen wir Projekt->Verweis hinzufügen... und dann den Tab "Projekte"

progresstaskbar4Bild 3: Verweise hinzufügen

Hier wählen wir alle drei Projekte aus und klicken auf "OK"!

Wie ihr nun im Projektmappen Explorer erkennen werdet ist das Projekt gleich mal um einiges gewachsen! Ihr könnt dieses Vorgehen auch umgehen, indem ihr die importierten Class Librarys als DLL kompiliert und direkt in das Projekt einbindet. Das schafft vielleicht mehr Übersicht.

Nun haben wir schon das größte Hindernis schon überwunden! Nun gehts ans Programmieren, wofür ihr die oben vorgestellten Funktionen benutzen könnt um eurem Programm den nötigen Windows 7 Look zu verpassen!

Ich habe dazu wie immer eine kleine Demo angefertigt. Meine sieht so aus:

progresstaskbar2Bild 4: Das Demoprojekt in Aktion

Das Demoprojekt könnt ihr hier laden: Download [VS 2008]

VN:F [1.9.3_1094]
Rating: 8.2/10 (5 votes cast)
Get Adobe Flash playerPlugin by wpburn.com wordpress themes