.NET Blog   ·   .NET Casts   ·   .NET GUI Foren   ·   .NET BlogBook   ·   WPF Blogger   ·   visual studio one   ·   ASP.NET professional

  • 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.
Download .NET Essentials Installer
Trickkiste

Generische Liste mit dynamischem Typ

05.08.08 - .NET, Grundlagen, Base Framework
Beitrag von Norbert Eder
 Da ich gefragt wurde, wie man eine generische Liste mit einem dynamischen Typen erstellen kann, hier ein kurzer Codeteil, welcher genau dies zeigt:
Type t = Type.GetType("System.String");   
IList tempList = (IList)Activator.CreateInstance(
               (typeof(List<>).MakeGenericType(t))
            );  
Console.WriteLine(tempList.GetType().FullName);


  2 Kommentare - 942 mal angesehen   |  0 Trackbacks   |  Permalink  |  Trackback-URL


Events unter .NET

05.05.08 - .NET, Grundlagen, Base Framework
Beitrag von Norbert Eder
 Nachdem immer wieder die Frage auftaucht, wie denn Events unter .NET funktionieren, wie man eigene Events definieren kann usw. habe ich ein kleines Tutorial dafür geschrieben. Zu finden ist es hier.

Auf dass es dem einen oder anderen helfen möge.

  Kommentar hinzufügen   |  0 Trackbacks   |  Permalink  |  Trackback-URL


Na? Welche .NET Framework-Version darf es denn sein?

28.04.08 - .NET, Grundlagen, Base Framework, WPF, ASP.NET, Silverlight, Mobile Devices, Datenverwaltung, Visual Studio, Allerlei
Beitrag von Norbert Eder
 Wohl eine der häufigsten Fragen (gleich neben: "Wie bekomme ich Wert A von Form1 nach Form2?") ist wohl die, welche .NET Framework-Version eingesetzt werden soll/darf/muss.

Ein durchaus nicht (immer) einfach zu klärendes Thema. Grundsätzlich wäre es ja sehr einfach: Nimm die Version, die alles enthält, was du auch wirklich benötigst. Damit läßt sich die Frage jedoch nicht gänzlich beantworten.

Oft sind beim Kunden Prozesse am Laufen, die eine freie Wahl des .NET Frameworks nicht zuläßt (lange Evaluierungsphasen bezüglich der Sicherheit, Funktionsfähigkeit usw. fallen hier auf Anhieb ein). In diesen Fällen muss mit dem Kunden zusammen abgestimmt werden, was denn bei ihm tatsächlich verwendet werden darf. Dies betrifft nicht nur das Framework selbst, sondern auch unterschiedlichste Tools und Libraries aller Art. Bereits im Vorfeld muss eine Abgrenzung stattfinden. Dürfen 3rd Party Controls/Libraries verwendet werden? Wenn ja, welche? Diese und weitere Fragen tauchen auf.

Kunden, die derartige Einschränkungen nicht zu Tage liefern sollten jedoch auch nicht gleich mit der full featured Variante ausgestattet werden. Nach einer ordentlichen Evaluierung der Anforderungen sollte schnell klar sein, welche Komponenten notwendig sind. Dies inkludiert auch das Framework. Zukunftsdenken ist schön und oft auch unerläßlich, dennoch würde es beispielsweise wenig sinnvoll sein, eine Konsolenanwendung zum Datentransfer mit dem .NET Framework 3.5 zu implementieren. Version 2.0 ist vollkommen ausreichend. Im Falle einer Serveranwendung kommt dies eventuell nicht so schwer zu tragen (abgesehen davon, dass am Server wirklich nur das Notwendigste installiert werden sollte). Wird ein Produkt auf zig Hundert Rechner ausgeliefert, kann dies sehr wohl einen Unterschied machen. Version 2 sollte auf den meisten Rechnern installiert sein, 3.5 hingegen nicht. Dies würde einen zusätzlichen Deployment-Aufwand mit sich bringen, der nicht zur Zeit und somit auch Geld kostet, sondern eventuell auch auf der einen oder anderen Maschine zu Problemen führt (Murphy läßt grüßen).

Bei der Wahl der richtigen Framework-Version, als auch der verwendeten Tools und Libraries kann also ruhig auch ein wenig Pragmatismus ins Spiel kommen.

Ähnlich der obigen Überlegung sieht es bei der Entwicklung eines Frameworks aus. Oft erscheint in der Zwischenzeit eine neue Version des Frameworks. Eine Umstellung würde Aufwand bedeuten (mal davon abgesehen, dass eventuell neue Features hinzukommen und der begeisterte Feature-Junkie gleich ein Refactoring und ein Recoding in den Raum wirft). Hier muss überlegt werden, auf welcher Version die darauf aufbauenden Zielprojekte umgesetzt werden (sollen). Ist zu rechnen, dass eben diese Projekte auf die neue .NET Framework Version aufsetzen, sollte wohl eher umgestellt werden (eine spätere Umstellung würde vermutlich wohl noch mehr Zeit und Aufwand kosten). Jedoch muss alles gut überlegt sein.

Bei kleinen Tools und Anwendungen, die eventuell über das Internet zur Verfügung gestellt werden, gehen die Überlegungen eher in die Richtung, welche Framework-Version von den meisten Benutzern eingesetzt wird. Will man unbedingt ein aufregendes Design usw. führt ein Weg an WPF (und damit 3.0 bzw. 3.5) kaum vorbei.

Die Überlegungen sind also sehr zahlreich und eine allgemeine Antwort ist auf diese Frage nicht zu geben. Der Einzelfall muss hinterfragt und beleuchtet werden, dann ergibt sich auch eine entsprechende Antwort.
  1 Kommentar - 187 mal angesehen   |  0 Trackbacks   |  Permalink  |  Trackback-URL


.NET BlogBook Ausgabe 6

14.04.08 - Entwicklung, Diskussionen, Patterns, Software Testing, Projektmgmt., Qualitätsmgmt., .NET, Grundlagen, Base Framework, WPF, ASP.NET, Silverlight, Mobile Devices, Datenverwaltung, Visual Studio, Allerlei, Microsoft Office, SQL Server
Beitrag von Norbert Eder
 Ab sofort steht die 6. Ausgabe des .NET BlogBooks zur Verfügung. Insgesamt stehen nun fast 330 Seiten an puren Informationen und Praxiswissen zur Verfügung.

Noch dazu wurden einige Anregungen aufgegriffen. Es gibt ein neues Cover (ein herzliches Dankeschön an 69° media solutions). Ebenfalls wurden unnötige dunkle Stellen entfernt, die beim Ausdrucken maximal Toner verbrauchen, sonst jedoch keinerlei Wirkung erzielen.

Hauptsächlich wurde das BlogBook um Wissen rund um die Windows Presentation Foundation erweitert, aber auch andere Punkte kamen hinzu. Ein Blick lohnt sich allemal.

Weitere Informationen sind auf der Homepage unter http://www.dotnet-blogbook.com zu finden.

Für Anregungen, Wünsche und (konstruktive) Kritik haben wir natürlich weiterhin ein offenes Ohr.
  6 Kommentare - 1363 mal angesehen   |  1 Trackbacks   |  Permalink  |  Trackback-URL


Das .NET BlogBook bricht die 20.000 Downloads-Schallmauer

02.04.08 - Blog-Intern, .NET, Grundlagen, Base Framework, WPF, ASP.NET, Silverlight, Mobile Devices, Datenverwaltung, Visual Studio, Allerlei, Microsoft Office, SQL Server
Beitrag von Norbert Eder
 Kürzlich wurde der 20.000ste Download vom .NET BlogBook vollführt. Für mich als Herausgeber ist dies natürlich eine große Freude. Schließlich existiert das .NET BlogBook erst seit knapp mehr als einem Jahr.

Das gibt natürlich Motivation für weitere Anpassungen, Ergänzungen und natürlich Verbesserungen.

Vielen Dank auch an alle Leser, die das Team mit Rückmeldungen motivieren oder Verbesserungen anregen.

Danke!

  1 Kommentar - 781 mal angesehen   |  0 Trackbacks   |  Permalink  |  Trackback-URL


Artikel: Techniken miteinander verbinden

17.03.08 - .NET, Grundlagen, Base Framework, WPF, Datenverwaltung
Beitrag von Norbert Eder
  Wie die Zeit vergeht. So habe ich doch glatt vergessen, meinen letzten Artikel in der visual studio one anzukündigen. Das Thema: Techniken miteinander verbinden.

Einzelne Technologien und Techniken sind oft schnell verinnerlicht und werden anfänglich für kleinere Projekte eingesetzt. Meist jedoch getrennt voneinander, um etwaige Fehlerquellen oder ›Blocker‹ zu minimieren. Dieser Artikel zeigt, wie LINQ mit der Windows Presentation Foundation zusammen spielt.

Der gesamte Artikel ist in der Ausgabe 02/08 der Zeitschrift visual studio one zu finden.

Eine Liste der von mir verfassten Artikel ist in der Rubrik Zeitschriften-Artikel zu finden.
  Kommentar hinzufügen   |  0 Trackbacks   |  Permalink  |  Trackback-URL


Mitschnitte vom Microsoft Launch Event

16.03.08 - .NET, Grundlagen, Base Framework, WPF, ASP.NET, Silverlight, Mobile Devices, Datenverwaltung, Visual Studio, Allerlei, SQL Server
Beitrag von Norbert Eder
 Unter dem nachfolgenden Link sind einige Livemitschnitte vom Lauchevent 2008 in Frankfurt zu finden. Zum Ansehen wird das Silverlight-Plugin benötigt.

Hier der Link: Mitschnitte Launch 2008

Und hier die Themen:

- Keynote
- Neu in Visual Studio 2008
- SQL Server 2008
- Überblick Windows Server 2008 Management
- Internet Information Server 7
- Virtualisieren mit dem Windows Server

Viel Spass beim Gucken.
  Kommentar hinzufügen   |  0 Trackbacks   |  Permalink  |  Trackback-URL


Undo und Redo implementieren

12.03.08 - Entwicklung, Diskussionen, Patterns, .NET, Grundlagen, Base Framework, WPF, ASP.NET
Beitrag von Norbert Eder
 Es kommt ja doch häufig vor, dass eine Anwendung ein Undo bzw. ein Redo unterstützen muss. Wird diese Funktionalität gefordert wird immer wieder nach einer Umsetzungsmöglichkeit gefragt. Hier eine kleine Lösung, die für diese Zwecke verwendet werden kann.

Hinweis: In diesem Beispiel werden keine Fehlerabfragen gemacht. Es empfiehlt sich, einen Ausführungsstatus zu integrieren, der das Verhalten entsprechend beeinflusst.

Design


Um diese Funktionalität umzusetzen, wird das Command-Pattern verwendet. Dieses eignet sich sehr gut dazu, Aktionen auszuführen und diese auch wieder zurück zu nehmen. Erweitert wird das Command-Pattern um einen CommandManager, der für die Ausführung und Verwaltung der einzelnen Commands zuständig ist.



Implementierung


Zuerst wird eine Basisklasse für den Command implementiert, welche die Methoden Execute(), Undo und Redo zur Verfügung stellt.

public abstract class Command
{
    public abstract void Execute();

    public abstract void Undo();

    public abstract void Redo();
}


Als weiteren Schritt wird der CommandManager implementiert. Dieser ist in diesem Fall ein Singleton (damit er nur einmal pro Instanz vorhanden sein kann) und bietet nach aussen hin die selbe Funktionalität wie ein Command an. Intern werden die einzelnen Commands jedoch in einem Stack behalten, um den Verlauf der einzelnen Commands nachvollziehen zu können. Darüber kann nun ein Undo bzw. ein Redo abgebildet werden.

public class CommandManager
{
    #region Static Attributes

    private static object _lockObject = new object();
    private static CommandManager _instance = null;

    #endregion Static Attributes

    #region Attributes

    private Stack<Command> _commandStack = new Stack<Command>();
    private Stack<Command> _undoneStack = new Stack<Command>();

    #endregion Attributes

    #region ctor

    private CommandManager() { }

    #endregion ctor

    #region Static Methods

    public static CommandManager GetInstance
    {
        get
        {
            if (_instance == null)
            {
                lock (_lockObject)
                {
                    _instance = new CommandManager();
                }
            }
            return _instance;
        }
    }

    #endregion Static Methods

    #region Public Methods

    public void Execute(Command command)
    {
        command.Execute();
        _commandStack.Push(command);
    }

    public void Redo()
    {
        Command redoCommand = _undoneStack.Pop();
        redoCommand.Redo();
        _commandStack.Push(redoCommand);
    }

    public void Undo()
    {
        Command undoCommand = _commandStack.Pop();
        undoCommand.Undo();
        _undoneStack.Push(undoCommand);
    }

    #endregion Public Methods
}


Damit ist die eigentliche Implementierung bereits abgeschlossen und wir können zu einem ersten Test schreiten. Hierzu benötigen wir ein paar kleinere Klassen, die nicht wirklich etwas aufregendes machen.

Hier eine Klasse Person, die zwei Eigenschaften zur Verfügung stellt, anhand derer getestet wird. Zudem implementiert sie das Interface ICloneable (wird im nachfolgenden Command benutzt) und überschreibt die ToString-Methode.

public class Person : ICloneable
{
    #region Properties

    public String Firstname { get; set; }
    public String Lastname { get; set; }

    #endregion Properties

    #region ICloneable Members

    public object Clone()
    {
        Person p = new Person();
        p.Firstname = this.Firstname;
        p.Lastname = this.Lastname;
        return p;
    }

    #endregion ICloneable Members

    #region Overrides

    public override string ToString()
    {
        return String.Format("{0}, {1}", Lastname, Firstname);
    }

    #endregion Overrides
}


Als nächsten Schritt müssen wir noch einen konkreten Command implementieren, der eine Aktion durchführt. Dieser wird sich lediglich ein wenig mit den Eigenschaften der Person spielen:

public class PersonCommand : Command
{
    private Person _person;
    private Person _personStateBefore;

    public PersonCommand(Person person)
    {
        _person = person;
    }

    public override void Execute()
    {
        _personStateBefore = _person.Clone() as Person;

        _person.Firstname = "Norbert";
        _person.Lastname = "Eder";
    }

    public override void Undo()
    {
        _person.Firstname = _personStateBefore.Firstname;
        _person.Lastname = _personStateBefore.Lastname;
    }

    public override void Redo()
    {
        Execute();
    }
}


Wichtig ist an dieser Stelle nur, dass sich der Command den ursprünglichen Status des übergebenen Objektes merkt und somit eine Undo bzw. Redo-Funktionalität anbieten kann.

Schlussendlich ein Stück Code, welches bei mir in einer Konsolen-Anwendung direkt in der static void Main ausgeführt wird:

CommandManager manager = CommandManager.GetInstance;

Person p = new Person();
p.Firstname = "<not set>";
p.Lastname = "<not set>";
Console.WriteLine(
    String.Format("Before first execution: " + p.ToString()));

manager.Execute(new PersonCommand(p));
Console.WriteLine(
    String.Format("After first execution : " + p.ToString()));

manager.Undo();
Console.WriteLine(
    String.Format("After undo            : " + p.ToString()));

manager.Redo();
Console.WriteLine(
    String.Format("After redo            : " + p.ToString()));

Console.Read();


Und nun möchte ich das Ergebnis nicht vorenthalten:



Fazit


Wie zu sehen ist, ist ein Undo bzw. Redo-Mechanismus sehr einfach zu implementieren. Abhängig der Umgebung in welcher diese Methode zu tragen kommt, müssen eventuell weitere Mechanismen eingefügt werden.
  9 Kommentare - 2601 mal angesehen   |  0 Trackbacks   |  Permalink  |  Trackback-URL


Februar 2008 im Rückblick

03.03.08 - .NET, Grundlagen, Base Framework, WPF, ASP.NET, Silverlight, Datenverwaltung, Visual Studio, Allerlei
Beitrag von Norbert Eder
 Mensch, die Zeit vergeht. Schon wieder ist ein Monat um und dieses Mal bin ich ja wirklich kaum zu neuen Einträgen gekommen. Das lag wohl an der vielen Arbeit die unbedingt erledigt werden wollte. Dennoch hier eine kleine Übersicht der wichtigsten Beiträge:

Design Patterns


Verhalten einer Anwendung per Konfiguration bzw. Laufzeit verändern

Windows Presentation Foundation


Über die Wichtigkeit der Windows Presentation Foundation
Image aus einem WPF-Control erzeugen

Windows Forms


PropertyGrid löst Event PropertyValueChanged bei Collections nicht aus

Sonstiges


Service-Oase Österreich - Internetprovider unleashed

  Kommentar hinzufügen   |  0 Trackbacks   |  Permalink  |  Trackback-URL


Image aus einem WPF-Control erzeugen

07.02.08 - .NET, Base Framework, WPF
Beitrag von Norbert Eder
 Früher oder später stößt jeder WPF-Entwickler auf diese Aufgabe: Aus unterschiedlichsten Gründen muss von einem dargestellten Control eine Grafik erzeugt werden. Wer bereits mit Windows Forms gearbeitet hat, versucht nun vergeblich den Weg über CreateGraphics. Dieser Ansatz funktioniert unter der Windows Presentation Foundation nicht. Stattdessen muss ein anderer Kniff angewandt werden.
Im ersten Schritt kann mittels RenderTargetBitmap ein Bitmap mit der gewünschten Größe erstellt werden. Darin hinein wird nun das entsprechende Control gerendert. Nun müssen wir uns eines Kniffes behelfen (da eventuell die Größe nicht gänzlich korrekt ist). Dazu erstellen wir ein Image-Control, welches das Bitmap als Source erhält und aktualisieren die Größe des Elements entsprechend des Inhaltes mittels der Methoden Measure und Arrange. Nun wird das Image mit der korrekten Größe erneut gerendert und beispielsweise einem Objekt vom Typ PngBitmapEncoder übergeben. Nun kann das Image in einen Stream geschrieben und in ein System.Drawing.Image umgewandelt werden. Hier nun ein Beispielcode:
public System.Drawing.Image Convert(
  FrameworkElement controlToRender)
{
    RenderTargetBitmap rtb = new RenderTargetBitmap(
      (int)controlToRender.ActualWidth, 
      (int)controlToRender.ActualHeight, 
      90, 
      90, 
      PixelFormats.Default);
    
    Visual vis = (Visual)controlToRender;
    rtb.Render(vis);
    
    System.Windows.Controls.Image img = 
      new System.Windows.Controls.Image();
    img.Source = rtb;
    img.Stretch = Stretch.None;
    img.Measure(new System.Windows.Size(
      (int)controlToRender.ActualWidth, 
      (int)controlToRender.ActualHeight));
    System.Windows.Size sizeImage = img.DesiredSize;
    img.Arrange(new System.Windows.Rect(new 
      System.Windows.Point(0, 0), sizeImage));
    
    RenderTargetBitmap rtb2 = new RenderTargetBitmap(
      (int)rtb.Width, 
      (int)rtb.Height, 
      90, 
      90, 
      PixelFormats.Default);
    rtb2.Render(img);
    
    PngBitmapEncoder png = new PngBitmapEncoder();
    png.Frames.Add(BitmapFrame.Create(rtb2));
    
    Stream ms = new MemoryStream();
    png.Save(ms);
    
    ms.Position = 0;
    
    System.Drawing.Image retImg = 
      System.Drawing.Image.FromStream(ms);
    return retImg;
}

Zum PngBitmapEncoder: Hier stehen weitere Encoder bereit. Zusätzliche Informationen sind auf der MSDN-Seite zum Thema BitmapEncoder zu finden. Der Vollständigkeit halber hier die Liste der zur Verfügung stehenden Encoder:
  • BmpBitmapEncoder
  • GifBitmapEncoder
  • JpegBitmapEncoder
  • PngBitmapEncodery
  • TiffBitmapEncoder
  • WmpBitmapEncoder

  2 Kommentare - 3758 mal angesehen   |  0 Trackbacks   |  Permalink  |  Trackback-URL



Zurück Weiter