Noodles.NET

Sunday, November 18, 2007

Ich habe eben einen Artikel zu den Spracherweiterungen von C# 3.0 erstellt.
Spracherweiterungen in C# 3.0

Tuesday, November 06, 2007

LINQ to SQL ( Teil 1 )

LINQ to SQL ist ein O/R Mapper, welcher mit dem .NET Framework 3.5 mitkommt. LINQ to SQL erlaubt es, relationale Daten als .NET Klassen zu modellieren. Die Daten können sowohl gelesen, als auch manipuliert werden. Dabei unterstützt LINQ to SQL Transaktionen, Views, Gespeicherte Prozeduren und benutzerdefinierte Funktionen.

Visual Studio 2008 hat einen Designer, um die Daten zu modellieren.



Die DataContext Klasse übernimmt die eigentliche Arbeit. Diese Klasse kapselt den Zugriff auf die Datenbank.

Codebeispiele in C#:
Das folgende Beispiel alle Kunden aus London zurück.

using(NorthwindDataContext ctx = new NorthwindDataContext())
{
var customers = from c in ctx.Customers
where c.City == "London"
select c;
}


Ein Kunde bearbeiten und speichern.

using(NorthwindDataContext ctx = new NorthwindDataContext())
{
Customer customer =
ctx.Customers.Single( c => c.CustomerID == "ALFKI" );
customer.City = "New City";
ctx.SubmitChanges();
}


Einem Kunde eine Bestellung hinzufügen.

using(NorthwindDataContext ctx = new NorthwindDataContext())
{
Customer customer =
ctx.Customers.Single( c => c.CustomerID == "ALFKI" );
Order order = new Order
{
OrderDate = DateTime.Now,
ShipCountry = "Berlin",
ShippedDate = DateTime.Now.AddMonths(2)
};
customer.Orders.Add( order );
ctx.SubmitChanges();
}


Eine Bestellung löschen.

using(NorthwindDataContext ctx = new NorthwindDataContext())
{
Order order =
ctx.Orders.Single( o => o.OrderID == 11080 );
ctx.Orders.Remove( order );
ctx.SubmitChanges();
}

Tuesday, August 29, 2006

WCF Fehler - Service ... has zero application (non-infrastructure) endpoints

Im Buch "Microsoft Windows Communication Foundation Hands-on! Beta Edition By Craig McMurtry, Marc Mercuri, Nigel Watling" entsteht bei dem ersten Beispiel folgender Fehler ( getestet mit Beta 2 ).

Service 'DerivativesCalculator.DerivativesCalculatorServiceType' has zero application (non-infrastructure) endpoints. This might be because no configuration file was found for your application, or because no service element matching the service name could be found in the configuration file, or because no endpoints were defined in the service element.

Um diesen Fehler zu beheben muss man nur in der app.config, im Name des Service und im Contract den Assemblynamen entfernen.

vorher: contract="Namespace.Type, Assemblyname"
nachher: contract="Namespace.Type"

Friday, August 11, 2006

Visual Studio Remote Debugging

Hier findet man eine Erklärung, wie man die Voraussetzungen für Remote Debugging schafft.

Thursday, June 15, 2006

ASP.NET GridView mit Row Highlighting

Um bei einem GridView die Zeilen farblich hervorzuheben, wenn man mit der Maus darüber fährt ist nur ein kleiner Aufwand nötig.

Als erstes erstellen wir ein Control, welches von GridView ableitet. Nun implementieren wir eine Eigenschaft, die festlegt, ob RowHighlighting gewünscht ist und eine weitere Eigenschaft, die die Farbe des Highlighting angibt.
[ToolboxData("<{0}:HighlightedGridView runat=server
ID=HighlightedGridView1></{0}:HighlightedGridView>"
)]
public class HighlightedGridView : GridView
{
[Category("Behavior")]
[DefaultValue("false")]
public bool HighlightRowOnMouseOver
{
get { return ViewState["rHighlight"] == null ?
false : (bool)ViewState["rHighlight"]; }
set { ViewState["rHighlight"] = value; }
}

[Category("Appearance")]
[Description("---RowHighlightColor---")]
public Color RowHighlightColor
{
get { return ViewState["hlColor"] == null ?
Color.White : (Color)ViewState["hlColor"]; }
set { ViewState["hlColor"] = value; }
}
}
Als nächstes überschreiben wir OnRowCreated und setzen die RowHighlightColor.
protected override void OnRowCreated
(GridViewRowEventArgs e)
{
base.OnRowCreated(e);

if (this.HighlightRowOnMouseOver &&
e.Row.RowType == DataControlRowType.DataRow)
SetRowHighlightColor(e.Row);
}
Nun müssen wir nur noch die Methode erstellen, die sich um das Highlighting kümmert. Ich weiße hier mit BackColor immer die Hintergrundfarbe zu. Dies kann aber zu unerwünschten Effekten führen, wenn eine alternierende RowColor eingestellt wurde. Aber das überlasse ich dem aufmerksamen Leser.

private void SetRowHighlightColor(GridViewRow row)
{
row.Attributes.Add("onmouseover",
"this.style.backgroundColor='" +
Utils.ColorToHexString(RowHighlightColor) + "'");
row.Attributes.Add("onmouseout",
"this.style.backgroundColor='" +
Utils.ColorToHexString(BackColor) + "'");
}

Thursday, June 08, 2006

ListView mit DataBinding

Mit der neuen BindingSource Komponente ist es relativ einfach, ein ListView mit DataBinding-Unterstützung zu erstellen. Als erstes erstellen wir ein Control, welches von ListView erbt.
public partial class ListViewEx : ListView
{
BindingSource bindingSource;
public ListViewEx()
{
bindingSource = new BindingSource();
this.View = View.Details;
this.FullRowSelect = true;
this.GridLines = true;
bindingSource.ListChanged += OnListChanged;
}
}

Als nächstes werden die Eigenschaften DataSource und DataMember implementiert. Das Attribut [AttributeProvider(typeof(IListSource))] legt fest, dass im PropertyGrid
ein DataSource Window angezeigt wird.

[AttributeProvider(typeof(IListSource))]
public object DataSource
{
get { return bindingSource.DataSource; }
set { bindingSource.DataSource = value; }
}

[Editor("System.Windows.Forms.Design.DataMemberListEditor,
System.Design, Version=2.0.0.0, Culture=neutral,
PublicKeyToken=b03f5f7f11d50a3a"
, typeof(UITypeEditor))]
public string DataMember
{
get { return bindingSource.DataMember; }
set { bindingSource.DataMember = value; }
}

Als nächstes implementieren wir das ListChanged Event. Darin können wir das ListView neu füllen, sobald sich die interne Liste der BindingSource Komponente ändert.

void OnListChanged(object sender, ListChangedEventArgs e)
{
this.SetColumnHeaders();
this.SetValues();
}

Als nächstes erstellen wir die Spalten anhand der Typinformationen. Wir holen uns das 1. Item aus der Liste und lesen dessen Eigenschaften aus. Falls eine Eigenschaft ein IList implementiert wird es eine Parent-Child Beziehung sein, deshlab zeigen wir diese nicht mit. Wenn es ein String ist erstellen wir die Spalte selbst, da sonst die Eigenschaft Length als Spaltenüberschrift angezeig wird. Ansonsten weisen wir einfach den DisplayName der jeweiligen Eigenschaft zu. In eigenen Klassen, kann der DisplayName gesetzt werden, indem man der jeweiligen Eigenschaft das Attribut DisplayName zuweißt.

private void SetColumnHeaders()
{
if (bindingSource.List.Count > 0)
{
this.Columns.Clear();
object dataItem = bindingSource.List[0];
foreach (PropertyDescriptor prop in
TypeDescriptor.GetProperties(dataItem))
{
if(prop.PropertyType.GetInterface("IList")
== null)
{
if (prop.ComponentType == typeof(string))
this.Columns.Add("Value");
else
this.Columns.Add(prop.DisplayName);
}
}
}
}

Als letztes füllen wir das ListView mit den Werten. Dafür iterieren wir über die interne Liste der BindingSource-Komponente. Jetzt prüfen wir, ob es sich um einen String oder einen ValueType. Mit TypeDescriptor.GetProperties(dataItem).Count == 0 stelle ich sicher, dass eine Struktur mit ihren Eigenschaften im else Zweig behnadelt wird.
private void SetValues()
{
this.Items.Clear();
foreach (object dataItem in bindingSource.List)
{
if (dataItem is string)
this.Items.Add((string)dataItem);
else if
(TypeDescriptor.GetProperties(dataItem).Count==0

&& dataItem is System.ValueType)
{
if (this.Columns.Count == 0)
this.Columns.Add("Value");
this.Items.Add(dataItem.ToString());
}
else
{
PropertyDescriptorCollection props =

TypeDescriptor.GetProperties(dataItem);
List<string> valueList = new List<string>();
foreach (PropertyDescriptor propDesc in props)
{
string value =
propDesc.GetValue(dataItem) == null ?
string.Empty :
propDesc.GetValue(dataItem).ToString();
valueList.Add(value);
}
this.Items.Add
(new ListViewItem(valueList.ToArray()));
}
}
}

Generische Singleton-Implementierung

public static class Singleton<T> where T : new()
{
private static T instance = new T();
public static T Instance
{
get { return instance; }
}
}