-
ACHTUNG - NEUES BLOG
Ab sofort steht unter http://devtyr.norberteder.com mein neues Blog zur Verfügung. Dieses Blog wird nicht weiter betreut, bleibt aber erhalten. Neue Eintr%auml;ge erfolgen nur mehr im neuen Blog. Kommentare werden ebenfalls nicht mehr behandelt. Wer weiterhin meinen Einträgen und Aktivitäten folgen möchte, möge bitte RSS-Feeds, Verlinkungen etc. an die neue Location anpassen.
|
.NET BlogBook Ausgabe 4: Inoffizielle HTML Version
17.10.07 - .NET, Grundlagen, Base Framework, WPF, ASP.NET, Datenverwaltung, Visual Studio, Allerlei, Microsoft Office, SQL Server, Internet, Community Beitrag von Norbert Eder
.NET BlogBook Ausgabe 4 inklusive Gewinnspiel
15.10.07 - .NET, Grundlagen, Base Framework, WPF, ASP.NET, Datenverwaltung, Visual Studio, Allerlei, Microsoft Office, SQL Server Beitrag von Norbert Eder| | Die vierte Ausgabe des .NET BlogBook ist ab sofort verfügbar. Nun mit weit mehr Informationen als jemals zuvor - geballt auf 275 Seiten.
Viele Bereiche wurden erweitert, unter anderem:
- Base Framework
- Windows Forms
- ASP.NET
- Tools
Zusätzlich sind auch neue Bereiche zu finden, beispielsweise:
- Windows Communication Foundation
- LINQ
Gewinnspiel
Eine weitere Neuerung: Diesmal gibt es ein Gewinnspiel. Insgesamt werden fünf Jahresabos von wahlweise visual studio one oder ASP.NET Professional unter allen Teilnehmern verlost. Weitere Informationen finden sich direkt im BlogBook auf Seite 3.
Zum .NET BlogBook
| | | 8 Kommentare
- 1091 mal angesehen
| 0 Trackbacks
| Permalink | Trackback-URL |
C#: Arbeit mit der Registry
10.10.07 - .NET, Grundlagen, Base Framework, Datenverwaltung Beitrag von Norbert Eder| | Die Registry wird noch immer häufig verwendet, um bestimmte Daten zu hinterlegen. .NET bietet hierfür die Klasse RegistryKey.
Hier ein Beispielcode wie Daten in die Registry geschrieben werden können:
RegistryKey rk = Registry.CurrentUser;
RegistryKey rkSoftware =
rk.OpenSubKey("Software", true);
if (rkSoftware != null)
{
RegistryKey rkCompany =
rkSoftware.OpenSubKey("Norbert Eder",true);
if (rkCompany == null)
{
rkCompany = rkSoftware.CreateSubKey("Norbert Eder");
}
RegistryKey rkInstaller =
rkCompany.OpenSubKey("MySoftware", true);
if (rkInstaller == null)
rkInstaller = rkCompany.CreateSubKey("MySoftware");
rkInstaller.SetValue("value1", "test1");
rkInstaller.SetValue("value2", "test2");
rkInstaller.Close();
rkCompany.Close();
rkSoftware.Close();
}
rk.Close();
Natürlich müssen die Werte auch wieder ausgelesen werden. Dies passiert auf folgende Art und Weise:
RegistryKey rk =
Registry.CurrentUser.OpenSubKey
(@"Software\Norbert Eder\MySoftware");
if (rk != null)
{
string value1 = (string)rk.GetValue("value1");
string value2 = (string)rk.GetValue("value2");
rk.Close();
}
Damit sollte es nun einfach möglich sein, Werte in die Registry zu schreiben und daraus auszulesen. Eventuell empfiehlt es sich, hier noch genauer im MSDN nachzulesen, um zusätzliche Informationen zu erhalten.
| | | Kommentar hinzufügen
| 0 Trackbacks
| Permalink | Trackback-URL |
Controls auf einem Formular bewegen
10.10.07 - .NET, Grundlagen, Base Framework, WPF Beitrag von Norbert Eder| | In Foren als auch meiner Inbox taucht immer wieder die Frage auf, wie man denn bewegbare Controls erstellen kann, um beispielsweise ein Diagramm zu zeichnen etc. Deshalb möchte ich hier ein ganz kleines Beispiel zeigen, wie in zwei Minuten eine bewegliche Basisklasse für bewegliche Controls erstellt werden kann. Und hier kommt schon der Sourcecode:
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Drawing;
using System.Data;
using System.Text;
using System.Windows.Forms;
namespace MoveableControlDemo
{
public partial class MoveableBaseControl
: UserControl
{
private bool _isMoving = false;
private int _deltaX = 0;
private int _deltaY = 0;
public MoveableBaseControl()
{
InitializeComponent();
}
private void MoveableBaseControl_MouseDown(
object sender,
MouseEventArgs e)
{
_isMoving = true;
_deltaX = e.X;
_deltaY = e.Y;
}
private void MoveableBaseControl_MouseUp(
object sender,
MouseEventArgs e)
{
_isMoving = false;
}
private void MoveableBaseControl_MouseMove(
object sender,
MouseEventArgs e)
{
if (_isMoving && e.Button == MouseButtons.Left)
{
this.Location = new Point(
this.Location.X + (e.X - _deltaX),
this.Location.Y + (e.Y - _deltaY)
);
}
}
}
}
Im Grunde passiert nicht viel. Es wird lediglich festgehalten wann sich das Control bewegen soll und wann nicht (MouseDown und MouseUp). Bei einem MouseMove wird anschließend die Position des Controls berechnet. Zu beachten ist hier nur, dass die MouseEventArgs die Position des Cursors innerhalb des Controls angibt und nicht auf Formular- bzw. Screen-Basis. Daher muss das Delta zum Rand des Controls beim MouseDown festgehalten werden, um dies später in die Berechnung einfließen zu lassen.
Dieses Control kann sozusagen als ein Basis-Control verwendet werden. Zum Test einfach in ein Projekt einbauen, auf ein Formular ziehen, Anwendung starten und mit der Maus über das Formular bewegen.
| | | Kommentar hinzufügen
| 0 Trackbacks
| Permalink | Trackback-URL |
AutoScroll für RichTextBox
04.10.07 - .NET, Grundlagen, Base Framework, WPF Beitrag von Norbert Eder| | In der letzten Zeit wurde ich des öfteren gefragt, wie man denn eine RichTextBox dazu bringt, automatisch zu scrollen, sobald neuer Text hinzugefügt wird (wenn diese beispielsweise als Ausgabe für Log-Informationen verwendet wird). Hier wie ich es mache:
this.LogRtb.Text += "My additional log text ...";
this.LogRtb.SelectionStart = this.LogRtb.Text.Length;
this.LogRtb.ScrollToCaret();
| | | Kommentar hinzufügen
| 0 Trackbacks
| Permalink | Trackback-URL |
.NET Framework zukünftig inklusive Sourcecode?
04.10.07 - .NET, Base Framework, Visual Studio Beitrag von Norbert Eder| | Scott Guthrie berichtet in seinem Blog darüber, dass Microsoft mit dem neuen Framework 3.5 und Visual Studio 2008 auch den Sourcecode mit ausliefern möchte - um das Debugging zu erleichtern. Konkret meint er:
"We'll begin by offering the source code (with source file comments included) for the .NET Base Class Libraries (System, System.IO, System.Collections, System.Configuration, System.Threading, System.Net, System.Security, System.Runtime, System.Text, etc), ASP.NET (System.Web), Windows Forms (System.Windows.Forms), ADO.NET (System.Data), XML (System.Xml), and WPF (System.Windows). We'll then be adding more libraries in the months ahead (including WCF, Workflow, and LINQ). The source code will be released under the Microsoft Reference License (MS-RL).
Na, da bin ich doch mal gespannt. Auf jeden Fall eine sinnvolle Idee mit der sicherlich kaum jemand gerechnet hat ...
| | | 2 Kommentare
- 618 mal angesehen
| 0 Trackbacks
| Permalink | Trackback-URL |
Exception Handling und Security
01.10.07 - .NET, Grundlagen, Base Framework, WPF, ASP.NET Beitrag von Norbert Eder| | Zum Exception Handling habe ich bereits hier, hier und hier berichtet. Was aber bis dato gefehlt hat, war eine Aussage zum Thema Sicherheit bei der Behandlung von Ausnahmen.
Was also hat das Behandeln von Ausnahmen mit Sicherheit zu tun?
In den meisten Fällen wird bei einer Exception der Inhalt der Eigenschaft Message zurückgegeben und in der Hauptanwendung (egal ob Windows Forms, Web, WPF) zur Anzeige gebracht. Dadurch werden jedoch in manchen Fällen Daten zum Vorschein gebracht, die besser im Verborgenen bleiben sollten. Nehmen wir das Beispiel Webanwendung. Gehen wir weiters davon aus, dass diese eine Verbindung zu einer Datenbank benötigt. Nun wird hier im System ein ConnectionString hinterlegt (natürlich gilt es auch diesen abzusichern). Nun kann folgendes Problem auftreten:
Die Anmeldung auf den Datenbank-Server schlägt fehl. Daraufhin wird eine Exception geworfen, welche dann im User-Interface angezeigt wird (entsweder per eigener Fehlerseite oder überhaupt als Exception). Aus dem Message-Text ist nun ersichtlich, dass die Anmeldung scheitterte und mit welchem User die Anmeldung versucht wurde.
Ein potentieller Angreifer hat nun ein leichteres Spiel, da er einen User für die Datenbank definitiv kennt.
Dies ist nur ein einfaches Beispiel. Aus diesem Grunde sollten Exception-Messages niemals direkt an den User weitergegeben werden. Folgende Vorgehensweise ist hier empfohlen:
1. Jede Exception abfangen
2. Exceptions in eine Log-Datei loggen (Bei Webanwendungen sollte die Log-Datei in ein Verzeichnis geschrieben werden, welches nicht über das Web zugänglich ist)
3. Fehlertexte, die an den User gehen sollten unbedingt zuvor angepasst werden. D.h. ein eigener Wortlaut muss deklariert werden.
Schließlich bleibt noch zu erwähnen, dass dem User nicht jeder Fehler sichtbar gemacht werden muss. Mit vielen Fehlern kann der Unser ohnehin nichts anfangen und sie verwirren ihn nur. Ergo immer überlegen, ob die Benachrichtigung im speziellen Fall sinnvoll ist oder nicht.
| | | 2 Kommentare
- 559 mal angesehen
| 1 Trackbacks
| Permalink | Trackback-URL |
C# 3.0: Anonyme Typen
28.09.07 - .NET, Grundlagen, Base Framework, Allerlei Beitrag von Norbert Eder| | Nachdem ich bereits über Anonymen Delegates (auch unter .NET 2.0 verfügbar) als auch dem unter C# 3.0 neuen Keyword var geschrieben habe, möchte ich ein wenig über Anonyme Typen schreiben.
Anonyme Typen sind ähnlich zu anonymen Methoden (dazu kommen wir dann auch in einem der nächsten Blogbeiträge).Dies bedeutet, dass anonyme Typen inline gebildet werden können. Um dies zu verdeutlichen gleich ein kleines Beispiel:
Wie zu sehen ist, ist hierfür das Schlüsselwort var zu verwenden. Die Definition erfolgt inline und definiert welche Eigenschaften der neue Typ hat. Selbst IntelliSense kennt die neuen Eigenschaften.
Anonyme Typen kennzeichnen sich dadurch aus, dass sie keinen zugewiesenen Namen besitzen (dies ist auch in der Typen-Beschreibung - siehe IntelliSense - ersichtlich).
Werden im gleichen Scope zwei anonyme Typen definiert, welche die gleiche Signatur besitzen, kann der erste Type den zweiten einfach übernehmen, wie nachfolgend zu sehen:
Wozu werden anonyme Typen nun gebraucht?
Zum einen wurden anonyme Typen natürlich für LINQ eingeführt. Diese werden dort häufig verwendet und bilden daher eine Notwendigkeit. Aber auch für andere Zwecke können sie verwendet werden.
Grundsätzlich bieten sich anonyme Type dann an, wenn ein Typ kurzfristig (für die Ausgabe etc.) benötigt wird, aber nicht für die gesamte Anwendung zur Verfügung stehen muss. In diesem Fall muss also keine eigene Klasse erstellt werden, welche schlussendlich nur an einer einzigen Stelle verwendet werden würde. Wann anonyme Typen einzusenden sind bleibt jedem Entwickler selbst überlassen. Unter dem obigen Gesichtspunkt sollte aber durchaus klar sein, wann eine Verwendung sinnvoll ist und wann weniger.
| | | Kommentar hinzufügen
| 0 Trackbacks
| Permalink | Trackback-URL |
Anonymous Delegates
25.09.07 - .NET, Grundlagen, Base Framework Beitrag von Norbert Eder| | Dem einen oder anderen mögen anonyme Methoden (oder beispielsweise anonyme Typen wie sie mit C# 3.0 kommen) bekannt sein. In diesem Beitrag möchte ich ein wenig über anonyme Delegates schreiben und wozu diese benötigt werden (sind ohnehin sehr ähnlich zu anonymen Methoden).
Zuerst gleich das Beispiel, anhand dessen die Erklärungen vorgenommen werden:
using System;
using System.Collections.Generic;
using System.Text;
namespace AnonymousDelegatesSample
{
public class Book
{
public string Title;
public decimal Price;
}
public class Person
{
public string Firstname;
public string Lastname;
public List<Book> BookList;
public decimal Discount;
public DiscountCalculator CalculationMethod;
}
public delegate decimal DiscountCalculator(decimal price);
public class Example
{
private decimal CalculateDiscount(decimal price)
{
return price * new decimal(0.05);
}
public void ShowExample()
{
DiscountCalculator default_calc =
new DiscountCalculator(CalculateDiscount);
DiscountCalculator specialcustomer_calc =
delegate(decimal price)
{
return price * new decimal(0.09);
};
Book book1 = new Book();
book1.Title = "ASP.NET for dummies";
book1.Price = new decimal(35.99);
Book Book2 = new Book();
Book2.Title = "C# for dummies";
Book2.Price = new decimal(49.99);
List<Book> bookList = new List<Book>();
bookList.Add(book1);
bookList.Add(Book2);
List<Person> personList = new List<Person>();
Person person1 = new Person();
person1.Firstname = "Norbert";
person1.Lastname = "Eder";
person1.BookList = bookList;
person1.CalculationMethod = specialcustomer_calc;
personList.Add(person1);
Person person2 = new Person();
person2.Firstname = "Alf";
person2.Lastname = "Dudldei";
person2.BookList = bookList;
person2.CalculationMethod = default_calc;
personList.Add(person2);
foreach (Person p in personList)
{
decimal price = 0;
foreach (Book b in p.BookList)
price += b.Price;
p.Discount = p.CalculationMethod(price);
Console.WriteLine(
String.Format("{0} {1}:t {2} discount",
p.Firstname,
p.Lastname,
p.Discount.ToString()));
}
Console.WriteLine("Press any key ...");
Console.ReadKey();
}
}
}
Zuerst ein kurze Erklärung wozu dieses Beispiel dient: Grundsätzlich gibt es zwei Klassen. Zum einen die Person und zum anderen das Book. Wir gehen also davon aus, dass eine Person Bücher kauft und diese in einer Collection aufbewahrt werden. Nun soll (je nach Kundenstatus) ein Rabatt berechnet werden.
Zur Erklärung: Dies kann natürlich auch auf eine andere - vermutlich einfachere Art und Weise implementiert werden. Dieses Beispiel dient lediglich der Veranschaulichung von anonymen Delegates.
Grundsätzlich ist in diesem Beispiel ein üblicher Delegate definiert:
public delegate decimal DiscountCalculator(decimal price);
Dieser wird im Standardfall auch verwendet, um eine Methode aufzurufen, die für die Rabattberechnung zuständig ist.
DiscountCalculator default_calc =
new DiscountCalculator(CalculateDiscount);
Die aufgerufene Methode sieht dann so aus:
DiscountCalculator default_calc =
new DiscountCalculatprivate decimal CalculateDiscount(decimal price)
{
return price * new decimal(0.05);
}or(CalculateDiscount);
Nun kann es jedoch vorkommen, dass eine spezielle Berechnung durchgeführt werden muss, diese wird nur in einem ganz bestimmten Fall angewandt und bedarf daher keiner eigenen Methoden-Implementierung (in diesem Beispiel vielleicht weniger sinnvoll, aber generell treten bei der Verwendung von Delegates immer wieder Fälle auf, in denen sich eine eigene Methode nicht rentiert). Hier kommen nun anonyme Delegates ins Spiel. Die aufgerufene Methode ist hierbei ansich nicht vorhanden (daher anonym) und wird erst bei der Erstellung des Delegate definiert. Wie hier:
DiscountCalculator specialcustomer_calc =
delegate(decimal price)
{
return price * new decimal(0.09);
};
Damit wird im Grunde erreicht, dass die eigentliche Berechnung durch eine neue ersetzt wird. Eine entsprechende Methode muss hierzu nicht vorhanden sein.
Einsatzgebiete hierfür finden sich immer wieder, daher grundsätzlich nicht schlecht, wenn man sie kennt und auch anwenden kann. Im Falle des Falles muss der Entwickler ohnehin selbst entscheiden ob dies sinnvoll ist oder nicht. Wird die Berechnung anderweitig verwendet ist es sicherlich sinnvoll, diese in eine eigene Methode zu kapseln. Andernfalls kann durchaus ein anonymer Delegate verwendet werden.
| | | Kommentar hinzufügen
| 0 Trackbacks
| Permalink | Trackback-URL |
C# 3.0: Keyword var
18.09.07 - .NET, Grundlagen, Base Framework Beitrag von Norbert Eder| | Nein, var steht hier nicht in nostalgischer Verbindung zu Visual Basic. Vielmehr handelt es sich – streng genommen – auch nicht wirklich um ein Schlüsselwort (Keyword). Schlüsselwörter dürfen ja nicht in Klassen, Strukturen etc. verwendet werden, var hingegen sehr wohl. Aber unabhängig dieser Tatsache, was verbirgt sich dahinter?
Beginnen wir mit einem kleinen Beispiel:
var htTemp = new Hashtable();
In diesem Fall versucht der Compiler auf den Typ von strList zu schließen, was auch kein Problem darstellt, da dieser ohnehin durch new Hashtable() definiert wird. Es entfällt also die lange und natürlich auch unschöne und redudante Darstellung á la:
Hashtable htTemp = new Hashtable();
Manche mögen nun der Meinung sein, dass sich C# dadurch von der starken Typisierung verabschiedet. Dem ist jedoch nicht so. Wurde die Variable deklariert, wird auf ihren Typ geschlossen und zugewiesen. Der Typ kann an einer späteren Stelle nicht mehr verändert werden (wie dies beispielsweise unter VB.NET möglich ist).
Ebenfalls sei zu betonen, dass var auch nur bei der Initialisierung verwendet werden kann.
| | | 5 Kommentare
- 618 mal angesehen
| 0 Trackbacks
| Permalink | Trackback-URL | Zurück Weiter
|
|
|
|
|
|
|