Bernhard's profileBernhard Grojer - BlogPhotosBlogLists Tools Help

Blog


    July 16

    Centrino 2


    Endlich war es soweit. Intel stellte die Centrino2 Platform vor. 

    So und nun hätte ich gern noch ein Notebook:
    - 13,3 LED Display (mit 1400+ Auflösung)
    - 256 GB SSD
    - eSata Anschluss
    - 2,5 GHZ+ CPU mit P Prefix
    - 4 GB Ram (8 wäre auch ok :D)
    - WiFiLink 5300 mit 450 Mbps
    - 4h+ Akkulaufzeit
    - max 2,5 kg

    Und das alles bitte in einem vernünftigen Gehäuse das nicht nach 3 mal "onroad" ausschaut als hätte man auf dem Teil geparkt.

    Hersteller ... ich warte :D

    July 15

    C# 4.0

    Erstes Infos vom Team zu C# 4.0 gibts auf Channel9.

    Anders Hejlsberg (Wer? Sie wissen schon: Pascal, Delphi, C#, LINQ, ... - irgendwer muss sich das ja ausgedacht haben) und der Rest vom C# Team erzählen ein bisschen über die Zeile die Microsoft für C# 4.0 hat.

    Eventull wird es nun doch noch etwas Yoda Syntax.

    Von Spam, Captchas und dem täglichen Kampf dagegen


    Hannes hat sich vor kurzem zu der Lösung eines unschönen Spam-Problems geäußert.

    Selbiges geht auch ohne (eigenen) Programmieraufwand. Im aktuellen AJAX Control Toolkit gibts dafür ein Control mit dem Namen NoBot.

    July 03

    Farben aus System.Drawing.Color auflisten

    WIe bereites hier gepostet haben wir Bedarf gehabt die Farben aus System.Drawing.Color aufzulisten.

    Alternativ gehts auch mit LINQ und DataBinding:

    var res = from c In System.Enum.GetNames(GetType(KnownColor))
    Where Color.FromName(c).IsSystemColor

    DropDownList1.DataSource = res
    DropDownList1.DataBind()

    Sie sehen mal wieder: Mit LINQ können Sie sich das leben in fast jeden bereicht leichter machen.

    June 08

    Microsoft PDC - 27.-30. Oktober 2008


    Microsoft PDC: http://www.microsoftpdc.com/

    Status: Flug ab Wien via London gebucht.

    WPF - ContextMenu via Code anzeigen


    ctx.Placement = PlacementMode.Relative;
    ctx.PlacementTarget = this;
    ctx.PlacementRectangle = new Rect(30, 50, 0, 0);
    ctx.IsOpen = true;


    Sieht unschön aus und ist viel zu tippen. Lösung? Extension Methods aus .net 3.5.

    ctx.Show(30, 50, this);

    Besser?

    Wie ist .Show definiert?

    public static class Extensions
        {
            public static void Show(this ContextMenu ctx, double PositionX, double PositionY, UIElement relativeTo)
            {
                ctx.Placement = PlacementMode.Relative;
                ctx.PlacementTarget = relativeTo;
                ctx.PlacementRectangle = new Rect(PositionX, PositionY, 0, 0);
                ctx.IsOpen = true;
            }
        }

    Download des Samples gibt es hier.

    June 07

    Silverlight 2.0 - Beta 2


    Seit gestern gibt es eine neu Version von Silverlight. Die Beta2 soll deutlich mehr Controls - out of the box - beinhalten.

    Infos gibt es im Blog von Scott Guthrie.

    May 13

    .net Framework 3.5 - Beta1


    Ihr dachtet die stressigen Tage sind vorbei? .net 3.5 Release und es wird ruhiger?

    Schwer getäuscht,- .net Framework 3.5 SP1 Beta1 ist hier mit vielen Änderungen ...

    Scott Guthrie (wer auch sonst) hat die wichtigsten Information zusammengestellt.

    May 05

    Bitmaps in WPF (Transparenz-Angabe)


    Nehmen wir mal an, wir haben ein Bitmap das wir in unserer Anwendung darstellen wollen.

    Kein Problem in WPF:

    <Image Source="img.bmp" />

    TransparentWpfShoot2 

    Doch der Magenta-Hintergrund ist nicht unbedingt das Ergebnis das wir erwartet haben. Transparenz muss also her.
    Eine Möglichkeit wäre zu PNG oder dem GIF Format zu greifen. Alternativ hatten wir in WinForms die Option TransparentColor zu verwenden.

    In WPF wird die Sache leider etwas mühsamer.

    Wir können uns einen eigenen Converter für die Problemstellung schreiben:
    public class BitmapTransparentConverter : IValueConverter
        {
            #region IValueConverter Members

            public object Convert(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
            {
                BitmapDecoder decoder = BitmapDecoder.Create(new Uri(value.ToString(), UriKind.Relative), BitmapCreateOptions.None, BitmapCacheOption.Default);

                BitmapSource sourceImage = decoder.Frames[0] as BitmapSource;
                Color transparentColor = Colors.Magenta; //Alternativ IMultiValueConverter und als Paramter verwenden

                sourceImage = new FormatConvertedBitmap(sourceImage, PixelFormats.Bgra32, null, 0.0);
                int step = (sourceImage.PixelWidth * sourceImage.Format.BitsPerPixel) / 8;
                byte[] pix = new byte[sourceImage.PixelHeight * step];
                sourceImage.CopyPixels(pix, step, 0);
                byte r = transparentColor.R;
                byte g = transparentColor.G;
                byte b = transparentColor.B;

                for (int i = 0; i < sourceImage.PixelHeight * step; i += (sourceImage.Format.BitsPerPixel / 8))
                {
                    if (pix[i] == b && pix[i + 1] == g && pix[i + 2] == r)
                        pix[i + 3] = 0;
                }
                return BitmapSource.Create(sourceImage.PixelWidth, sourceImage.PixelHeight,
                                    sourceImage.DpiX, sourceImage.DpiY, PixelFormats.Bgra32, sourceImage.Palette, pix, step);
            }

            public object ConvertBack(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
            {
                throw new NotImplementedException();
            }

            #endregion
        }

    Danach noch einbinden in die Resourcen:

    <Window.Resources>
            <local:BitmapTransparentConverter x:Key="BitmapConverter">           
            </local:BitmapTransparentConverter>
    </Window.Resources>

    und nun konsumieren:

    <Image>
                <Image.Source>
                    <Binding Converter="{StaticResource BitmapConverter}" Source="img.bmp" />
                </Image.Source>           
    </Image>

    TransparentWpfShoot1 

    Aber Achtung. Performance ist nicht unbedingt optimal, wenn wir jedes mal (unnötig) konvertieren müssen um das Bild darzustellen.
    Die KonverterKlasse kann dafür natürlich beliebig ausgebaut werden (Caching, ...)

    Code zum Download

    March 08

    MIX 08 - Las Vegas ...


    ... und wie gewohnt können wir ab sofort alle Sessions / Slides downloaden unter: http://sessions.visitmix.com/

    Ist mehr als nur einen Blick wert.

    February 28

    Windows Live SkyDrive

    In der Zwischenzeit gibts 5 GB (kostenlos) für den Austausch von Dateien. Freigabe auf LiveID Ebene, als Backup für sich selbst oder generell für die Öffentlichkeit.

    Super einfach fürn schnellen Dateiaustausch.

    Mehr Infos gibts hier: SkyDrive Team Blog

    February 14

    Windows Vista SP1 RTM - Verfügbar


    Nachdem es mit der Fertigstellung von Vista SP1 etwas Verwirrung gab kann ab sofort via Technet Plus ab sofort VISTA SP1 runterladen.

    Mehr Infos gibts hier: http://technet.microsoft.com/de-de/subscriptions/default.aspx

    February 02

    ObjectDataSource - LINQ - BusinessObjects - Entitys (Part 2 - Workaround)

    Wie bereits in meinem Blogeintrag berichtet ist die Verwendung der ObjectDataSource in Verbindung mit LINQ nicht völlig unproblematisch.

    Eine Lösung wäre es, wenn wir die ObjectDataSource durch unsere eigene Implementierung ersetzen können. Doch dies hätte zur folge, dass wir die DesignTools nicht mehr verwenden können und außerdem dediziert in JEDE Website eingreifen müssen.

    Auf der Suche nach einen Lösungsansatz bin ich auf die Idee gekommen <tagMapping> zu verwenden. Damit lässt sich eine eigene Klasse verwenden, die von der Basisklasse abgeleitet ist. Somit sind wir dem Problem schon einen Schritt näher gekommen.
    Schnell werden wir allerdings wieder enttäuscht werden, da sich die "Update, Insert, Delete, ..." Methoden NICHT überschreiben lassen.

    Allerdings benutzt die ObjectDataSource intern eine Instanz/Klasse vom Type ObjectDataSourceView. Bei dieser Klasse ist es möglich, die Methoden (Update, Insert, ...) entsprechend unserer Wünsche abzuleiten.

    Bleibt nur noch die Frage, wie wir unsere eigene (abgeleitete) Implementierung des ObjectDataSourceView in unsere ObjectDataSource einfügen.

    Im Konstruktor der unserer abgeleiteten ObjectDataSource haben wir mittels Reflection allerdings eine Möglichkeit:

    var currentEntityObjectDataSourceView = new EntityObjectDataSourceView(this, DefaultViewName, Context);
    var targetField = typeof(System.Web.UI.WebControls.ObjectDataSource).GetField("_view", BindingFlags.Instance | BindingFlags.NonPublic);
    targetField.SetValue(this, currentEntityObjectDataSourceView);
    if (IsTrackingViewState)
        ((IStateManager)currentEntityObjectDataSourceView).TrackViewState();

    Somit haben wir eine kompatible ObjectDataSource die automatisch durch tagMapping anstatt der orig. Version benutzt wird.
    Intern wird eine abgeleite Version der ObjectDataSourceView benutzt, die wir mittels Reflection ausgetauscht haben.

    January 20

    ObjectDataSource - LINQ - BusinessObjects - Entitys (Part 1 - Die Problemstellung)

    Schonmal versucht eine Manager-Klasse zu erzeugen die Insert,Update,Delete für die ObjectDataSource anbietet?
    Nun die ODS bietet dafür mehre Möglichkeiten. Eine davon ist es das Object selbst zu übergeben anstatt unzählige Überladungen der Update/Insert/Delete-Methode zu erzeugen die noch dazu bei jeder Änderung der betroffenen Klasse apdatiert werden.
    Besonders wenn die Applikation an Umfang zunimmst ist diese Variante ziemlich mühsam.

    namespace Sample.Manager
    {
        [DataObject()]
        public class PersonEntityManager
        {
            [DataObjectMethod(DataObjectMethodType.Select)]
            public bool GetById(Guid ID)
            {
                //Code to load (LINQ?)
            }
    
            [DataObjectMethod(DataObjectMethodType.Insert)]
            public bool Insert(Person p)
            {
            }
    
            [DataObjectMethod(DataObjectMethodType.Update)]
            public bool Update(Person p)
            {
                //Code to save (LINQ?)
            }
    
            [DataObjectMethod(DataObjectMethodType.Delete)]
            public bool Delete(Person p)
            {
            }
        }
    }

    Sieht doch mal recht, simple aus aber man wird schnell ferstellen, dass man auf einige Probleme stossen wird.
    Eines davon liegt in der Natur des HTTP Protokolls. Es ist statuslos.
    Wir bekommen daher beim Update/Insert/Delete immer eine neue Instanz des Entitys (im Beispiel die Klasse Person). Die ODS befüllt zwar schön alle Werte die es kennt (Werte aus den DataKeys sowie die Werte die "angezeigt" werden) jedoch bleibt der Rest unbefüllt.

    Für uns ist es zu diesem Zeitpunkt leider unmöglich festzustellen, welche Werte tatsächlich geändert wurden vom User und welche lediglich die "Default-Werte" des Objekts sind ...

    Mein bisheriges Workaround war die Änderungen mitzuprotokollieren (beim Setter des Objekts wird der Name des Propertys gespeichert)
    In der Update Methode hab ich nun das orig. Objekt geladen, und lediglich die "tatsächlich" gesetzten Werte auf das orig. Objekt gemappt hat und dieses zum Speichern an den DAL weiterreichte.

    Doch genau diese Funktionalität kann man in Verbindung mit LINQ nicht mehr (so einfach) verwenden, vorausgesetzt man möchte nicht auf LINQ-TO-SQL Desinger bzw. auf SQLMetal.exe zur Codegenerierung verzichten.

    Was machen wir also? Die ObjectDataSource ein klein wenig anpassen.
    Das Vorteil dadurch: Wir tausche in der web.config die orig. ODS durch unsere eigene Variante aus und müssen somit unsere einzelnen Websites NICHT anfassen oder Code einfügen. Selbst alle Design-Tools in VisualStudio können weiter benutzt werden.
    Mehr dazu jedoch in Part 2.

    January 18

    VSone 2008 - 13. - 14. Feb. 2008 in München

    Auf der VSone in München werde ich einen Talk zum Thema LINQ halten.

    VSone 

    Ich freue mich.

    Source Code .NET Framework verfügbar

    Wie bereits im Oktober des letzten Jahres im Blog von Scott Guthrie angekündigt wurde, ist es nun tatsächlich soweit.
    Der Source Code des .NET Frameworks wurde offengelegt.

    Direkt aus Visual Studio 2008 kann nun in die .NET Libraries steppen. Wie funktionierts? Im Blog von Shawn Burke findet man die Antwort.

    January 15

    LINQ - Vererbung bei Entites

    Wie Dinesh Kulkarni - seines Zeichen Programm-Manager vom LINQ-Project - vor kurzem in seinen Blog über eine gemeinsame Basis-Klasse berichtete hat man mit LINQ durchaus die Möglichkeit Vererbung abzubilden.

    Doch leider ist nicht alles Gold, dass beim ersten Anblick glänzt. "Manche" LINQ-Querys gegen die vererbten Members scheitern danach.

    Setzt man ein nun eine Abfrage gegen den DataContext ....

    GUID ID; //Value from somewhere else ...
    var DB = new MyDataContext(;
    var res = from c in DB.Customers
    Where c.ID == ID
    Select c;

    ... ab, wird man unweigerlich mit dieser Fehlermeldung zur Laufzeit ...

    Class member EntityBase.ID is unmapped

    ... belohnt.

    Macht man sich die Mühe und castet c bei der Where-Abfrage in einen Customer, dann läuft die Sache wieder:

    GUID ID; //Value from somewhere else ...
    var DB = new MyDataContext(;
    var res = from c in DB.Customers
    Where ((Customer)c).ID == ID
    Select c;


    Eigenartiger ist auch, dass das selbe Phänomen TEILWEISE bei Lamda Expressions zu beobachten ist.

    Folgendes Statement führt zu einer Exception

    var c = DB.Customers.SingleOrDefault(p => p.ID == ID);

    hingegen läuft

    var c = DB.Customers.Where(p => p.ID == ID).SingleOrDefault();

    einwandfrei.

    January 14

    Willkommen im Blog


    Lange Zeit hat es gedauert und nun ist es soweit und ein weiteres Blog hat das Licht der Welt erblickt.

    MCT