<?xml version="1.0" encoding="UTF-8" ?>
<?xml-stylesheet type="text/xsl" href="http://www.aspnetzone.de/utility/FeedStylesheets/rss.xsl" media="screen"?><rss version="2.0" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:slash="http://purl.org/rss/1.0/modules/slash/" xmlns:wfw="http://wellformedweb.org/CommentAPI/"><channel><title>Search results matching tag 'Gastbeitrag'</title><link>http://www.aspnetzone.de/search/SearchResults.aspx?o=DateDescending&amp;tag=Gastbeitrag&amp;orTags=0</link><description>Search results matching tag 'Gastbeitrag'</description><dc:language>en-US</dc:language><generator>CommunityServer 2.1 SP2 (Build: 61120.2)</generator><item><title>Gastbeitrag: MVP oder MVVM? Was gehoert wohin?</title><link>http://www.aspnetzone.de/blogs/peterbucher/archive/2013/02/06/gastbeitrag-mvp-oder-mvvm-was-geh-rt-wohin.aspx</link><pubDate>Wed, 06 Feb 2013 19:14:00 GMT</pubDate><guid isPermaLink="false">ce930855-ae9b-4fa4-8077-06a76071cc6a:224895</guid><dc:creator>Peter Bucher</dc:creator><description>&lt;P&gt;&lt;FONT size=3&gt;&lt;STRONG&gt;Einleitung&lt;/STRONG&gt;&lt;/FONT&gt;&lt;/P&gt;
&lt;P&gt;Ein Kollege von mir hat sich intensiv mit den Designpatterns MVP und MVVM auseinandergesetzt und unter anderem auch mit mir diskutiert.&lt;BR&gt;Da ich seine Gedanken sehr interessant fand, kam uns schlussendlich die Idee, diese als Gastbeitrag in meinem Blog zu veröffentlichen.&lt;BR&gt;Der Hauptgedanke dieser Veröffentlichung ist Entwirrung und das Einholen von Feedback zu diesem Thema aus meiner Leserschaft.&lt;/P&gt;
&lt;P&gt;In diesem Sinne wünsche ich euch viel Spass mit dem Gastbeitrag und wir freuen uns auf reichliches Feedback.&lt;/P&gt;
&lt;P&gt;&lt;FONT size=3&gt;&lt;STRONG&gt;Gastbeitrag&lt;/STRONG&gt;&lt;/FONT&gt;&lt;/P&gt;
&lt;P&gt;Die Designpatterns MVP (Model - View - Presenter) und MVVM (Model - View - ViewModel) sind Designpatterns für die Strukturierung und Trennung von Daten, Ansicht und Presentationslogik. &lt;BR&gt;Ich habe mich im Zusammenhang mit der Entwicklung eines Applikationsframework für Businessanwendungen damit beschäftigt und schaute dazu im Internet verschiedene Implementierungen und Blogeinträge an. Mein Verständnis hatte sich dabei nicht vergrössert, sondern erstmal mehr Verwirrung geschaffen:&lt;/P&gt;
&lt;UL&gt;
&lt;LI&gt;Was ist der Unterschied zwischen einem Model und einem Entity? 
&lt;LI&gt;Was ist ein Presenter? 
&lt;LI&gt;Was ist Presentationslogik? 
&lt;LI&gt;Was ist der Unterschied zwischen Presenter und ViewModel?&lt;/LI&gt;&lt;/UL&gt;
&lt;P&gt;Ich versuche möglichst knapp meine Ansicht mitzuteilen und auch Beispiel-Code anzubieten. Im folgenden Beispiel verwende ich das MVP-Pattern:&lt;/P&gt;
&lt;P&gt;&lt;STRONG&gt;Entity / Model&lt;/STRONG&gt;: &lt;/P&gt;
&lt;P&gt;Ein Entity enthält Daten wie Name, Adresse und Ort usw. z.B. eines Customers:&lt;/P&gt;
&lt;P&gt;&amp;nbsp;&lt;/P&gt;
&lt;P&gt;&lt;code&gt;&lt;span style="color: Black;background-color: Transparent;font-family: Courier New;font-size: 14px;font-weight: normal;"&gt; &lt;br /&gt;&lt;span style="color: Blue;background-color: Transparent;font-family: Courier New;font-size: 14px;font-weight: normal;"&gt;public&lt;/span&gt; &lt;span style="color: Blue;background-color: Transparent;font-family: Courier New;font-size: 14px;font-weight: normal;"&gt;class&lt;/span&gt; CustomerEntity&lt;br /&gt;    {&lt;br /&gt;        &lt;span style="color: Blue;background-color: Transparent;font-family: Courier New;font-size: 14px;font-weight: normal;"&gt;public&lt;/span&gt; &lt;span style="color: Blue;background-color: Transparent;font-family: Courier New;font-size: 14px;font-weight: normal;"&gt;int&lt;/span&gt; CustomerId { get; set; }&lt;br /&gt;&lt;br /&gt;        &lt;span style="color: Blue;background-color: Transparent;font-family: Courier New;font-size: 14px;font-weight: normal;"&gt;public&lt;/span&gt; &lt;span style="color: Blue;background-color: Transparent;font-family: Courier New;font-size: 14px;font-weight: normal;"&gt;string&lt;/span&gt; Name { get; set; }&lt;br /&gt;&lt;br /&gt;        &lt;span style="color: Blue;background-color: Transparent;font-family: Courier New;font-size: 14px;font-weight: normal;"&gt;public&lt;/span&gt; &lt;span style="color: Blue;background-color: Transparent;font-family: Courier New;font-size: 14px;font-weight: normal;"&gt;string&lt;/span&gt; Address { get; set; }&lt;br /&gt;&lt;br /&gt;        &lt;span style="color: Blue;background-color: Transparent;font-family: Courier New;font-size: 14px;font-weight: normal;"&gt;public&lt;/span&gt; &lt;span style="color: Blue;background-color: Transparent;font-family: Courier New;font-size: 14px;font-weight: normal;"&gt;string&lt;/span&gt; Location { get; set; }&lt;br /&gt;    }&lt;/span&gt;&lt;/code&gt;&lt;/P&gt;
&lt;P&gt;&amp;nbsp;&lt;/P&gt;
&lt;P&gt;Ein Model enthält wiederum ein oder mehrere Entities (z.B. ein zu editierender Customer oder ein Suchergebnis).&lt;/P&gt;
&lt;P&gt;Das Model stellt die dazugehörenden Methoden, um Entities zu laden, zu suchen oder abzuspeichern zur Verfügung. &lt;BR&gt;Zusätzlich darf im Model der Status des Views gespeichert werden, z.B. IsCustomerSelected, um gebunden mit der Eigenschaft IsEnabled eines Button zu unterscheiden, ob ein Customer im ListView der Ansicht selektiert wurde und somit editiert werden kann oder nicht.&lt;BR&gt;Eigenschaften wie die eines Customers sollten meiner Meinung nach nicht im Model zur Verfügung gestellt werden, sondern getrennt in einem separaten Entity, obwohl dies in den meisten Artikel bezüglich MVP / MVVM genau anders dargestellt wird. &lt;BR&gt;Im MVVM-Pattern wird von Microsoft empfohlen, die Daten sogar im ViewModel (Presenter) einzufügen; diese Mischung zwischen einerseits Daten und Presentationslogik steht die Möglichkeit entgegen, ableitbare Model-BasisKlassen für Daten und Basisklassen für Presentationslogik zu entwickeln. &lt;/P&gt;
&lt;P&gt;In der Basisklasse für Modelle sollte INotifyPropertyChanged implementiert werden, damit die Ansicht, falls mit DataBinding gearbeitet, aktualisiert wird.&lt;/P&gt;
&lt;P&gt;&amp;nbsp;&lt;/P&gt;
&lt;P&gt;&lt;code&gt;&lt;span style="color: Black;background-color: Transparent;font-family: Courier New;font-size: 14px;font-weight: normal;"&gt; &lt;br /&gt;&lt;span style="color: Blue;background-color: Transparent;font-family: Courier New;font-size: 14px;font-weight: normal;"&gt;public&lt;/span&gt; &lt;span style="color: Blue;background-color: Transparent;font-family: Courier New;font-size: 14px;font-weight: normal;"&gt;class&lt;/span&gt; Model : INotifyPropertyChanged&lt;br /&gt;    {&lt;br /&gt;        &lt;span style="color: Blue;background-color: Transparent;font-family: Courier New;font-size: 14px;font-weight: normal;"&gt;public&lt;/span&gt; &lt;span style="color: Blue;background-color: Transparent;font-family: Courier New;font-size: 14px;font-weight: normal;"&gt;void&lt;/span&gt; OnPropertyChanged(&lt;span style="color: Blue;background-color: Transparent;font-family: Courier New;font-size: 14px;font-weight: normal;"&gt;string&lt;/span&gt; propertyName)&lt;br /&gt;        {&lt;br /&gt;            &lt;span style="color: Blue;background-color: Transparent;font-family: Courier New;font-size: 14px;font-weight: normal;"&gt;if&lt;/span&gt; (&lt;span style="color: Blue;background-color: Transparent;font-family: Courier New;font-size: 14px;font-weight: normal;"&gt;this&lt;/span&gt;.PropertyChanged !&lt;span style="color: Red;background-color: Transparent;font-family: Courier New;font-size: 14px;font-weight: normal;"&gt;=&lt;/span&gt; &lt;span style="color: Blue;background-color: Transparent;font-family: Courier New;font-size: 14px;font-weight: normal;"&gt;null&lt;/span&gt;)&lt;br /&gt;            {&lt;br /&gt;                &lt;span style="color: Blue;background-color: Transparent;font-family: Courier New;font-size: 14px;font-weight: normal;"&gt;this&lt;/span&gt;.PropertyChanged(&lt;span style="color: Blue;background-color: Transparent;font-family: Courier New;font-size: 14px;font-weight: normal;"&gt;this&lt;/span&gt;, &lt;span style="color: Blue;background-color: Transparent;font-family: Courier New;font-size: 14px;font-weight: normal;"&gt;new&lt;/span&gt; PropertyChangedEventArgs(propertyName));&lt;br /&gt;            }&lt;br /&gt;        }&lt;br /&gt;&lt;br /&gt;        &lt;span style="color: Blue;background-color: Transparent;font-family: Courier New;font-size: 14px;font-weight: normal;"&gt;public&lt;/span&gt; &lt;span style="color: Blue;background-color: Transparent;font-family: Courier New;font-size: 14px;font-weight: normal;"&gt;event&lt;/span&gt; PropertyChangedEventHandler PropertyChanged;&lt;br /&gt;    }&lt;br /&gt;&lt;br /&gt;&lt;span style="color: Blue;background-color: Transparent;font-family: Courier New;font-size: 14px;font-weight: normal;"&gt;public&lt;/span&gt; &lt;span style="color: Blue;background-color: Transparent;font-family: Courier New;font-size: 14px;font-weight: normal;"&gt;class&lt;/span&gt; EditCustomerModel : Model&lt;br /&gt;    {&lt;br /&gt;        &lt;span style="color: Blue;background-color: Transparent;font-family: Courier New;font-size: 14px;font-weight: normal;"&gt;private&lt;/span&gt; CustomerEntity _customer;&lt;br /&gt;&lt;br /&gt;        &lt;span style="color: Blue;background-color: Transparent;font-family: Courier New;font-size: 14px;font-weight: normal;"&gt;public&lt;/span&gt; &lt;span style="color: Blue;background-color: Transparent;font-family: Courier New;font-size: 14px;font-weight: normal;"&gt;void&lt;/span&gt; NewCustomer()&lt;br /&gt;        {&lt;br /&gt;            &lt;span style="color: Blue;background-color: Transparent;font-family: Courier New;font-size: 14px;font-weight: normal;"&gt;this&lt;/span&gt;.Customer &lt;span style="color: Red;background-color: Transparent;font-family: Courier New;font-size: 14px;font-weight: normal;"&gt;=&lt;/span&gt; &lt;span style="color: Blue;background-color: Transparent;font-family: Courier New;font-size: 14px;font-weight: normal;"&gt;new&lt;/span&gt; CustomerEntity();&lt;br /&gt;        }&lt;br /&gt;&lt;br /&gt;        &lt;span style="color: Blue;background-color: Transparent;font-family: Courier New;font-size: 14px;font-weight: normal;"&gt;public&lt;/span&gt; &lt;span style="color: Blue;background-color: Transparent;font-family: Courier New;font-size: 14px;font-weight: normal;"&gt;void&lt;/span&gt; EditCustomer(&lt;span style="color: Blue;background-color: Transparent;font-family: Courier New;font-size: 14px;font-weight: normal;"&gt;int&lt;/span&gt; customerId)&lt;br /&gt;        {&lt;br /&gt;            &lt;span style="color: Green;background-color: Transparent;font-family: Courier New;font-size: 14px;font-weight: normal;"&gt;// Code, um Customer Entity zu laden&lt;/span&gt;&lt;br /&gt;            &lt;span style="color: Green;background-color: Transparent;font-family: Courier New;font-size: 14px;font-weight: normal;"&gt;// this.Customer = ...&lt;/span&gt;&lt;br /&gt;        }&lt;br /&gt;&lt;br /&gt;        &lt;span style="color: Blue;background-color: Transparent;font-family: Courier New;font-size: 14px;font-weight: normal;"&gt;public&lt;/span&gt; CustomerEntity Customer&lt;br /&gt;        {&lt;br /&gt;            get { &lt;span style="color: Blue;background-color: Transparent;font-family: Courier New;font-size: 14px;font-weight: normal;"&gt;return&lt;/span&gt; _customer; }&lt;br /&gt;            set&lt;br /&gt;            {&lt;br /&gt;                _customer &lt;span style="color: Red;background-color: Transparent;font-family: Courier New;font-size: 14px;font-weight: normal;"&gt;=&lt;/span&gt; value;&lt;br /&gt;&lt;br /&gt;                &lt;span style="color: Blue;background-color: Transparent;font-family: Courier New;font-size: 14px;font-weight: normal;"&gt;this&lt;/span&gt;.OnPropertyChanged(&lt;span style="color: #666666;background-color: #e4e4e4;font-family: Courier New;font-size: 14px;font-weight: normal;"&gt;"Customer"&lt;/span&gt;);&lt;br /&gt;            }&lt;br /&gt;        }&lt;br /&gt;    }&lt;br /&gt;&lt;br /&gt;&lt;span style="color: Blue;background-color: Transparent;font-family: Courier New;font-size: 14px;font-weight: normal;"&gt;public&lt;/span&gt; &lt;span style="color: Blue;background-color: Transparent;font-family: Courier New;font-size: 14px;font-weight: normal;"&gt;class&lt;/span&gt; SearchCustomerModel : Model&lt;br /&gt;    {&lt;br /&gt;        &lt;span style="color: Blue;background-color: Transparent;font-family: Courier New;font-size: 14px;font-weight: normal;"&gt;private&lt;/span&gt; IEnumerable&amp;lt;CustomerEntity&amp;gt; _customers &lt;span style="color: Red;background-color: Transparent;font-family: Courier New;font-size: 14px;font-weight: normal;"&gt;=&lt;/span&gt; &lt;br /&gt;&lt;span style="color: Blue;background-color: Transparent;font-family: Courier New;font-size: 14px;font-weight: normal;"&gt;new&lt;/span&gt; List&amp;lt;CustomerEntity&amp;gt;();&lt;br /&gt;&lt;br /&gt;        &lt;span style="color: Blue;background-color: Transparent;font-family: Courier New;font-size: 14px;font-weight: normal;"&gt;private&lt;/span&gt; CustomerEntity _selectedCustomer &lt;span style="color: Red;background-color: Transparent;font-family: Courier New;font-size: 14px;font-weight: normal;"&gt;=&lt;/span&gt; &lt;span style="color: Blue;background-color: Transparent;font-family: Courier New;font-size: 14px;font-weight: normal;"&gt;null&lt;/span&gt;;&lt;br /&gt;&lt;br /&gt;        &lt;span style="color: Blue;background-color: Transparent;font-family: Courier New;font-size: 14px;font-weight: normal;"&gt;public&lt;/span&gt; CustomerEntity SelectedCustomer&lt;br /&gt;        {&lt;br /&gt;            get { &lt;span style="color: Blue;background-color: Transparent;font-family: Courier New;font-size: 14px;font-weight: normal;"&gt;return&lt;/span&gt; _selectedCustomer; }&lt;br /&gt;            set&lt;br /&gt;            {&lt;br /&gt;                _selectedCustomer &lt;span style="color: Red;background-color: Transparent;font-family: Courier New;font-size: 14px;font-weight: normal;"&gt;=&lt;/span&gt; value;&lt;br /&gt;&lt;br /&gt;                &lt;span style="color: Green;background-color: Transparent;font-family: Courier New;font-size: 14px;font-weight: normal;"&gt;// Aktualisiert DataBindings für SelectedCustomer&lt;/span&gt;&lt;br /&gt;                &lt;span style="color: Blue;background-color: Transparent;font-family: Courier New;font-size: 14px;font-weight: normal;"&gt;this&lt;/span&gt;.OnPropertyChanged(&lt;span style="color: #666666;background-color: #e4e4e4;font-family: Courier New;font-size: 14px;font-weight: normal;"&gt;"SelectedCustomer"&lt;/span&gt;);&lt;br /&gt;&lt;br /&gt;                &lt;span style="color: Green;background-color: Transparent;font-family: Courier New;font-size: 14px;font-weight: normal;"&gt;// Aktualisiert die IsEnabled Eigenschaft des Buttons&lt;/span&gt;&lt;br /&gt;                &lt;span style="color: Blue;background-color: Transparent;font-family: Courier New;font-size: 14px;font-weight: normal;"&gt;this&lt;/span&gt;.OnPropertyChanged(&lt;span style="color: #666666;background-color: #e4e4e4;font-family: Courier New;font-size: 14px;font-weight: normal;"&gt;"IsCustomerSelected"&lt;/span&gt;);&lt;br /&gt;            }&lt;br /&gt;        }&lt;br /&gt;&lt;br /&gt;        &lt;span style="color: Blue;background-color: Transparent;font-family: Courier New;font-size: 14px;font-weight: normal;"&gt;public&lt;/span&gt; IEnumerable&amp;lt;CustomerEntity&amp;gt; Customers&lt;br /&gt;        {&lt;br /&gt;            get { &lt;span style="color: Blue;background-color: Transparent;font-family: Courier New;font-size: 14px;font-weight: normal;"&gt;return&lt;/span&gt; _customers; }&lt;br /&gt;            set&lt;br /&gt;            {&lt;br /&gt;                _customers &lt;span style="color: Red;background-color: Transparent;font-family: Courier New;font-size: 14px;font-weight: normal;"&gt;=&lt;/span&gt; value;&lt;br /&gt;&lt;br /&gt;                &lt;span style="color: Green;background-color: Transparent;font-family: Courier New;font-size: 14px;font-weight: normal;"&gt;// OnPropertyChanged aktiviert das updaten der Liste in der Ansicht, falls DataBinding verwendet wurde&lt;/span&gt;&lt;br /&gt;                &lt;span style="color: Blue;background-color: Transparent;font-family: Courier New;font-size: 14px;font-weight: normal;"&gt;this&lt;/span&gt;.OnPropertyChanged(&lt;span style="color: #666666;background-color: #e4e4e4;font-family: Courier New;font-size: 14px;font-weight: normal;"&gt;"Customers"&lt;/span&gt;);&lt;br /&gt;            }&lt;br /&gt;        }&lt;br /&gt;&lt;br /&gt;        &lt;span style="color: Blue;background-color: Transparent;font-family: Courier New;font-size: 14px;font-weight: normal;"&gt;public&lt;/span&gt; &lt;span style="color: Blue;background-color: Transparent;font-family: Courier New;font-size: 14px;font-weight: normal;"&gt;void&lt;/span&gt; LoadAllCustomers()&lt;br /&gt;        {&lt;br /&gt;            &lt;span style="color: Green;background-color: Transparent;font-family: Courier New;font-size: 14px;font-weight: normal;"&gt;// Code, um alle CustomerEntities zu laden&lt;/span&gt;&lt;br /&gt;            &lt;span style="color: Green;background-color: Transparent;font-family: Courier New;font-size: 14px;font-weight: normal;"&gt;// this.Customers = ...&lt;/span&gt;&lt;br /&gt;        }&lt;br /&gt;&lt;br /&gt;        &lt;span style="color: Blue;background-color: Transparent;font-family: Courier New;font-size: 14px;font-weight: normal;"&gt;public&lt;/span&gt; &lt;span style="color: Blue;background-color: Transparent;font-family: Courier New;font-size: 14px;font-weight: normal;"&gt;void&lt;/span&gt; SearchCustomers(&lt;span style="color: Blue;background-color: Transparent;font-family: Courier New;font-size: 14px;font-weight: normal;"&gt;string&lt;/span&gt; text)&lt;br /&gt;        {&lt;br /&gt;            &lt;span style="color: Green;background-color: Transparent;font-family: Courier New;font-size: 14px;font-weight: normal;"&gt;// Code, um CustomerEntities zu laden&lt;/span&gt;&lt;br /&gt;        }&lt;br /&gt;&lt;br /&gt;        &lt;span style="color: Blue;background-color: Transparent;font-family: Courier New;font-size: 14px;font-weight: normal;"&gt;public&lt;/span&gt; &lt;span style="color: Blue;background-color: Transparent;font-family: Courier New;font-size: 14px;font-weight: normal;"&gt;bool&lt;/span&gt; IsCustomerSelected&lt;br /&gt;        {&lt;br /&gt;            get&lt;br /&gt;            {&lt;br /&gt;                &lt;span style="color: Blue;background-color: Transparent;font-family: Courier New;font-size: 14px;font-weight: normal;"&gt;return&lt;/span&gt; &lt;span style="color: Blue;background-color: Transparent;font-family: Courier New;font-size: 14px;font-weight: normal;"&gt;this&lt;/span&gt;.SelectedCustomer !&lt;span style="color: Red;background-color: Transparent;font-family: Courier New;font-size: 14px;font-weight: normal;"&gt;=&lt;/span&gt; &lt;span style="color: Blue;background-color: Transparent;font-family: Courier New;font-size: 14px;font-weight: normal;"&gt;null&lt;/span&gt; ? &lt;span style="color: Blue;background-color: Transparent;font-family: Courier New;font-size: 14px;font-weight: normal;"&gt;true&lt;/span&gt; : &lt;span style="color: Blue;background-color: Transparent;font-family: Courier New;font-size: 14px;font-weight: normal;"&gt;false&lt;/span&gt;;&lt;br /&gt;            }&lt;br /&gt;        }&lt;br /&gt;    }&lt;/span&gt;&lt;/code&gt;&lt;/P&gt;
&lt;P&gt;&amp;nbsp;&lt;/P&gt;
&lt;P&gt;&lt;STRONG&gt;&lt;/STRONG&gt;&amp;nbsp;&lt;/P&gt;
&lt;P&gt;&lt;STRONG&gt;View&lt;/STRONG&gt;:&lt;/P&gt;
&lt;P&gt;Die Views hier als Code bereitzustellen, sprengt den Rahmen dieses Artikels. Ich bitte hierzu die Vorstellungskraft des Lesers zu bemühen, um sich die Views für EditCustomerView und SearchCustomerView vorzustellen. &lt;BR&gt;Das Databinding für ListView und SearchCustomerModel.Customers, sowie den Edit Button mit IsCustomerSelected zu verknüpfen, können wir uns vorstellen.&lt;BR&gt;Im View ist eine Referenz auf den Presenter zu setzen, um auf die Methoden des Presenters zugreifen zu können.&lt;/P&gt;
&lt;P&gt;&amp;nbsp;&lt;/P&gt;
&lt;P&gt;&lt;code&gt;&lt;span style="color: Black;background-color: Transparent;font-family: Courier New;font-size: 14px;font-weight: normal;"&gt; &lt;br /&gt;&lt;span style="color: Blue;background-color: Transparent;font-family: Courier New;font-size: 14px;font-weight: normal;"&gt;public&lt;/span&gt; partial &lt;span style="color: Blue;background-color: Transparent;font-family: Courier New;font-size: 14px;font-weight: normal;"&gt;class&lt;/span&gt; SearchCustomerView : Page&lt;br /&gt;    {&lt;br /&gt;        &lt;span style="color: Blue;background-color: Transparent;font-family: Courier New;font-size: 14px;font-weight: normal;"&gt;private&lt;/span&gt; SearchCustomerPresenter Presenter { get; set; }&lt;br /&gt;&lt;br /&gt;        &lt;span style="color: Blue;background-color: Transparent;font-family: Courier New;font-size: 14px;font-weight: normal;"&gt;public&lt;/span&gt; SearchCustomerView()&lt;br /&gt;        {&lt;br /&gt;            InitializeComponent();&lt;br /&gt;&lt;br /&gt;            &lt;span style="color: Green;background-color: Transparent;font-family: Courier New;font-size: 14px;font-weight: normal;"&gt;// Neue Presenter Instanz&lt;/span&gt;&lt;br /&gt;            &lt;span style="color: Blue;background-color: Transparent;font-family: Courier New;font-size: 14px;font-weight: normal;"&gt;this&lt;/span&gt;.Presenter &lt;span style="color: Red;background-color: Transparent;font-family: Courier New;font-size: 14px;font-weight: normal;"&gt;=&lt;/span&gt; &lt;span style="color: Blue;background-color: Transparent;font-family: Courier New;font-size: 14px;font-weight: normal;"&gt;new&lt;/span&gt; SearchCustomerPresenter();&lt;br /&gt;&lt;br /&gt;            &lt;span style="color: Green;background-color: Transparent;font-family: Courier New;font-size: 14px;font-weight: normal;"&gt;// Model binden mit DataContext des View für DataBinding&lt;/span&gt;&lt;br /&gt;            &lt;span style="color: Blue;background-color: Transparent;font-family: Courier New;font-size: 14px;font-weight: normal;"&gt;this&lt;/span&gt;.DataContext &lt;span style="color: Red;background-color: Transparent;font-family: Courier New;font-size: 14px;font-weight: normal;"&gt;=&lt;/span&gt; &lt;span style="color: Blue;background-color: Transparent;font-family: Courier New;font-size: 14px;font-weight: normal;"&gt;this&lt;/span&gt;.Presenter.Model;&lt;br /&gt;&lt;br /&gt;        }&lt;br /&gt;&lt;br /&gt;        &lt;span style="color: Blue;background-color: Transparent;font-family: Courier New;font-size: 14px;font-weight: normal;"&gt;private&lt;/span&gt; &lt;span style="color: Blue;background-color: Transparent;font-family: Courier New;font-size: 14px;font-weight: normal;"&gt;void&lt;/span&gt; searchButton_Click_1(&lt;span style="color: Blue;background-color: Transparent;font-family: Courier New;font-size: 14px;font-weight: normal;"&gt;object&lt;/span&gt; sender, RoutedEventArgs e)&lt;br /&gt;        {&lt;br /&gt;            &lt;span style="color: Blue;background-color: Transparent;font-family: Courier New;font-size: 14px;font-weight: normal;"&gt;this&lt;/span&gt;.Presenter.SearchCustomers(&lt;span style="color: Blue;background-color: Transparent;font-family: Courier New;font-size: 14px;font-weight: normal;"&gt;this&lt;/span&gt;.searchTextBox.Text);&lt;br /&gt;        }&lt;br /&gt;&lt;br /&gt;        &lt;span style="color: Blue;background-color: Transparent;font-family: Courier New;font-size: 14px;font-weight: normal;"&gt;private&lt;/span&gt; &lt;span style="color: Blue;background-color: Transparent;font-family: Courier New;font-size: 14px;font-weight: normal;"&gt;void&lt;/span&gt; loadAllCustomers_Click_1(&lt;span style="color: Blue;background-color: Transparent;font-family: Courier New;font-size: 14px;font-weight: normal;"&gt;object&lt;/span&gt; sender, RoutedEventArgs e)&lt;br /&gt;        {&lt;br /&gt;            &lt;span style="color: Blue;background-color: Transparent;font-family: Courier New;font-size: 14px;font-weight: normal;"&gt;this&lt;/span&gt;.Presenter.LoadAllCustomers();&lt;br /&gt;        }&lt;br /&gt;    }&lt;/span&gt;&lt;/code&gt;&lt;/P&gt;
&lt;P&gt;&lt;STRONG&gt;&lt;/STRONG&gt;&amp;nbsp;&lt;/P&gt;
&lt;P&gt;&lt;STRONG&gt;Presenter / ViewModel&lt;/STRONG&gt;:&lt;/P&gt;
&lt;P&gt;Persönlich finde ich die Namensgebung Presenter besser als ViewModel; so kann besser zwischen Model-, View- und Presenterklassen unterschieden werden. &lt;BR&gt;Im Presenter ist die Presentationslogik. Der Presenter delegiert meistens nur vom View zum Model. &lt;BR&gt;Microsoft empfiehlt bezüglich MVVM das ViewModel (Presenter) als DataContext im View zu setzen - dies im Zusammenhang mit Commands, die sich im Presenter befinden und mit Steuerelementen des Views gebunden werden; in meinem Beispiel setze ich als DataContext das Model.&lt;/P&gt;
&lt;P&gt;Ich meine, dass das MVVM Schema im Sinne von Microsoft hinterfragt werden muss, denn Microsoft trennt im MVVM-Schema nicht klar zwischen Model und Presenter oder besser ausgedrückt zwischen Daten und Presentation. Das Model klar vom ViewModel (Presenter) zu trennen, ist ja aber gerade die ursprüngliche Idee dieser Pattern MVP und MVVM. &lt;/P&gt;
&lt;P&gt;Meiner Ansicht nach gehören Daten ins Model und nicht in die Presentationslogik: deshalb setze ich das Model als DataContext im View und nicht das ViewModel (Presenter).&lt;/P&gt;
&lt;P&gt;In meinem Beispiel habe ich eine einfache Implementierung verwendet, ohne Kommunikation zwischen Presenter und View:&lt;/P&gt;
&lt;P&gt;&amp;nbsp;&lt;/P&gt;
&lt;P&gt;&lt;code&gt;&lt;span style="color: Black;background-color: Transparent;font-family: Courier New;font-size: 14px;font-weight: normal;"&gt; &lt;br /&gt;&lt;span style="color: Blue;background-color: Transparent;font-family: Courier New;font-size: 14px;font-weight: normal;"&gt;public&lt;/span&gt; &lt;span style="color: Blue;background-color: Transparent;font-family: Courier New;font-size: 14px;font-weight: normal;"&gt;class&lt;/span&gt; EditCustomerPresenter&lt;br /&gt;    {&lt;br /&gt;        &lt;span style="color: Blue;background-color: Transparent;font-family: Courier New;font-size: 14px;font-weight: normal;"&gt;public&lt;/span&gt; EditCustomerPresenter()&lt;br /&gt;        {&lt;br /&gt;            &lt;span style="color: Blue;background-color: Transparent;font-family: Courier New;font-size: 14px;font-weight: normal;"&gt;this&lt;/span&gt;.Model &lt;span style="color: Red;background-color: Transparent;font-family: Courier New;font-size: 14px;font-weight: normal;"&gt;=&lt;/span&gt; &lt;span style="color: Blue;background-color: Transparent;font-family: Courier New;font-size: 14px;font-weight: normal;"&gt;new&lt;/span&gt; EditCustomerModel();&lt;br /&gt;        }&lt;br /&gt;&lt;br /&gt;        &lt;span style="color: Blue;background-color: Transparent;font-family: Courier New;font-size: 14px;font-weight: normal;"&gt;public&lt;/span&gt; &lt;span style="color: Blue;background-color: Transparent;font-family: Courier New;font-size: 14px;font-weight: normal;"&gt;void&lt;/span&gt; NewCustomer()&lt;br /&gt;        {&lt;br /&gt;            &lt;span style="color: Blue;background-color: Transparent;font-family: Courier New;font-size: 14px;font-weight: normal;"&gt;this&lt;/span&gt;.Model.NewCustomer();&lt;br /&gt;        }&lt;br /&gt;&lt;br /&gt;        &lt;span style="color: Blue;background-color: Transparent;font-family: Courier New;font-size: 14px;font-weight: normal;"&gt;public&lt;/span&gt; &lt;span style="color: Blue;background-color: Transparent;font-family: Courier New;font-size: 14px;font-weight: normal;"&gt;void&lt;/span&gt; EditCustomer(&lt;span style="color: Blue;background-color: Transparent;font-family: Courier New;font-size: 14px;font-weight: normal;"&gt;int&lt;/span&gt; customerId)&lt;br /&gt;        {&lt;br /&gt;            &lt;span style="color: Blue;background-color: Transparent;font-family: Courier New;font-size: 14px;font-weight: normal;"&gt;this&lt;/span&gt;.Model.EditCustomer(customerId);&lt;br /&gt;&lt;br /&gt;            &lt;span style="color: Green;background-color: Transparent;font-family: Courier New;font-size: 14px;font-weight: normal;"&gt;// Falls ohne DataBinding per xaml:&lt;/span&gt;&lt;br /&gt;            &lt;span style="color: Green;background-color: Transparent;font-family: Courier New;font-size: 14px;font-weight: normal;"&gt;// UpdateView();&lt;/span&gt;&lt;br /&gt;        }&lt;br /&gt;&lt;br /&gt;        &lt;span style="color: Blue;background-color: Transparent;font-family: Courier New;font-size: 14px;font-weight: normal;"&gt;public&lt;/span&gt; EditCustomerModel Model { get; set; }&lt;br /&gt;    }&lt;br /&gt;&lt;br /&gt;&lt;span style="color: Blue;background-color: Transparent;font-family: Courier New;font-size: 14px;font-weight: normal;"&gt;public&lt;/span&gt; &lt;span style="color: Blue;background-color: Transparent;font-family: Courier New;font-size: 14px;font-weight: normal;"&gt;class&lt;/span&gt; SearchCustomerPresenter&lt;br /&gt;    {&lt;br /&gt;        &lt;span style="color: Blue;background-color: Transparent;font-family: Courier New;font-size: 14px;font-weight: normal;"&gt;public&lt;/span&gt; SearchCustomerPresenter()&lt;br /&gt;        {&lt;br /&gt;            &lt;span style="color: Blue;background-color: Transparent;font-family: Courier New;font-size: 14px;font-weight: normal;"&gt;this&lt;/span&gt;.Model &lt;span style="color: Red;background-color: Transparent;font-family: Courier New;font-size: 14px;font-weight: normal;"&gt;=&lt;/span&gt; &lt;span style="color: Blue;background-color: Transparent;font-family: Courier New;font-size: 14px;font-weight: normal;"&gt;new&lt;/span&gt; SearchCustomerModel();&lt;br /&gt;        }&lt;br /&gt;&lt;br /&gt;        &lt;span style="color: Blue;background-color: Transparent;font-family: Courier New;font-size: 14px;font-weight: normal;"&gt;public&lt;/span&gt; SearchCustomerModel Model { get; set; }&lt;br /&gt;&lt;br /&gt;        &lt;span style="color: Blue;background-color: Transparent;font-family: Courier New;font-size: 14px;font-weight: normal;"&gt;public&lt;/span&gt; &lt;span style="color: Blue;background-color: Transparent;font-family: Courier New;font-size: 14px;font-weight: normal;"&gt;void&lt;/span&gt; SearchCustomers(&lt;span style="color: Blue;background-color: Transparent;font-family: Courier New;font-size: 14px;font-weight: normal;"&gt;string&lt;/span&gt; text)&lt;br /&gt;        {&lt;br /&gt;            &lt;span style="color: Blue;background-color: Transparent;font-family: Courier New;font-size: 14px;font-weight: normal;"&gt;this&lt;/span&gt;.Model.SearchCustomers(text);&lt;br /&gt;        }&lt;br /&gt;&lt;br /&gt;        &lt;span style="color: Blue;background-color: Transparent;font-family: Courier New;font-size: 14px;font-weight: normal;"&gt;public&lt;/span&gt; &lt;span style="color: Blue;background-color: Transparent;font-family: Courier New;font-size: 14px;font-weight: normal;"&gt;void&lt;/span&gt; LoadAllCustomers()&lt;br /&gt;        {&lt;br /&gt;            &lt;span style="color: Blue;background-color: Transparent;font-family: Courier New;font-size: 14px;font-weight: normal;"&gt;this&lt;/span&gt;.Model.LoadAllCustomers();&lt;br /&gt;        }&lt;br /&gt;    }&lt;/span&gt;&lt;/code&gt;&lt;/P&gt;
&lt;P&gt;&amp;nbsp;&lt;/P&gt;
&lt;P&gt;Um nun an einem ganz kleinen Beispiel zu veranschaulichen, was Presentationslogik ist, erweitere ich die SearchCustomers Methode etwas:&lt;/P&gt;
&lt;P&gt;&amp;nbsp;&lt;/P&gt;
&lt;P&gt;&lt;code&gt;&lt;span style="color: Black;background-color: Transparent;font-family: Courier New;font-size: 14px;font-weight: normal;"&gt; &lt;br /&gt;&lt;span style="color: Blue;background-color: Transparent;font-family: Courier New;font-size: 14px;font-weight: normal;"&gt;public&lt;/span&gt; &lt;span style="color: Blue;background-color: Transparent;font-family: Courier New;font-size: 14px;font-weight: normal;"&gt;void&lt;/span&gt; SearchCustomers(&lt;span style="color: Blue;background-color: Transparent;font-family: Courier New;font-size: 14px;font-weight: normal;"&gt;string&lt;/span&gt; text)&lt;br /&gt;        {&lt;br /&gt;            &lt;span style="color: Blue;background-color: Transparent;font-family: Courier New;font-size: 14px;font-weight: normal;"&gt;this&lt;/span&gt;.Model.SearchCustomers(text);&lt;br /&gt;                &lt;br /&gt;MessageBox.Show(String.Format(&lt;span style="color: #666666;background-color: #e4e4e4;font-family: Courier New;font-size: 14px;font-weight: normal;"&gt;"{0} Kunde(n) gefunden."&lt;/span&gt;, &lt;span style="color: Blue;background-color: Transparent;font-family: Courier New;font-size: 14px;font-weight: normal;"&gt;this&lt;/span&gt;.Model.Customers.Count()));&lt;br /&gt;            &lt;br /&gt;        }&lt;/span&gt;&lt;/code&gt;&lt;/P&gt;
&lt;P&gt;&amp;nbsp;&lt;/P&gt;
&lt;P&gt;Wo sonst sollte die MessageBox die Anzahl der Ergebnisse anzeigen, wenn nicht in der Presentationslogik des Presenters? Diese Info soll natürlich nur die Presenationslogik veranschaulichen; solche unnötigen Infos sollten in Businessapplikationen vermieden werden.&lt;/P&gt;
&lt;P&gt;Auch erfahrene Entwickler brauchen etwas Zeit, wenn sie sich zum ersten Mal mit MVP und MVVM beschäftigen, um diese Patterns zu verstehen. Das beste Verständnis habe ich persönlich beim Implementieren eigener MVPs gewonnen und kann das nur weiterempfehlen.&lt;/P&gt;
&lt;P&gt;Hier eine fragwürdige Implementierung des MVVM:&lt;/P&gt;
&lt;P&gt;&lt;A href="http://msdn.microsoft.com/de-de/magazine/dd419663.aspx"&gt;http://msdn.microsoft.com/de-de/magazine/dd419663.aspx&lt;/A&gt; &lt;/P&gt;
&lt;P&gt;Hierzu einige Äusserungen:&lt;BR&gt;Erstmal vorne weg: In diesem Artikel scheint ein Model gar nicht erst vorzukommen; die Daten wurden in das ViewModel, bzw. in den Presenter, also in die Presentationlogik hineingesetzt. Deshalb wurde dort auch die Schnittstelle INotifyPropertyChanged implementiert, die klar ins Model gehört. &lt;/P&gt;
&lt;P&gt;&lt;BR&gt;&lt;STRONG&gt;Fazit&lt;/STRONG&gt;:&lt;BR&gt;&amp;nbsp;&lt;BR&gt;Der MVP Pattern trennt klar Model und Presenter; der MVVM Pattern scheint diese Trennung nicht mehr anzustreben. Auch wenn wir uns vorstellen, Models zu entwickeln, die mit Hilfe von Generics standardmässig Eigenschaften zur Verfügung stellen, scheint mir die Trennung zwischen Model und Presenter im Sinne der Klassenhierarchie wichtig; So würden wir wohl Basisklassen einerseits für Daten-Modelle und andererseits für Presentationslogik erstellen und kaum beides in eine ViewModel-Klasse zwängen.&lt;BR&gt;Wichtig ist für mich auch die Trennung zwischen Entity und Model.&lt;BR&gt;Der MVVM Pattern scheint einige sinnvolle Eigenheiten des MVP Pattern über Bord zu schmeissen (z.B. klare Trennung zwischen Model und Presenter). Die aufwendige Verwendung von Commands sehe ich nicht als existentielle Erweiterung beim MVVM; ich sehe die MVP Implementierung als einfacher und klarer an. &lt;/P&gt;
&lt;P&gt;&lt;BR&gt;Stefan Werdenberg, IntegralFramework&lt;/P&gt;</description></item><item><title>Vom Visual Studio zum Wix Setup in 5 einfachen Schritten</title><link>http://www.aspnetzone.de/blogs/juergengutsch/archive/2011/03/08/vom-visual-studio-zum-wix-setup-in-5-einfachen-schritten.aspx</link><pubDate>Tue, 08 Mar 2011 11:13:00 GMT</pubDate><guid isPermaLink="false">ce930855-ae9b-4fa4-8077-06a76071cc6a:221196</guid><dc:creator>Jürgen Gutsch</dc:creator><description>&lt;P&gt;Der folgende Beitrag ist ein Gastbeitrag von Sebastian Seidel, Gründer und Inhaber der Firma Cayas (&lt;A href="http://www.cayas.de/"&gt;http://www.cayas.de/&lt;/A&gt;). Vor einigen Monaten hatte ich per Twitter die Frage gestellt, wie man aus einem herkömmlichen Visual Studio Setup-Projekt ein Windows Installer XML-Projekt (WiX) erstellt. Falls es weitere Fragen zu WiX gibt, ist Sebastian über seine Website oder per &lt;A href="http://twitter.com/Cayas_Software"&gt;Twitter&lt;/A&gt; zu erreichen.&lt;/P&gt;
&lt;P&gt;Von meiner Seite ein großes Dankeschön an Sebastian, dass er sich die Mühe gemacht hat hier eine Anleitung zur Migration zu schreiben und hier zu veröffentlichen :-)&lt;/P&gt;
&lt;P&gt;--------------&lt;/P&gt;
&lt;P&gt;&lt;STRONG&gt;Vom Visual Studio zum Wix Setup in 5 einfachen Schritten&lt;/STRONG&gt;&lt;/P&gt;
&lt;P&gt;Vor einiger Zeit wurde über Twitter die Frage gestellt, wie man ein bestehendes Visual Studio Setup-Projekt (vd-proj) in ein Windows Installer XML-Setup (wixproj) migriert. Ich möchte an dieser Stelle einen möglichen Weg aufzeigen, wie man dies erreichen kann.&lt;/P&gt;
&lt;P&gt;&lt;B&gt;Schritt 1: Vorbereitung&lt;/B&gt;&lt;/P&gt;
&lt;P&gt;Um die Schritte nachvollziehen zu können benötigt ihr die aktuelle Version von Wix, die ihr unter &lt;A href="http://wix.sourceforge.net"&gt;http://wix.sourceforge.net&lt;/A&gt; herunterladen könnt. In diesem Artikel verwende ich die aktuelle Version 3.5 des Windows Installer XML Toolsets.&lt;/P&gt;
&lt;P&gt;Nach dem alles installiert und ins Visual Studio integriert ist solltet ihr folgendes Bild haben, wenn ihr ein neues Projekt erstellen wollt.&lt;/P&gt;
&lt;P&gt;&lt;A href="http://www.aspnetzone.de/photos/juergengutsch/images/221193/original.aspx"&gt;&lt;IMG border=0 alt="" src="http://www.aspnetzone.de/photos/juergengutsch/images/221193/500x346.aspx"&gt;&lt;/A&gt;&lt;/P&gt;
&lt;P&gt;Beginnen wir nun also mit der Konvertierung.&lt;/P&gt;
&lt;P&gt;&lt;B&gt;Schritt 2: altes Setup erstellen&lt;/B&gt;&lt;/P&gt;
&lt;P&gt;Im eigentlichen ersten Schritt bleibt alles wie gehabt. Ihr erstellt also euer Setup über die VS-Setup Solution. Das Ergebnis des Builds ist eine Setup.exe und ein Setup.msi-Paket.&lt;/P&gt;
&lt;P&gt;&lt;B&gt;Schritt 3: altes Setup dekompilieren&lt;/B&gt;&lt;/P&gt;
&lt;P&gt;Für das unter Schritt 2 erstelle msi-Paket erstellen wir uns einen Ordner &lt;I&gt;WixTransform &lt;/I&gt;auf dem Desktop und kopieren unser msi-File dort hin. Anschließend öffnen wir eine Command-Box (cmd) und wechseln in das Installationsverzeichnis vom Windows Installer XML. Darin befindet sich eine Datei namens &lt;I&gt;Dark.exe&lt;/I&gt;, die wir mit dem Parameter &lt;I&gt;-h&lt;/I&gt; aufrufen. Im folgenden Bild sieht man einen Teil der ausgegebenen Parameter, die mit Dark verwendet werden können.&lt;/P&gt;
&lt;P&gt;&lt;A href="http://www.aspnetzone.de/photos/juergengutsch/images/221195/original.aspx"&gt;&lt;IMG border=0 alt="" src="http://www.aspnetzone.de/photos/juergengutsch/images/221195/500x253.aspx"&gt;&lt;/A&gt;&lt;/P&gt;
&lt;P&gt;Uns interessiert nur der &lt;I&gt;-o[ut]&lt;/I&gt; Parameter mit dem wir angegeben können, wohin wir den Output umgeleitet haben möchten.&lt;/P&gt;
&lt;P&gt;&lt;B&gt;Hinweis: Dark kann nicht mit Leerzeichen im Pfad umgehen. Ich behelfe mir damit, dass ich mein msi-Paket in einen Ordner auf dem Desktop kopiere und alle Leerzeichen entferne.&lt;/B&gt;&lt;/P&gt;
&lt;P&gt;Wir haben nun alle Vorbereitungen erledigt und können mit der eigentlichen Konvertierung beginnen. Dazu geben wir folgenden Aufruf ein:&lt;/P&gt;
&lt;P&gt;&lt;I&gt;Dark.exe -nologo -o C:\Users\Sebastian\Desktop\WixTransform\mySetup.wxs C:\Users\Sebastian\Desktop\WixTransform\Setup.msi&lt;/I&gt;&lt;/P&gt;
&lt;P&gt;Wenn der Vorgang erfolgreich durchgeführt wurde, finden wir in unserem Ordner - bei mir WixTransform - nun eine &lt;I&gt;mySetup.wxs&lt;/I&gt;, die den kompletten Aufbau unseres alten Setups enthält.&lt;/P&gt;
&lt;P&gt;&lt;B&gt;Schritt 4: Neues Setup-Projekt erstellen&lt;/B&gt;&lt;/P&gt;
&lt;P&gt;Wir haben in den vorherigen Schritten unser Setup erstellt und es anschließend wieder in eine Windows Installer XML Source Datei konvertiert. Im letzten Schritt geht es nun darum diese zu nutzen. Wir wechseln dazu ins Visual Studio und fügen unserer Solution ein weiteres Projekt hinzu. Dieses Mal allerdings eins vom Typ Windows Installer XML Setup Projekt.&lt;/P&gt;
&lt;P&gt;Unser leeres Projekt besteht lediglich aus der Product.wxs, welche wir löschen bzw. durch unsere mySetup.wxs ersetzen.&lt;/P&gt;
&lt;P&gt;&lt;B&gt;Schritt 5: Aufräumen&lt;/B&gt;&lt;/P&gt;
&lt;P&gt;Damit unser Setup nun wieder ordnungsgemäß erstellt werden kann müssen wir unsere mySetup.wxs noch aufräumen. Die folgende Beschreibung gibt meine Vorgehensweise wieder. Sicherlich gibt es verschiedene Wege das Ziel zu erreichen. Wenn Ihr also einen optimaleren Weg gefunden habt, so lasst es mich doch wissen, in dem Ihr einfach ein Kommentar schreibt.&lt;/P&gt;
&lt;P&gt;Fangen wir also an in dem wir unsere mySetup.wxs von oben nach unten durchgehen. Zuerst entferne ich alle &lt;I&gt;&amp;lt;Binary&amp;gt;,&lt;/I&gt; &lt;I&gt;&amp;lt;CustomAction&amp;gt;, &amp;lt;CustomTable&amp;gt; &lt;/I&gt;und &lt;I&gt;&amp;lt;Property&amp;gt;&lt;/I&gt; Elemente. Ausgenommen sind natürlich die CustomActions, die ich eventuell auch in meinem ursprünglichen VS-Setup eingebunden hatte sowie die folgenden und meine eigenen Properties:&lt;/P&gt;
&lt;P&gt;&lt;code&gt;&lt;span style="color: Black;background-color: Transparent;font-family: Courier New;font-size: 14px;font-weight: normal;"&gt;&lt;span style="color: Blue;background-color: Transparent;font-family: Courier New;font-size: 14px;font-weight: normal;"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: Maroon;background-color: Transparent;font-family: Courier New;font-size: 14px;font-weight: normal;"&gt;Property&lt;/span&gt; &lt;span style="color: Red;background-color: Transparent;font-family: Courier New;font-size: 14px;font-weight: normal;"&gt;Id&lt;/span&gt;&lt;span style="color: Blue;background-color: Transparent;font-family: Courier New;font-size: 14px;font-weight: normal;"&gt;="ARPHELPTELEPHONE"&lt;/span&gt; &lt;span style="color: Red;background-color: Transparent;font-family: Courier New;font-size: 14px;font-weight: normal;"&gt;Value&lt;/span&gt;&lt;span style="color: Blue;background-color: Transparent;font-family: Courier New;font-size: 14px;font-weight: normal;"&gt;="1234 1234567"&lt;/span&gt; &lt;span style="color: Blue;background-color: Transparent;font-family: Courier New;font-size: 14px;font-weight: normal;"&gt;/&amp;gt;&lt;/span&gt; &lt;br /&gt;&lt;span style="color: Blue;background-color: Transparent;font-family: Courier New;font-size: 14px;font-weight: normal;"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: Maroon;background-color: Transparent;font-family: Courier New;font-size: 14px;font-weight: normal;"&gt;Property&lt;/span&gt; &lt;span style="color: Red;background-color: Transparent;font-family: Courier New;font-size: 14px;font-weight: normal;"&gt;Id&lt;/span&gt;&lt;span style="color: Blue;background-color: Transparent;font-family: Courier New;font-size: 14px;font-weight: normal;"&gt;="ARPCONTACT"&lt;/span&gt; &lt;span style="color: Red;background-color: Transparent;font-family: Courier New;font-size: 14px;font-weight: normal;"&gt;Value&lt;/span&gt;&lt;span style="color: Blue;background-color: Transparent;font-family: Courier New;font-size: 14px;font-weight: normal;"&gt;="Sebastian Seidel"&lt;/span&gt; &lt;span style="color: Blue;background-color: Transparent;font-family: Courier New;font-size: 14px;font-weight: normal;"&gt;/&amp;gt;&lt;/span&gt; &lt;br /&gt;&lt;span style="color: Blue;background-color: Transparent;font-family: Courier New;font-size: 14px;font-weight: normal;"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: Maroon;background-color: Transparent;font-family: Courier New;font-size: 14px;font-weight: normal;"&gt;Property&lt;/span&gt; &lt;span style="color: Red;background-color: Transparent;font-family: Courier New;font-size: 14px;font-weight: normal;"&gt;Id&lt;/span&gt;&lt;span style="color: Blue;background-color: Transparent;font-family: Courier New;font-size: 14px;font-weight: normal;"&gt;="ARPCOMMENTS"&lt;/span&gt; &lt;span style="color: Red;background-color: Transparent;font-family: Courier New;font-size: 14px;font-weight: normal;"&gt;Value&lt;/span&gt;&lt;span style="color: Blue;background-color: Transparent;font-family: Courier New;font-size: 14px;font-weight: normal;"&gt;="Mein Produktname"&lt;/span&gt; &lt;span style="color: Blue;background-color: Transparent;font-family: Courier New;font-size: 14px;font-weight: normal;"&gt;/&amp;gt;&lt;/span&gt; &lt;br /&gt;&lt;span style="color: Blue;background-color: Transparent;font-family: Courier New;font-size: 14px;font-weight: normal;"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: Maroon;background-color: Transparent;font-family: Courier New;font-size: 14px;font-weight: normal;"&gt;Property&lt;/span&gt; &lt;span style="color: Red;background-color: Transparent;font-family: Courier New;font-size: 14px;font-weight: normal;"&gt;Id&lt;/span&gt;&lt;span style="color: Blue;background-color: Transparent;font-family: Courier New;font-size: 14px;font-weight: normal;"&gt;="ARPURLINFOABOUT"&lt;/span&gt; &lt;span style="color: Red;background-color: Transparent;font-family: Courier New;font-size: 14px;font-weight: normal;"&gt;Value&lt;/span&gt;&lt;span style="color: Blue;background-color: Transparent;font-family: Courier New;font-size: 14px;font-weight: normal;"&gt;="http://www.cayas.de"&lt;/span&gt; &lt;span style="color: Blue;background-color: Transparent;font-family: Courier New;font-size: 14px;font-weight: normal;"&gt;/&amp;gt;&lt;/span&gt; &lt;br /&gt;&lt;span style="color: Blue;background-color: Transparent;font-family: Courier New;font-size: 14px;font-weight: normal;"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: Maroon;background-color: Transparent;font-family: Courier New;font-size: 14px;font-weight: normal;"&gt;Property&lt;/span&gt; &lt;span style="color: Red;background-color: Transparent;font-family: Courier New;font-size: 14px;font-weight: normal;"&gt;Id&lt;/span&gt;&lt;span style="color: Blue;background-color: Transparent;font-family: Courier New;font-size: 14px;font-weight: normal;"&gt;="ARPPRODUCTICON"&lt;/span&gt; &lt;span style="color: Red;background-color: Transparent;font-family: Courier New;font-size: 14px;font-weight: normal;"&gt;Value&lt;/span&gt;&lt;span style="color: Blue;background-color: Transparent;font-family: Courier New;font-size: 14px;font-weight: normal;"&gt;="IconSource"&lt;/span&gt; &lt;span style="color: Blue;background-color: Transparent;font-family: Courier New;font-size: 14px;font-weight: normal;"&gt;/&amp;gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/P&gt;
&lt;P&gt;Anschließend ändere ich die kryptischen &lt;I&gt;&amp;lt;Component&amp;gt;&lt;/I&gt; IDs zu aussagekräftige ab. Da ich meine Dialoge in einer separaten Datei erstellt habe, lösche ich auch das &lt;I&gt;&amp;lt;UI&amp;gt;&lt;/I&gt; XML-Node. Wer möchte kann an dieser Stelle noch Einfluss auf die Dialoge nehmen und diese entsprechend anpassen.&lt;/P&gt;
&lt;P&gt;Zu guter Letzt entferne ich noch alle Nodes, die ein &lt;I&gt;Sequence&lt;/I&gt; enthalten. Auch das kann wieder jeder halten wie er möchte. Grundsätzlich kann man mit diesen Sequenzanweisungen viel Einfluss auf das Ausführungsverhalten des Setups nehmen.&lt;/P&gt;
&lt;P&gt;In einem letzten Durchgang passe ich dann alle Source-Elemente an, damit diese wieder die richtigen Dateien referenzieren.&lt;A name=_GoBack&gt;&lt;/A&gt;&lt;/P&gt;
&lt;DIV style="TEXT-ALIGN:left;PADDING-BOTTOM:4px;MARGIN:0px;PADDING-LEFT:4px;PADDING-RIGHT:4px;PADDING-TOP:4px;" class=wlWriterHeaderFooter&gt;&lt;A href="http://dotnet-kicks.de/kick/?url=http://www.aspnetzone.de/blogs/juergengutsch/archive/2011/03/08/vom-visual-studio-zum-wix-setup-in-5-einfachen-schritten.aspx"&gt;&lt;IMG border=0 alt="DotNetKicks-DE Image" src="http://dotnet-kicks.de/Services/Images/KickItImageGenerator.ashx?url=http://www.aspnetzone.de/blogs/juergengutsch/archive/2011/03/08/vom-visual-studio-zum-wix-setup-in-5-einfachen-schritten.aspx&amp;amp;bgcolor=3169AD&amp;amp;fgcolor=FFFFFF&amp;amp;border=000000&amp;amp;cbgcolor=D4E1ED&amp;amp;cfgcolor=000000"&gt;&lt;/A&gt;&lt;/DIV&gt;</description></item></channel></rss>