Blog Home  Home Feed your aggregator (RSS 2.0)  
artiso Blog - Wednesday, November 21, 2007
Neues rund um's Thema .Net
 
 Wednesday, November 21, 2007

Das Problem:

Ich habe in C# ein Objekt vom Typ System.Drawing.Color. Dieses möchte ich in einen String-Konvertieren, den ich im HTML verwenden kann. Das funktioniert gut bei benannten Farben wie z.B. "red". Dort kann man Color.Name verwenden. Aber bei nicht benannten Farben liefert dies einen ARGB-Wert mit dem HTML nichts anfangen kann. Dehalb habe ich diese kleine Mthode geschrieben:

private string GetColorString(Color color)
{
    if (color.ToKnownColor() != 0)
        return color.Name;
    else
        return "#" + color.Name.Substring(2);
}

 

Wenn jemand eine einfachere Lösung weiss, einfach her damit!

Update:

Jürgen hat noch eine viel einfacher Lösung (siehe Kommentar) mit
string htmlcolor = ColorTranslator.ToHtml(Color.Bisque)
Kannte ich bisher noch nicht, aber man lernt ja nie aus!

Wednesday, November 21, 2007 12:31:43 PM (Mitteleuropäische Zeit, UTC+01:00)  #    Comments [1]    | 

Ein weniger bekannter Operator in C# ist der Operator ??. Damit kann ein Objekt auf null geprüft werden und wenn dies der Fall ist ein Alternativwert verwendet werden. Ein Beispiel kann das verdeutlichen:

   1: object a = null;
   2: object b = 5;
   3:  
   4: object c = a ?? b;

In dem Beispiel gilt c = b. Würde in der Zeile 3 a noch entsprechend inizialisiert, dass dieses nut mehr null ist, dann würde gelten c = a.

Wednesday, November 21, 2007 9:53:25 AM (Mitteleuropäische Zeit, UTC+01:00)  #    Comments [0]    | 
 Monday, November 19, 2007

Visual Studio 2008 liegt nun als RTM-Version zum Downloadf bereit. Wer keine MSDN-Subscription hat, kann sich hier die Trail-Versionen herunterladen.

Visual Studio 2008 Trial Downloads

Monday, November 19, 2007 6:57:22 PM (Mitteleuropäische Zeit, UTC+01:00)  #    Comments [0]    | 
 Friday, November 16, 2007

Ich habe bei mir eine Liste die wiederum eine Liste mit Unterobjekten enthält. Ich möchte nun daraus ein Element der Unterliste mit einer bestimmten ID selektieren. Eine klare Sache für LINQ!

Als Leitfaden habe ich auf 101 LINQ Samples mir folgendes Beispiel rausgesucht:

   1: public void Linq15() {
   2:     List customers = GetCustomerList();
   3:  
   4:     var orders =
   5:         from c in customers,
   6:                 o in c.Orders
   7:         where o.Total < 500.00M
   8:         select new {c.CustomerID, o.OrderID, o.Total};
   9:  
  10:     ObjectDumper.Write(orders);
  11: }

 

Das sieht ganz eifach aus, hat bei mir aber absolut nicht funktioniert. Ich konnte das schon nicht sauber eingeben, da er in Zeile 6 für c keine Intellisense-Unterstützung geboten hat. Das Ganze konnte ich dann lösen, indem ich das etwas umgestellt habe, auf das Beispiel oben übertragen sieht meine Lösung so aus:

   1: public void Linq15() {
   2:     List customers = GetCustomerList();
   3:  
   4:     var orders =
   5:         from c in customers
   6:                from o in c.Orders
   7:         where o.Total < 500.00M
   8:         select new {c.CustomerID, o.OrderID, o.Total};
   9:  
  10:     ObjectDumper.Write(orders);
  11: }

 

Ich habe einfach in Zeile 6 statt des Kommas in der vorherigen Zeile nochmals ein from eingebaut. So funktioniert es bei mir nun, wie ich mir das gewünscht habe.

Friday, November 16, 2007 5:57:01 PM (Mitteleuropäische Zeit, UTC+01:00)  #    Comments [0]    |   | 
 Wednesday, November 14, 2007

Na wenigstens nimmt Visual Studio einen Absturz nicht auf die leichte Schulter sondern gibt zu, dass das eine Katastrophe ist.

image

Wednesday, November 14, 2007 4:53:43 PM (Mitteleuropäische Zeit, UTC+01:00)  #    Comments [0]    | 
 Tuesday, November 13, 2007

Damit Ich habe ein Web User Control bei dem ich eine TextBox als Property nach außen geben möchte, damit man die Eigenschaften der Textbox editieren kann. Das kann man durch ein paar Attribute erreichen.

[Browsable(true),
NotifyParentProperty(true),
PersistenceMode(PersistenceMode.InnerProperty),
DesignerSerializationVisibility(DesignerSerializationVisibility.Content), 
RefreshProperties(RefreshProperties.Repaint)]
public TextBox DropDownTextbox
{
    get
    {
        return this.TextBox1;
    }
    set
    {
        this.TextBox1 = value;                
    }
}
 
Damit werden auf dem UserControls zusätzliche Properties angelegt und zwar alle Properties einer Textbox mit dem Prefix "DropDownTexbox" also dem Namen des Properties auf dem Control.
 
image
 
Im Markup werden die Properties ganz normal als Attribute eingefügt. Was mich allerdings etwas gewundert hat war, dass ich im Markup über Intellisense die Textbox allerdings auch als separates Tag angeben kann und darauf meine Attribute definiere. Allerding wird das denn im Designer nicht mehr sauber gerendert.

 

<uc1:WebUserControl1 ID="WebUserControl11" runat="server" DropDownTextBox-BackColor="#FFCC00">
    <DropDownTextbox BackColor="red"></DropDownTextbox>
</uc1:WebUserControl1>

Tuesday, November 13, 2007 5:53:32 PM (Mitteleuropäische Zeit, UTC+01:00)  #    Comments [0]    |   | 
 Monday, November 12, 2007

Der Team Foundation Server ist ein sehr flexibles Werkzeug. Es lässt sich an verschiedene Prozessmodelle anpassen. Die die beiden folgenden Links verweisen zu entsprechenden Kapiteln in der MSDN-Hilfe die beschreiben wie Workitem Typen und Prozessvorlagen angepasst werden können.

Customizing Work Item Types
Customizing Process Templates

Monday, November 12, 2007 9:13:20 PM (Mitteleuropäische Zeit, UTC+01:00)  #    Comments [0]    | 

Der Team Foundation Server Guide liegt nun in der finalen Version vor. Dieses Dokument beschreibt viele gängige Szenarien in Zusammenhang mit dem TFS und bietet empfohlene Lösungen an. 

patterns & practices: Team Development with Visual Studio Team Foundation Server - View Release

Monday, November 12, 2007 9:10:04 PM (Mitteleuropäische Zeit, UTC+01:00)  #    Comments [0]    | 

LINQ erweitert ICollections, IEnumerable etc. mit einigen Extension Methods wie z.B. ToList() was sehr hilfreich ist. Ich hatte gerade das Problem, dass diese Extensions nicht im Intellisense angezeigt wurden. Nach einigem Suchen habe ich festgestellt, das lag daren, dass ich kein using System.Linq drin hatte, sondern nur auf System.Data.Linq und System.Data.Linq.Mapping. Nachdem ich das using ergänzt habe, funktionierte das problemlos.

Monday, November 12, 2007 6:31:35 PM (Mitteleuropäische Zeit, UTC+01:00)  #    Comments [0]    |   | 

Das alte Jahr ist noch nicht zu Ende undf schon verspricht das neue Jahr ereignisreich zu werden. Im Februar bin ich wieder auf Tour:

13. / 14. Feb. 2008 - VSOne in München
Hier halte ich zwei Vorträge zu XML-Serialisierung und Architektur

19. / 20. Feb. 2008 - Launch Event Microsoft in Frankfurt
Hier bin ich als ATE (Ask the Expert) zum Thema Visual Studio Team System

26. / 27. Feb. 2008 - BASTA! Sprint Edition in Frankfurt
Auf der BASTA! werde ich zwei Vorträge zum Thema TFS halten.

Weitere Details folgen noch. Ich würde mich freuen, den einen oder anderen Leser meines Blogs auf einem dieser Events persönlich kennen zu lernen.

Monday, November 12, 2007 10:04:29 AM (Mitteleuropäische Zeit, UTC+01:00)  #    Comments [2]    | 
 Wednesday, November 07, 2007

Ich hatte gerade ein Aha-Erlebnis der etwas anderen Art. Im Infragistics-Chart gibt es eine Zoom-Funktion für die Achsen. Bei einem Composite-Chart scheint das aber nicht zu funktionieren. Ich habe folgendes im Code stehen:

ChartObj.CompositeChart.ChartAreas[0].Axes[0].

Aber mein Intellisense zeigt kein passendes Property an. Im Forum steht auch die Aussage von einem Infragistics-Mitarbeiter, dass das nicht geht. Wenn ich dann "blind" das vervollständige zu

ChartObj.CompositeChart.ChartAreas[0].Axes[0].ScrollScale.Visible = true;


funktioniert der Code wunderbar! Mal abgesehen davon, dass ich gar nicht wüsste, wie man Properties im Intellisense versteckt aber dennoch verfügbar macht, warum um alles in der Welt haben die Jungs dieses Property nicht öffentlich zugänglich gemacht?

Wednesday, November 07, 2007 7:51:22 PM (Mitteleuropäische Zeit, UTC+01:00)  #    Comments [1]    | 
 Monday, November 05, 2007

Das Problem kennt vermutlich fast jeder Notebook-Besitzer der an seinem Arbeitsplatz noch einen zusätzlichen PC hat. Wenn man am Arbeitsplatz sitrzt steht das Notebook entweder nutzlos in der Ecke oder man kommt mit den Mäusen und Tastaturen immer durcheinander. Wäre es nicht schön, das Notebook am Arbeitsplatz zu integrieren. Unter XP hatte ich hier eine geniale Lösung - Maxivista. Damit konnte man sogar eine Zweischirmlösung aufbauen indem das Notebook einfach den Desktop des Arbeitsplatzrechners erweiterte. Absolut klasse, nur funktioniert der Host unter Vista nicht (zumindest nur mit den WDDM-Treibern, was für mich allerdings keine Alternative ist).

Nun habe ich Synergy entdeckt. Dieses Opensource-Tool bitet die Möglichkeit, einen Rechner mit der Maus / Taststur eines zweiten Rechners fernzusteuern. Es unterschiedet sich zu Remote Desktop o. ä., indem es nicht den Bildschirm des PCs auf den Zweit-PC überträgt. Es lässt sich in meinem Szenario damit wunderbar nutzen. Ich habe auf meinem Desktop-PC Visual Studio laufen und kann dann einfach mit der Maus links zum Bildschirmrand rausfahren und schon bin ich auf meinem Notebook und kann damit mit der gleichen Tastatur / Maus z.B. Suchen im Internet, Downloads, E-Mail oder andere Funktionen aufrufen ohne dass mein Desktop-PC damit belastet wird. Das Ganze läuft auch problemlos unter Vista und ist zumindest mal ein brauchbarer Ersatz für MaxiVista.

Monday, November 05, 2007 8:22:54 AM (Mitteleuropäische Zeit, UTC+01:00)  #    Comments [0]    | 
 Thursday, November 01, 2007

Ich habe mir gerade ein kleines Beispiel für den Zugriff auf einen Webservice per JavaScript per AJAX zusammengebaut. Da ich hier einige Informationen aus verschiedenen Quellen zusammengetragen habe, möchte ich das Beispiel hier kurz posten, vielleicht hilft es dem einen oder anderen, einige Informationen gesammelt zu finden.

Hier zunächst der Code für den Webservice:

   1: namespace ValuePlanner_2008.Services
   2: {
   3:     /// <summary>
   4:     /// Summary description for INNProjectExplorerWebService
   5:     /// </summary>
   6:     [WebService(Namespace = "http://tempuri.org/")]
   7:     [WebServiceBinding(ConformsTo = WsiProfiles.BasicProfile1_1)]
   8:     [GenerateScriptType(typeof(myData))]
   9:     [ToolboxItem(false)]
  10:     [ScriptService]
  11:     public class INNProjectExplorerWebService : System.Web.Services.WebService
  12:     {
  13:         [WebMethod]
  14:         [ScriptMethod]
  15:         public myData HelloWorld(int ID)
  16:         {
  17:             return new myData { ID = ID, Text = "Hello World" + ID.ToString() };
  18:         }
  19:     }
  20:     
  21:     public class myData
  22:     {
  23:         public int ID { get; set; }
  24:         public string Text { get; set; }
  25:     }
  26: }


Kurz zu erwähnen sind hier folgende Details: In Zeile 10 wird über ein entsprechndes Attribut der Webservice für die Zusammenarbeit mit AJAX konfiguriert. Das selbe gilt in Zeile 14 für die Methode, die der Webservicebereitstellt. Da die Methode einen eigenen Datentyp (myData) zurückgibt, wird in Zeile 8 dieser Typ ebenfalls für AJAX veröffentlicht. Man kan so beliebig komplexe Datenstrukturen zwichen JavaScript und dem WebService austauschen, solange diese auf Datentypen basieren, dieJavaScript auch verarbeiten kann (also z.B. keine generischen Listen etc.). Der restliche Code wird automatisch über das Webservice Template erzeugt bzw. sollte keiner weiteren Erklärung bedürfen.

In der ASPX-Seite muss ein Scriptmanager eingebaut werden und der Service darauf registriert werden. Da ich de Scriptmanager in meinem Beispiel in der Master-Page habe, verwende ich einen ScriptmanagerProxy, der es erlaubt, die Registrierungen für einzelne Seiten vorzunehmen und an den Scriptmanager in der Master-Page weiterleitet. Dies ist deshalb notwendig, da auf einer Seite nur ein einziger Scriptmanager vorkommen darf.

   1: <asp:ScriptManagerProxy ID="ScriptManagerProxy1" runat="server">
   2:     <Services>
   3:         <asp:ServiceReference Path="~/Services/INNProjectExplorerWebService.asmx" />
   4:     </Services>
   5: </asp:ScriptManagerProxy>


Noch ein wichtiger Hinweis: Ich hatte zuerst den ToolScriptManager aus dem AJAX Component Toolkit in meiner Masterpage. Dieser scheint nicht mit dem ScriptManagerProxy zusammenzuarbeiten, jedenfalls wurde bei mir die Proxy-Klasse nicht erstellt. Erst als ich einen "normalen" ScriptManager verwendet habe, funktionierte das problemlos.

Auf dem Client wird nun eine Proxy-Klasse erstellt, die die Datentypen und die Methoden des Webservices in JavaScript nachgebildet werden. Darüber lässt sich der WebService sehr einfach aufrufen.

   1: <script language="javascript" type="text/javascript">
   2:     
   3:    function fnCallWebService()
   4:     {
   5:         ValuePlanner_2008.Services.INNProjectExplorerWebService.HelloWorld(5, fnHelloWorlSuccess, fnHelloWorlFailed);
   6:     }
   7:     
   8:     function fnHelloWorlSuccess(results, context, methodName)
   9:     {
  10:         alert(results.Text);
  11:     }
  12:     
  13:     function fnHelloWorlFailed(results, context, methodName)
  14:     {
  15:         alert ("Error calling webservice");
  16:     }
  17: </script> 


in Zeile 5 wird der WebService mit der dem Namespace und dem Namen der Webservice Klasse aufgerufen. Zunächst wird der Parameter der HelloWorld-Methode übergeben. Da der Aufruf asynchron erfolgt kann wird noch eine Methode angegeben angegeb, die im Erfolgsfall aufgerufen wird, optional noch eine Methode, wenn der Aufruf fehlschlägt. In Zeile 10 sieht man schön, dass man in JavaScript nun auch das Datenobjekt des Rückgabewertes in gewohnter Weise zugreifen kann.

Thursday, November 01, 2007 9:10:45 PM (Mitteleuropäische Zeit, UTC+01:00)  #    Comments [0]    | 
 Monday, October 29, 2007

Eines der neuen coolen Features in VS2008 ist der Intellisense-Support und das einfärben für Javascript-Code. Das hat bei mir aber nicht funktioniert. Das Problem liegt daran, dass bei der Installation zwei Registry-keys nicht korrekt gesetzt werden.

Setzt man folgende Registry-Keys korrekt dann funktioniert das Intellisense einwandfrei:

[HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\VisualStudio\9.0\CLSID\{014E9A41-54E5-44ED-B15E-EFFA8758BFFC}]

"CodeBase"=file:///C:\\Program Files\\Microsoft Visual Studio 9.0\\Common7\\IDE\\Microsoft.JScript.AuthoringServices.dll

 

[HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\VisualStudio\9.0\CLSID\{014E9A41-54E5-44ED-B15E-EFFA8758BFFC}\InprocServer32\9.0.0.0]

"CodeBase"=file:///C:\\Program Files\\Microsoft Visual Studio 9.0\\Common7\\IDE\\Microsoft.JScript.AuthoringServices.dll

 

Nähere Infos findet man hier.

Monday, October 29, 2007 5:17:18 PM (Mitteleuropäische Zeit, UTC+01:00)  #    Comments [0]    | 
 Thursday, October 25, 2007

Auf dieser Seite sind jede Menge Beispiele zum Thema LINQ thematisch geordnet aufgelistet. Hier findet man wirklich für viele Einsatzgebiete entsprechende Beispiele. Wirklich empfehlenswert! 

101 LINQ Samples

Thursday, October 25, 2007 8:30:39 PM (Mitteleuropäische Zeit, UTC+01:00)  #    Comments [1]    |   | 

Wenn man eine Datei löscht, die in der Quellcode-Verwaltung eingecheckt war, kann man diese leicht aus der Quellcode-Verwaltung wiederherstellen. Dazu muss man aber zuerst eine kleine Einstellung vornehmen. Unter Tools / Options / Source Control / Visual Studio Team Foundation Server kann man die Option "Show deleted items in the Source Control Explorer" aktivieren.

image

Dann werden im Source Control Explorer gelöschte Elemente angezeugt, die man einfach "undeleten" kann.

image

Thursday, October 25, 2007 5:09:17 PM (Mitteleuropäische Zeit, UTC+01:00)  #    Comments [1]    |   | 
 Wednesday, October 24, 2007

Wer mal etwas mehr mit WCF programmiert hat, wird feststellen, dass es recht müßig ist, für jeden Service einen Host zu implementieren. Deshalb habe ich zusammen mit meinem Kollegen Tobi einen WCF Service-Managerr entwickelt. Dieser Servicemanager wird auf dem Application-Server als Windows-Dienst ausgeführt und ist in der Lage Services die in DLLs bereitgestellt werden dynamisch zu laden und auszuführen. Zur Steuerung dient ein Client der natürlich per WCF mit dem Service-Manager kommuniziert. Damit kann auch eine größere Zahl von Services auf einem Application-Server effizient verwaltet werden.

image

Der Service-Manager kann inkl. einer kleinen Doku kostenlos heruntergeladen und verwendet werden. Über ein Feedback würde ich mich freuen.

artisoServiceManager.zip (5,94 MB) Version 0.9.0
Wednesday, October 24, 2007 10:11:09 AM (Mitteleuropäische Zeit, UTC+01:00)  #    Comments [0]    |   | 
 Thursday, October 18, 2007

Während einer Präsentation hat man oft das Problem, dass man einen Bereich vergrößern möchte um ihn für das Publikum besser lesbar zu machen. Das kann man mit dem kleinen kostenlosen Tool ZoomIt ganz einfach bewerkstelligen. Zusätzlich bietet das Tool auch die Möglichkeit, dass man direkt auf dem Desktop Striche zeichnet. Dadurch kann man z.B. bestimmte Bereiche während der Präsentation kennzeichnen.

Den Download gibt's hier

Thursday, October 18, 2007 11:55:51 PM (Mitteleuropäische Zeit, UTC+01:00)  #    Comments [0]    | 
 Wednesday, October 17, 2007

Preisfrage: Was passiert bei folgendem Code:

Dictionary<int, string> Names = new Dictionary<int, string> { { 1, "Thomas" }, { 2, "Chris" } };
Names[5] = "Luka";


Ich hätte erwartet, dass der eine KeyNotFoundException wirft. Tut er aber nicht. Statt dessen wird einfach ein neues Element dem Dictionary hinzugefügt mit dem Key 5 und dem Value "Luka". Ob man das verwenden sollte sei mal dahingestellt, aber zumindest gut zu wissen.

Wednesday, October 17, 2007 5:13:36 PM (Mitteleuropäische Zeit, UTC+01:00)  #    Comments [0]    | 

Möchte man den kleinesten Key aus einem Dictionary abfragen, dann kann man das jetzt mit Hilfe von LINQ ganz einfach tun. Das Dictionary-Objekt ist in C#3.0 mit einer ensprechenden Extension versehen wordurch das Ganze so einfach ist, wie man sich das immer gewünscht hat.

Dictionary<int, double> ListObject = new Di