July 16
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
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.
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
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.
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
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
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
Nehmen wir mal an, wir haben ein Bitmap das wir in unserer Anwendung darstellen wollen.
Kein Problem in WPF:
<Image Source="img.bmp" />
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>
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
... 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
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 02
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
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
Auf der VSone in München werde ich einen Talk zum Thema LINQ halten.
Ich freue mich.
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
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
Lange Zeit hat es gedauert und nun ist es soweit und ein weiteres Blog hat das Licht der Welt erblickt.
