Web- und Software Development

MVC / Razor Style-Switcher – Quicky

Written By: Mario Priebe - Jan• 26•12

Heute möchte ich zeigen, wie man sich einen einfachen Style-Switcher mittels jQuery in einem MVC / Razor Projekt einbauen kann.

image

Den Basis-Style setzen wir zu Beginn, wenn die Seite zum ersten Mal geöffnet wird. Wichtig ist, das wir eine Id setzen, um in unserer jQuery Funktion dieses Element wieder zu finden.

<link id="jQ" href="@Url.Content("http://ajax.googleapis.com/ajax/libs/jqueryui/1.8/themes/base/jquery-ui.css")" rel="Stylesheet" type="text/css" />

Um zwischen den Styles zu wechseln, erstellen wir eine Html-ComboBox mit den Namen der einzelnen Styles:

<select id="styles"> <option value="base">base</option> <option value="black-tie">black-tie</option> <option value="blitzer">blitzer</option> <option value="cupertino">cupertino</option> <option value="dark-hive">dark-hive</option> <option value="dot-luv">dot-luv</option> <option value="eggplant">eggplant</option> <option value="excite-bike">excite-bike</option> <option value="flick">flick</option> <option value="hot-sneaks">hot-sneaks</option> <option value="humanity">humanity</option> <option value="le-frog">le-frog</option> <option value="mint-choc">mint-chocolate</option> <option value="overcast">overcast</option> <option value="pepper-grinder">pepper-grinder</option> <option value="redmond">redmond</option> <option value="smoothness">smoothness</option> <option value="south-street">south-street</option> <option value="start">start</option> <option value="sunny">sunny</option> <option value="swanky-purse">swanky-purse</option> <option value="trontastic">trontastic</option> <option value="ui-darkness">ui-darkness</option> <option value="ui-lightness">ui-lightness</option> <option value="vader">vader</option> </select>

Als Script verwenden wir folgenden Codeabschnitt. Die Funktion setzt den gewählten Style und ruft eine Methode im Controller auf, der ggfls. den Style in den Usereinstellungen speichern kann.

<script> $(document).ready(function () $('#styles').change(function () { var style = $(this).val(); $("#jQ").attr("href", "http://ajax.googleapis.com/ajax/libs/jqueryui/1.8/themes/" + style + "/jquery-ui.css"); $.post('@Url.Action("SaveStyle", "Home")', { style: style }, function () { return false; }); }); }); </script>

Im Controller dann kann der Name des gewählten Styles weiter verarbeitet werden:

public void SaveStyle(string style) { //save style }

Viel Spaß beim entwickeln : )

Google API jQuery UI 1.7.2 Theme Übersicht + Razor-Layout

Written By: Mario Priebe - Jan• 24•12

Im folgenden eine kleine Übersicht von Google API jQuery UI 1.7.2 Designs, so vorbereitet, dass diese schnell im Header eines Razor Layouts eingefügt werden können.

base

<link href="@Url.Content("http://ajax.googleapis.com/ajax/libs/jqueryui/1.7.2/themes/base/jquery-ui.css")" rel="Stylesheet" type="text/css" />

image


black-tie

<link href="@Url.Content("http://ajax.googleapis.com/ajax/libs/jqueryui/1.7.2/themes/black-tie/jquery-ui.css")" rel="Stylesheet" type="text/css" />

image


blitzer

<link href="@Url.Content("http://ajax.googleapis.com/ajax/libs/jqueryui/1.7.2/themes/blitzer/jquery-ui.css")" rel="Stylesheet" type="text/css" />

image


cupertino

<link href="@Url.Content("http://ajax.googleapis.com/ajax/libs/jqueryui/1.7.2/themes/cupertino/jquery-ui.css")" rel="Stylesheet" type="text/css" />

image


dark-hive

<link href="@Url.Content("http://ajax.googleapis.com/ajax/libs/jqueryui/1.7.2/themes/dark-hive/jquery-ui.css")" rel="Stylesheet" type="text/css" />

image


dot-luv

<link href="@Url.Content("http://ajax.googleapis.com/ajax/libs/jqueryui/1.7.2/themes/dot-luv/jquery-ui.css")" rel="Stylesheet" type="text/css" />

image


eggplant

<link href="@Url.Content("http://ajax.googleapis.com/ajax/libs/jqueryui/1.7.2/themes/eggplant/jquery-ui.css")" rel="Stylesheet" type="text/css" />

image


excite-bike

<link href="@Url.Content("http://ajax.googleapis.com/ajax/libs/jqueryui/1.7.2/themes/excite-bike/jquery-ui.css")" rel="Stylesheet" type="text/css" />

image


flick

<link href="@Url.Content("http://ajax.googleapis.com/ajax/libs/jqueryui/1.7.2/themes/flick/jquery-ui.css")" rel="Stylesheet" type="text/css" />

image


hot-sneaks

<link href="@Url.Content("http://ajax.googleapis.com/ajax/libs/jqueryui/1.7.2/themes/hot-sneaks/jquery-ui.css")" rel="Stylesheet" type="text/css" />

image


humanity

<link href="@Url.Content("http://ajax.googleapis.com/ajax/libs/jqueryui/1.7.2/themes/humanity/jquery-ui.css")" rel="Stylesheet" type="text/css" />

image


le-frog

<link href="@Url.Content("http://ajax.googleapis.com/ajax/libs/jqueryui/1.7.2/themes/le-frog/jquery-ui.css")" rel="Stylesheet" type="text/css" />

image


mint-chocolate

<link href="@Url.Content("http://ajax.googleapis.com/ajax/libs/jqueryui/1.7.2/themes/mint-choc/jquery-ui.css")" rel="Stylesheet" type="text/css" />

image


overcast

<link href="@Url.Content("http://ajax.googleapis.com/ajax/libs/jqueryui/1.7.2/themes/overcast/jquery-ui.css")" rel="Stylesheet" type="text/css" />

image


pepper-grinder

<link href="@Url.Content("http://ajax.googleapis.com/ajax/libs/jqueryui/1.7.2/themes/pepper-grinder/jquery-ui.css")" rel="Stylesheet" type="text/css" />

image


redmond

<link href="@Url.Content("http://ajax.googleapis.com/ajax/libs/jqueryui/1.7.2/themes/redmond/jquery-ui.css")" rel="Stylesheet" type="text/css" />

image


smoothness

<link href="@Url.Content("http://ajax.googleapis.com/ajax/libs/jqueryui/1.7.2/themes/smoothness/jquery-ui.css")" rel="Stylesheet" type="text/css" />

image


south-street

<link href="@Url.Content("http://ajax.googleapis.com/ajax/libs/jqueryui/1.7.2/themes/south-street/jquery-ui.css")" rel="Stylesheet" type="text/css" />

image


start

<link href="@Url.Content("http://ajax.googleapis.com/ajax/libs/jqueryui/1.7.2/themes/start/jquery-ui.css")" rel="Stylesheet" type="text/css" />

image


sunny

<link href="@Url.Content("http://ajax.googleapis.com/ajax/libs/jqueryui/1.7.2/themes/sunny/jquery-ui.css")" rel="Stylesheet" type="text/css" />

image


swanky-purse

<link href="@Url.Content("http://ajax.googleapis.com/ajax/libs/jqueryui/1.7.2/themes/swanky-purse/jquery-ui.css")" rel="Stylesheet" type="text/css" />

image


trontastic

<link href="@Url.Content("http://ajax.googleapis.com/ajax/libs/jqueryui/1.7.2/themes/trontastic/jquery-ui.css")" rel="Stylesheet" type="text/css" />

image


ui-darkness

<link href="@Url.Content("http://ajax.googleapis.com/ajax/libs/jqueryui/1.7.2/themes/ui-darkness/jquery-ui.css")" rel="Stylesheet" type="text/css" />

image


ui-lightness

<link href="@Url.Content("http://ajax.googleapis.com/ajax/libs/jqueryui/1.7.2/themes/ui-lightness/jquery-ui.css")" rel="Stylesheet" type="text/css" />

image


vader

<link href="@Url.Content("http://ajax.googleapis.com/ajax/libs/jqueryui/1.7.2/themes/vader/jquery-ui.css")" rel="Stylesheet" type="text/css" />

image

Asynchrones Befüllen einer ObservableCollection<T> in einem ViewModel

Written By: Mario Priebe - Jan• 14•12

Die Aufgabenstellung beschreibt, das innerhalb eine ViewModels Daten aus einer Datenbank ausgelesen und über der Netzwerkverbindung noch weiter verarbeitet werden müssen. Hier liegt es auf der Hand, dass eine asynchrone Lösung her muss, sprich es muss unter allen Umständen verhindert werden, dass die UI blockiert.

Wie man das machen kann, zeige ich wie folgt:

Ich erstelle mir vorerst einen einfachen Delegate.

1 private delegate void AsyncAwsDelegate();

Im Konstruktor der ViewModels, bzw in einem Command wird dann an diesem Delegate ein BeginInvoke aufgerufen, der die Methode zur asynchronen Verarbeitung zugewiesen bekommt.

1 public MainViewModel() 2 { 3 AsyncAwsDelegate del = (FetchItemsAsync); 4 del.BeginInvoke(null, null); 5 }

In dieser Methode findet dann der Prozess statt, wo die Items verarbeitet und einer ObservableCollection<T> hinzugefügt werden.

1 private void FetchItemsAsync() 2 { 3 var items = _dataLayer.Items.ToList(); 4 items.ForEach(i => Items.Add(_aws.ItemLookup(i.ItemId))); 5 }

Das geht leider nicht ohne Dispatcher, sprich wenn ich die “normale” ObservableCollection verwenden würde, müsste ich zuerst in den UI Thread gelangen, ansonsten knallt es.

Dazu konnte ich eine nette spezialisierte Klasse finden, die mir diese Arbeit abnimmt.

1 public class DispatchingObservableCollection<T> : ObservableCollection<T> 2 { 3 private readonly Dispatcher _currentDispatcher; 4 5 /// <summary> 6 /// The default constructor of the ObservableCollection 7 /// </summary> 8 public DispatchingObservableCollection() 9 { 10 //Assign the current Dispatcher (owner of the collection) 11 _currentDispatcher = Dispatcher.CurrentDispatcher; 12 } 13 14 /// <summary> 15 /// Executes this action in the right thread 16 /// </summary> 17 ///<param name="action">The action which should be executed</param> 18 private void DoDispatchedAction(Action action) 19 { 20 if (_currentDispatcher.CheckAccess()) 21 action(); 22 else 23 _currentDispatcher.Invoke(DispatcherPriority.DataBind, action); 24 } 25 26 /// <summary> 27 /// Clears all items 28 /// </summary> 29 protected override void ClearItems() 30 { 31 DoDispatchedAction(() => base.ClearItems()); 32 } 33 34 /// <summary> 35 /// Inserts a item at the specified index 36 /// </summary> 37 ///<param name="index">The index where the item should be inserted</param> 38 ///<param name="item">The item which should be inserted</param> 39 protected override void InsertItem(int index, T item) 40 { 41 DoDispatchedAction(() => base.InsertItem(index, item)); 42 } 43 }

Da die ObservableCollection das INotifyPropertyChanged Interface implementiert, brauch ich auch nicht mehr dafür Sorge tragen, dass sich bei jedem Zufügen eines Items die UI aktualisieren muss.

Viel Spaß beim entwickeln : )

Automatisiertes Ein- und Auschecken im Buildprozess

Written By: Mario Priebe - Jan• 12•12

Möchte man nach einem Build, die Assembly in ein dafür bereitgestelltes Verzeichnis kopieren, kann man das recht einfach im Prä- und Postbuild-Ereignis im Visual Studio definieren. Hat man die DLL jedoch im TFS eingecheckt, muss man vor dem Kopieren dafür Sorge tragen, dass die Datei ausgecheckt wurde, ansonsten kann die eben wegen dem Schreibschutz nicht überschrieben werden.

Unter “C:\Program Files (x86)\Microsoft Visual Studio 10.0\Common7\IDE” findet man die tf.exe, die es einem erlaubt, den TFS über den Kommandozeileninterpreter zu verwenden. Wie man die einzelnen Parameter verwendet, findet man ganz leicht über die Hilfe (tf help [command]) heraus : )

Um hier aber nicht händisch vorgehen zu müssen, kann man die über folgende Einträge in den Buildereignissen diese Aufgabe automatisieren. Diese findet man in den Eigenschaften vom Projekt.

2012-01-12 13h26_44

Im Prä- und im Postbuildereignis, kann man Befehle verknüpft mit Makros, Pfade und Dateinamen angeben.

Unter dem Button Makros, findet man einige vordefinierte Makros, die man verwenden kann.

2012-01-12 13h35_441

Jedoch gibt es da noch einige mehr. Eine Liste verfügbarer Makros findet man in der MSDN.

Im Präbuildereignis checken wir die entsprechende Datei aus:

"$(DevEnvDir)tf" checkout "$(SolutionDir)../Bin/$(TargetFileName)"

und nach dem Erstellen, also im Postbuild kopieren wir die Datei und checken diese wieder ein. Hier kann man auch einen notwendigen Kommentar hinterlassen.

copy "$(TargetPath)" "$(SolutionDir)../Bin/$(TargetFileName)" "$(DevEnvDir)tf" checkin /noprompt /comment:"automatic build checkin" "$(SolutionDir)../Bin/$(TargetFileName)"

Das Ganze sieht dann wie folgt aus:

2012-01-12 13h32_29

 

Nach einem erfolgreichen Build, wird die Assembly nun ausgecheckt, durch den neuen Build ersetzt und wieder in den TFS eingecheckt.

 

Viel Spaß beim entwickeln : )