
		<rss version="2.0">
			<channel>
			<ttl>5</ttl>
				<title>ppedv Blog</title>
				<link>http://blog.ppedv.de</link>
				<description>update by ppedv ***** Team Blog</description>
				<lastbuildDate>Mon, 04 May 2026 17:21:44 GMT</lastbuildDate>

				<image>
				    <url>http://blogs.ppedv.de/images/logo2.gif</url>
				    <title>ppedv Blog</title>
				    <link>http://www.ppedv.de</link>
				</image>
	
		<item>
			<title>[Felix Ruthenberg] WPF Designer mit Fake-Daten fttern um Connection String Fehler zu vermeiden</title>
			<description>Beim Erstellen eines WPF-Projektes, das über eine ausgelagerte Bibliothek auf Daten über das Entity-Framework zugreift zeigt Visual Studio (2008 SP1) ein seltsames Verhalten.&#160; Die Anwendung kompiliert (solange fehlerfrei natürlich) allerdings ist der Designer “tot” und folgende Fehlermeldung (nicht Warnung) wird angezeigt:  “The specified named connection is either not found in the configuration, not intended to be used with the EntityClient provider, or not valid.”  Offensichtlich ein Fehler über einen fehlenden Connectionstring (fehlerhaft eher nicht, da der Connectionstring über den VS Wizard generiert wurde).&#160; Doch hinzufügen des Strings in die Sektion ConnectionStrings der App.Config bringt auch nicht den gewünschten Erfolg.  Das ist darauf zurückzuführen, dass während der Design-Zeit VS versucht uns LiveDaten zu präsentieren, dazu versucht der Prozess devenv.exe (nämlich unsere Instanz von Visual Studio) die benötigte Verbindung aufzubauen und sucht vergeblich in der eigenen Applikationskonfiguration (also in devenv.exe.config) nach dem entsprechenden Connectionstring.  Als Workaround empfiehlt Microsoft (https://connect.microsoft.com/VisualStudio/feedback/ViewFeedback.aspx?FeedbackID=386982), dass Fake-Daten während der Entwicklungszeit generiert und geliefert werden sollen.&#160; Das bedeutet, dass wir die Klassen, die uns das EntityDataModell erzeugt hat zwar nutzen können, aber nicht über dieses befüllen.&#160; Hierfür lassen sich die Präprozessordirektiven von C# prima einsetzen (http://msdn.microsoft.com/de-de/library/ed8yd1ha.aspx).&#160; Einfach mit Hilfe der Direktive #define am Anfang des entsprechenden Dokuments eine Konstante (als Name zum Beispiel “DesignView”) definieren und die mit der Direktive #if DesignView an entsprechender Stelle abfragen.&#160; Der Vorteil ist dabei, dass Code, der nicht benötigt wird auch gar nicht erst kompiliert wird.  Microsoft verspricht diesen Bug in VS 2010 zu beheben, in der Beta 2 ist davon allerdings noch nichts zu merken.</description>
			<link>http://blogs.ppedv.de/felixr/archive/WPF-Designer-mit-Fake-Daten-fuumlttern-um-Connection-String-Fehler-zu-vermeiden</link>
			<author>Felix Ruthenberg </author>
			<pubDate>Mon, 23 Nov 2009 10:15:37 GMT</pubDate>
			<category domain="http://blogs.ppedv.de?tag=">
			.Net</category><category>C#</category><category>WPF</category><category>
			</category>
			
		</item>
	
		<item>
			<title>[Felix Ruthenberg] Zeilennummern in WPF ListView anzeigen</title>
			<description>Gestern wurde ich gefragt ob es denn möglich sein, in einer WPF ListView Zeilennummern anzeigen zu lassen.&#160; Sicherlich ein Anwendungsfall, der nicht einmalig ist.  Meine Recherchen haben ergeben, dass es nicht implizit möglich ist Zeilennummern anzeigen zu lassen (also es gibt keine Property oder ähnliches dafür).&#160; Der erste Lösungsansatz ist also ein Converter, die ja bekanntlich alles in alles andere konvertieren können, warum also keine Berechnung der Zeilnummern?  Ein solcher Converter muss zwei Informationen erhalten:  1) Die Instanz der ListView, die ihn aufgerufen hat    2) Der Wert, der momentan an die ListView gebunden wird  Mit Hilfe dieser Informationen kann nun über die Items der ListView iteriert werden und ein Vergleich mit dem aktuellen Wert führt dann zur Position innerhalb der ListView.&#160; Versuche ein Binding mit einem Converter zu versehen und diesem als ConverterParameter das aufrufende Objekt mitzugeben schlugen leider fehl, stattdessen habe ich ein MultiBinding erzeugt und beide Informationen als separate Bindings übergeben.&#160; Der XAML Aussschnitt dazu sieht folgendermaßen aus:               1: &lt;ListView x:Name=&quot;lsvOfferMoreLP&quot; 


       2:     Height=&quot;Auto&quot; 


       3:     IsSynchronizedWithCurrentItem=&quot;True&quot; 


       4:     AllowDrop=&quot;True&quot; 


       5:     SelectionChanged=&quot;lsvOfferMoreLP_SelectionChanged&quot; TabIndex=&quot;28&quot;&gt;


       6:     &lt;ListView.Resources&gt;


       7:     &lt;/ListView.Resources&gt;


       8:     &lt;ListView.View&gt;


       9:         &lt;GridView&gt;


      10:             &lt;GridViewColumn Header=&quot;LineNumber&quot; &gt;


      11:                 &lt;GridViewColumn.DisplayMemberBinding&gt;


      12:                     &lt;MultiBinding Converter=&quot;{StaticResource ConverterLineNumbers}&quot;&gt;


      13:                         &lt;Binding Path=&quot;.&quot;/&gt;


      14:                         &lt;Binding&gt;


      15:                             &lt;Binding.RelativeSource&gt;


      16:                                 &lt;RelativeSource Mode=&quot;FindAncestor&quot; AncestorType=&quot;{x:Type ListView}&quot; /&gt;


      17:                             &lt;/Binding.RelativeSource&gt;


      18:                         &lt;/Binding&gt;


      19:                     &lt;/MultiBinding&gt;


      20:                 &lt;/GridViewColumn.DisplayMemberBinding&gt;


      21:             &lt;/GridViewColumn&gt;


      22:             &lt;GridViewColumn DisplayMemberBinding=&quot;{Binding Path=.}&quot; Header=&quot;Text&quot; /&gt;


      23:         &lt;/GridView&gt;


      24:     &lt;/ListView.View&gt;


      25: &lt;/ListView&gt;



Auffallend ist die zweite Bindung, die an eine RelativeSource geht.&#160; Wie vielleicht aus der Syntax zu verstehen ist, bezieht sich dieses Binding auf den nächsten Vorfahren im Control Tree, der eine ListView ist.&#160; Damit enthält unsere Converter-Klasse (die das Interface IMultivalueConverter implementiert) sowohl die Instanz der auslösenden Listview sowie der aktuell zu bindende Wert.

In der Klasse ConverterLineNumbers, die als Ressource instanziiert und im MultBinding verwendet wird muss also das Interface IMultiValueConverter eingebunden werden, das u.a. folgende Convert-Methode vorschreibt:


  
       1: public object Convert(object[] values, Type targetType, object parameter, System.Globalization.CultureInfo culture)


       2: {


       3:     object itemValue = values[0];


       4:     var source = values[1] as ListView;


       5:     int count = -1;


       6:     if (itemValue != null &amp;&amp; source != null)


       7:     {


       8:         count = 0;


       9:         foreach (var item in source.ItemsSource)


      10:         {


      11:             count++;


      12:             if (itemValue.Equals(item))


      13:                 break;


      14:         }


      15:     }


      16:     return count.ToString();


      17: }



In der Convert-Methode wird nun über jedes Element der ListView iteriert und wenn das gerade zu bindende Element gleich dem Element der ItemsSource ist wird die Iteration abgebrochen.&#160; Der Zähler, der mit jeder Iteration um eins hochgesetzt wird gibt also die Position des Elementes in der Listview wider.&#160; Diese Zahl (umgewandelt zu einem String) ist das Ergebnis der Convert Methode und wird in der ListView an entsprechender Stelle dargestellt.

Der Vergleich einString.Equals(einAndererString) liefert true zurück, wenn beide Strings den selben Inhalt haben, bei “normalen” Referenztypen sollte tatsächlich ein Vergleich auf Objektgleichheit durchgeführt werden!!

Das Projekt zum Downloaden und Ausprobieren findet sich hier:

http://cid-fd4d63530af59c99.skydrive.live.com/self.aspx/.Public/Projekte/WPF/LineNumbers.zip</description>
			<link>http://blogs.ppedv.de/felixr/archive/Zeilennummern-in-WPF-ListView-anzeigen</link>
			<author>Felix Ruthenberg </author>
			<pubDate>Wed, 21 Oct 2009 14:29:50 GMT</pubDate>
			<category domain="http://blogs.ppedv.de?tag=">
			.Net</category><category>C#</category><category>WPF</category><category>XAML</category><category>
			</category>
			
		</item>
	
		<item>
			<title>[Felix Ruthenberg] Visual Studio ASP.NET Designer funktioniert nach Neuinstallation auf Win7 nicht mehr</title>
			<description>Von diesem Problem muss ich berichten, weil es mich beinahe zwei Tage gekostet&#160; hat, und die Informationen dazu im Netz eher spärlich sind.  Ich habe vor ca. zwei Wochen mein Notebook neu aufgesetzt mit Windows 7, Visual Studio 2008 SP1 und allem was dazu gehört (dachte ich zumindest).  Alles funktionierte auch soweit bis auf das Öffnen einer WebForm im Designer.&#160; Sobald ich von SourceView auf Split- bzw. DesignView wechselte starb Visual Studio, so dass nur abschießen über den Task-Manager übrig blieb.&#160; Keine Fehlermeldung oder sonst eine Regung.  Das Problem mit dem Designer liegt nun daran, dass er gar nicht mit installiert wurde, bei der Installation von Visual Studio.&#160; Das lässt sich aber nachträglich beheben, und zwar mit der Visual Studio Installations CD.&#160; Im Pfad “WCU&quot;WebDesignerCore” befindet sich das Installationsprogramm für den Designer “WebDesignerCore”, diese Applikation einmal ausgeführt (die Installation passiert ohne GUI im Hintergrund) und schon geht alles wieder wie gewohnt.  Fazit, wenn Visual Studio einfriert beim Wechseln in die Design-Ansicht, einfach den Designer manuell installieren.</description>
			<link>http://blogs.ppedv.de/felixr/archive/Visual-Studio-ASP.NET-Designer-funktioniert-nach-Neuinstallation-auf-Win7-nicht-mehr</link>
			<author>Felix Ruthenberg </author>
			<pubDate>Wed, 09 Sep 2009 09:51:07 GMT</pubDate>
			<category domain="http://blogs.ppedv.de?tag=">
			
			</category>
			
		</item>
	
		<item>
			<title>[Felix Ruthenberg] Das Inherits Attribut in ASP.NET</title>
			<description>Seit ASP.NET 2.0 hat sich das code-behind Modell gegenüber der Version 1.1 in einigen Punkten signifikant geändert.&#160; Ein Beispiel dafür ist das neue Inherits Attribut in der Page Direktive.  Das Inherits Attribut zeigt die Verbindung der aspx mit der aspx.cs (bzw. aspx.vb) Datei als eine Klasse an.&#160; Das bedeutet, dass der Inhalt der Klassendefinition in der code-behind Datei und der Inhalt der aspx definition in einer (!) Klasse resultieren.&#160; Mit Vererbung hat das hier also relativ wenig zu tun.  Diese eine Klasse wird allerdings vom ASP.NET Parser als Basisklasse einer weiteren Klasse genutzt, die intern erzeugt wird.&#160; Diese automatisch generierte Klasse enthält alle Informationen, die zum Ausführen der Seite wichtig sind.&#160; Das sind zum Beispiel alle Texte, die in der aspx Form stehen, aber nicht vom Server direkt interpretiert werden müssen sowie das Aufrufen interner Methoden wie zum Beispiel DataBind und Render.  Im Normalfall müssen sich Entwickler keine Gedanken machen um die Vererbungsreihenfolge von ASP.NET Web Forms.&#160; Das dynamische Erstellen von User Controls kann hierdurch allerdings problematisch werden, einen Workaround und weitere Hinweise zur Page Verbung in ASP.NET beschreibt Rick Stahl in seinem Blog auf http://www.west-wind.com/Weblog/posts/3016.aspx</description>
			<link>http://blogs.ppedv.de/felixr/archive/Das-Inherits-Attribut-in-ASP.NET</link>
			<author>Felix Ruthenberg </author>
			<pubDate>Fri, 31 Jul 2009 11:21:26 GMT</pubDate>
			<category domain="http://blogs.ppedv.de?tag=">
			.Net</category><category>ASP.NET</category><category>
			</category>
			
		</item>
	
		<item>
			<title>[Felix Ruthenberg] ASP.NET Session ber mehrere Anwendungen verwenden</title>
			<description>Gestern kam eine interessante Kundenanfrage, bezüglich ASP.NET Sessions:     Wir haben drei verschiedene Web-Anwendungen auf einem Webserver und man soll aus den drei vorhanden Anwendungen auf die Session-Objekte einer übergeordneten Anwendung zugreifen können!   Mein erster Gedanke war, dass die Session nicht im Arbeitsspeicher gehalten werden kann, da der Scope des Session Objekts in ASP.NET standardmäßig auf die Anwendung UND den aktuellen Benutzer beschränkt ist.&#160; Eine (eher noch unklare) Absicht war also die Session in eine (SQL) Datenbank auszulagern.&#160; Das geht mit Hilfe des aspnet_regsql Tools relativ gut.  Aber auch im SqlServer Mode des sessionstate Eintrages der web.config gilt der Scope der Session wie oben beschrieben und man kann nicht anwendungsübergreifend auf das Sessionobjekt zugreifen.  &lt;sessionState mode=&quot;SQLServer&quot; cookieless=&quot;false&quot; sqlConnectionString=&quot;data source=vista-felixr&quot;sqlexpress;Integrated Security=True;Application Name=Test&quot;/&gt;

Der große Trick besteht nun darin den Stored Procedures, die von ASP.NET im Hintergrund aufgerufen werden um die Sessions zu verwalten, vorzumachen es würde sich jeweils um die gleiche Anwendung handeln.

Wie das ganz genau funktioniert hat Alex Cuse in seinem Blog festgehalten:

http://blogs.lessthandot.com/index.php/WebDev/ServerProgramming/ASPNET/sharing-asp-net-session-state-between-we

Er benutzt allerdings ein ASP.NET MVC Applikation, die für manche vielleicht etwas gewöhnungsbedürftig sein könnte.&#160; Ich habe die Anwendung auf’s simpelste reduziert und hochgeladen auf:

http://cid-fd4d63530af59c99.skydrive.live.com/self.aspx/.Public/Projekte/ASP.NET/Sharing%20Session%20between%20Applications.zip

Zur Zusammenfassung nochmal die “high-level” Schritte, wie ich vorgegangen bin

1) Zwei Websites erstellen (Website1 speichert Session, Website2 versucht sie auszulesen)

2) Mit aspnet_regsql Session Management im SQL Server aktivieren (genaue Parameter im Blog oben)

3) sessionstate in der web.config auf mode=”SqlServer” und Application Name=”Test”&#160; (auch im Blog beschrieben)

4) Änderung an der Stored Procedure wie im Text beschrieben (man muss nur genau lesen was zu tun ist!)

4) Websites als Anwendungen im lokalen IIS erstellen und laufen lassen (durch verschiedene Ports die vom internen Visual Studio Server generiert werden kann es vorkommen, dass eine neue SessionID angelegt wird für den Zugriff auf die 2. Anwendung, dann gibt es natürlich auch immer ein neues Session Objekt!)</description>
			<link>http://blogs.ppedv.de/felixr/archive/ASP.NET-Session-uumlber-mehrere-Anwendungen-verwenden</link>
			<author>Felix Ruthenberg </author>
			<pubDate>Tue, 14 Jul 2009 16:41:15 GMT</pubDate>
			<category domain="http://blogs.ppedv.de?tag=">
			
			</category>
			
		</item>
	
		<item>
			<title>[Felix Ruthenberg] Dynamisches Ribbon Menu in VSTO</title>
			<description>Auch wenn es trivial erscheint, mir hat es eben ein paar graue Zellen gekostet auf die Lösung zu kommen:  In VSTO habe ich ein neues Ribbon erzeugt und in dem Ribbon ein Menu abgelegt.&#160; Das Menu soll sich mit Informationen aus einer Datenbank dynamisch füllen.  Dazu erzeuge ich für jeden Eintrag einen RibbonButton, der zur Items Collection des Menus hinzugefügt wird.&#160; Beim Ausführen der Zeile   Menu1.Items.Add(btn)

Wird allerdings eine Exception geworfen, die Items Collection ist read-only.&#160; (Das sagt übrigens auch Intellisense, wenn man genau hinschaut).

Die Lösung des Problems ist die Bool-Eigenschaft Dynamic am Menu selbst.&#160; Mit dieser Eigenschaft auf True gesetzt lässt sich das Menu programmatisch auffüllen.</description>
			<link>http://blogs.ppedv.de/felixr/archive/Dynamisches-Ribbon-Menu-in-VSTO</link>
			<author>Felix Ruthenberg </author>
			<pubDate>Tue, 14 Jul 2009 16:00:30 GMT</pubDate>
			<category domain="http://blogs.ppedv.de?tag=">
			.Net</category><category>C#</category><category>VSTO</category><category>VB</category><category>
			</category>
			
		</item>
	
		<item>
			<title>[Felix Ruthenberg] Gruppierungsberschrift in WPF ListBox anzeigen</title>
			<description>Das Anbinden von Daten (aus einer Datenbank zum Beispiel) in eine WPF Listbox geschieht am besten über ein CollectionViewSource Control deklarativ in XAML.&#160; Die CollectionViewSource hat den Vorteil, dass an ihr Filter, Sortierungen und Gruppierungen angewandt werden können, die direkt in der ListBox sichtbar werden.  Bei der Gruppierung ist es nun auch möglich sich die Gruppenüberschriften in der ListBox darstellen zu lassen, siehe hier (klicken zum Vergrößern):    Das Gruppieren ist im Check-Event der CheckBox mit diesen Zeilen Code eingestellt und angewandt:  private void CheckBoxGroupBy_Checked(object sender, RoutedEventArgs e)
{
  PropertyGroupDescription gd = new PropertyGroupDescription(&quot;Country&quot;);
  CustomerViewSource.GroupDescriptions.Add(gd);
}

[Hinweis, die CustomerViewSource Eigenschaft ist eine Eigenschaft des Windows und dort folgendermaßen deklariert:

public CollectionViewSource CustomerViewSource
{
  get
  {
    return this.Resources[&quot;CustomersViewSource&quot;] as CollectionViewSource;
  }
}

Sie gibt also die CollectionViewSource, die in den Resourcen definiert ist, zurück! ]

Die ListBox selbst hat ein GroupStyle Template in dem ein TextBlock definiert ist, der die jeweilige Gruppenüberschrift darstellen soll.&#160; Die eigentliche Information (Country in diesem Fall) lässt sich einfach über den Path=Name im DataTemplate abfragen, Code-Beispiel siehe hier:

&lt;ListBox Name=&quot;lstbxCustomers&quot;
  ItemsSource=&quot;{Binding Source={StaticResource CustomersViewSource}}&quot;&gt;
  &lt;ListBox.GroupStyle&gt;
    &lt;GroupStyle&gt;
      &lt;GroupStyle.HeaderTemplate&gt;
        &lt;DataTemplate&gt;
          &lt;TextBlock Text=&quot;{Binding Path=Name}&quot; /&gt;
        &lt;/DataTemplate&gt;
      &lt;/GroupStyle.HeaderTemplate&gt;
    &lt;/GroupStyle&gt;
  &lt;/ListBox.GroupStyle&gt;
  &lt;ListBox.ItemTemplate&gt;
        &lt;!-- ... --&gt;
  &lt;/ListBox.ItemTemplate&gt;
&lt;/ListBox&gt;

Dieses Beispiel steht unter http://cid-fd4d63530af59c99.skydrive.live.com/browse.aspx/.Public/Projekte/WPF?uc=1&amp;isFromRichUpload=1 zur Verfügung!</description>
			<link>http://blogs.ppedv.de/felixr/archive/Gruppierungsuumlberschrift-in-WPF-ListBox-anzeigen</link>
			<author>Felix Ruthenberg </author>
			<pubDate>Fri, 03 Jul 2009 16:49:09 GMT</pubDate>
			<category domain="http://blogs.ppedv.de?tag=">
			
			</category>
			
		</item>
	
		<item>
			<title>[Felix Ruthenberg] WPF Error Template bei der Validierung</title>
			<description>WPF bietet die Möglichkeit beim DataBind Validierung durchzuführen, dazu muss als erstes eine Klasse erstellt werden, die die Validierung durchführt.&#160; Die eigene Validierungsklasse ist abgeleitet von ValidationRule und überschreibt die Methode Validate wie im CodeSnippet gezeigt:      class NotANumberValidationRule : ValidationRule
    {
        public override ValidationResult Validate(object value, System.Globalization.CultureInfo cultureInfo)
        {
            double d;
            if (double.TryParse(value.ToString(), out d))
                return ValidationResult.ValidResult;
            else return new ValidationResult(false, &quot;Keine Zahl eingegeben&quot;);
        }
    }

Im XAML kann als DataBind Eigenschaft ValidationRules die ValidationRule angegeben werden:

&lt;Binding ElementName=&quot;txtbxDivision&quot; Path=&quot;Text&quot; 
  Converter=&quot;{StaticResource divideBy2Converter}&quot;
  UpdateSourceTrigger=&quot;PropertyChanged&quot;&gt;
  &lt;Binding.ValidationRules&gt;
  &lt;local:NotANumberValidationRule /&gt;
  &lt;/Binding.ValidationRules&gt;
&lt;/Binding&gt;

An dem Control an dem die Daten gebunden werden, kann zu dem ein ErrorTemplate definiert werden, das im Fehlerfall erscheint.&#160; Ist kein derartiges Template definiert wird automatisch ein dünner roter Rahmen um das Control gerendert.&#160; Die Überschreibung des Control Templates sind folgendermaßen aus:

&lt;ControlTemplate x:Key=&quot;errorTemplate&quot;&gt;


  &lt;DockPanel LastChildFill=&quot;True&quot;&gt;


    &lt;TextBlock DockPanel.Dock=&quot;Right&quot; 


                        Foreground=&quot;Red&quot;


                        FontSize=&quot;12pt&quot;&gt;


                        Fehler


    &lt;/TextBlock&gt;


    &lt;Border BorderBrush=&quot;Red&quot; BorderThickness=&quot;1&quot;&gt;


      &lt;AdornedElementPlaceholder /&gt;


    &lt;/Border&gt;


  &lt;/DockPanel&gt;


&lt;/ControlTemplate&gt;

Dabei steht der &lt;AdornedElementPlaceholder /&gt; als Platzhalter für das Element, das mit der Fehlermeldung markiert sein soll.&#160; Um dem zu validierenden Element das Template zuzuweisen muss die Validation.ErrorTemplate Eigenschaft angesprochen werden.&#160; Über Property Trigger können zudem noch weitere Aktionen angeworfen werden (siehe textBoxStyle).

Hier also das Anlegen der TextBox:

&lt;TextBox Name=&quot;txtbxNumber&quot; Validation.ErrorTemplate=&quot;{StaticResource errorTemplate}&quot; Style=&quot;{StaticResource textBoxStyle}&quot; &gt;
  &lt;Binding&gt;
    &lt;!-- Hier kommt das Binding wie oben beschrieben rein --&gt;
  &lt;/Binding&gt;
&lt;/TextBox&gt;

Und der dazugehörige Style:

&lt;Style x:Key=&quot;textBoxStyle&quot; TargetType=&quot;{x:Type TextBox}&quot;&gt;
  &lt;Style.Triggers&gt;
    &lt;Trigger Property=&quot;Validation.HasError&quot; Value=&quot;true&quot;&gt;
      &lt;Setter Property=&quot;ToolTip&quot; Value=&quot;{Binding RelativeSource={RelativeSource Self},
          Path=(Validation.Errors)[0].ErrorContent}&quot; /&gt;
    &lt;/Trigger&gt;
  &lt;/Style.Triggers&gt;
&lt;/Style&gt;

Die Bindung Value=&quot;{Binding RelativeSource={RelativeSource Self}, Path=(Validation.Errors)[0].ErrorContent}&quot; Holt die Validierungsfehlermessage aus der Validierungsklasse und zeigt sie im Tooltip der TextBox an.

Das Projekt (inklusive Konvertierungsbeispiel) kann heruntergeladen werden von:&#160; http://cid-fd4d63530af59c99.skydrive.live.com/self.aspx/.Public/Projekte/WPF/Validierung.zip</description>
			<link>http://blogs.ppedv.de/felixr/archive/WPF-Error-Template-bei-der-Validierung</link>
			<author>Felix Ruthenberg </author>
			<pubDate>Fri, 03 Jul 2009 16:26:53 GMT</pubDate>
			<category domain="http://blogs.ppedv.de?tag=">
			.Net</category><category>XAML</category><category>C#</category><category>WPF</category><category>
			</category>
			
		</item>
	
		<item>
			<title>[Felix Ruthenberg] Asynchrones Verarbeiten von WinFormEvents (Ein Beispiel)</title>
			<description>Problemstellung:    Eine Textbox soll zyklisch alle 2 Sekunden mit der aktuellen Uhrzeit gefüllt werden.&#160; Dieser Prozess soll als Worker Thread im Hintergrund laufen, damit andere Threads (zum Beispiel das UI) nicht weiter davon betroffen sind.&#160; Außerdem soll es möglich sein über einen Button weitere Zeilen in die Textbox einzufügen ohne dabei Threadverletzungen zu Riskieren.  Lösungsansatz:     Während der Ausführung des Asynchronen Threads kann die Invoke Methode der Form aufgerufen werden, die eine kurze Anweisung aus dem Worker Prozess übernimmt und ausführt.&#160; Diese kurze Anweisung besteht aus dem Setzen des neuen Textes und wird somit für das Control im Main Thread ausgeführt.&#160; Mit Hilfe dieser Vorgehensweise lassen sich also langwierige Berechnungen auslagern und aus diesem asynchronen Teil heraus können Methoden, die den Main Thread benötigen (zum Beispiel weil auf Controls des Mail Threads zugegriffen werden soll) weiterhin auf diesem ausgeführt werden.  Das Beispiel:    Im Beispiel Projekt ist eine TextBox (txtbxResult), sowie drei Buttons (btnStart, btnStop und btnInterfere) instanziiert.&#160; Außerdem gibt es auf Klassenebene eine Delegatdefinition (delegateWriteText), die eine Methodensignatur ohne Rückgabewert aber mit einem string Parameter definiert sowie ein boolscher Bezeichner asynchOn und ein Thread Bezeichner mit Namen t.  Starten des Asynchronen Threads:    Beim Erstellen des neuen Threads kann die auszuführende Funktion übergeben werden.&#160; Außerdem wird das asynchOn Flag gesetzt um anzuzeigen, dass der asynchrone Prozess läuft.  private void btnStart_Click(object sender, EventArgs e)
{
  asynchOn = true;
  btnStart.Enabled = false;
  t = new Thread(WriteTextAsynch);
  t.Start();
}

.csharpcode, .csharpcode pre
{
	font-size: small;
	color: black;
	font-family: consolas, "Courier New", courier, monospace;
	background-color: #ffffff;
	/*white-space: pre;*/
}
.csharpcode pre { margin: 0em; }
.csharpcode .rem { color: #008000; }
.csharpcode .kwrd { color: #0000ff; }
.csharpcode .str { color: #006080; }
.csharpcode .op { color: #0000c0; }
.csharpcode .preproc { color: #cc6633; }
.csharpcode .asp { background-color: #ffff00; }
.csharpcode .html { color: #800000; }
.csharpcode .attr { color: #ff0000; }
.csharpcode .alt 
{
	background-color: #f4f4f4;
	width: 100%;
	margin: 0em;
}
.csharpcode .lnum { color: #606060; }

Die asynchrone Methode:

  In einer while Schleife wird das asynchOn Flag geprüft und so lange ausgeführt wie dieses auf true steht.&#160; Dieses Verfahren hilft den asynchronen Thread durch simples Ändern des Flags zu beenden.&#160; Die Eigenschaft InvokeRequired gibt an ob das Control von dem derzeitgen Prozess angesprochen werden kann oder nicht.&#160; (In diesem Beispiel ist das nie der Fall, denn die Funktion wird nur vom asynchronen Thread aufgerufen, die Abfrage ist als hier redundant und nur zu Demozwecken angegeben.)&#160; Die Instanziierung des Delegaten zeigt auf die Synchrone WriteTextSynch Methode und wird zusammen mit einem Parameter (der entsprechende String) in der Invoke Methode der Form Übergeben.&#160; Die Invoke Methode sorgt dafür, dass die übergebene Delegat Methode im Main Thread ausgeführt wird.

private void WriteTextAsynch()
{
  delegateWriteText d = new delegateWriteText(WriteTextSynch);
  while (asynchOn)
  {
    if (txtbxResult.InvokeRequired)
    {
      this.Invoke(d, String.Format(&quot;Invoked Asynchronously at {0}{1}&quot;, DateTime.Now.ToLongTimeString(), Environment.NewLine));
    }
    Thread.Sleep(2000);
  }
}

Die synchrone Methode:

  Fügt den übergebenen Text an den Text in txtbxResult an

private void WriteTextSynch(string text)
{
  txtbxResult.Text += text;
}

Der Interfere Button:

  Hier kann die synchrone Methode einfach aufgerufen werden, denn auch die entsprechende ButtonClick Event Handler Methode wird im selben Thread ausgeführt, der auch den Button erstellt hat:

private void btnInterfere_Click(object sender, EventArgs e)
{
  WriteTextSynch(String.Format(&quot;Written Synchronously at {0}{1}&quot;, DateTime.Now.ToLongTimeString(), Environment.NewLine));
}

Der Stop Button:

  Setzt das Flag auf false und veranlasst so die asynchrone Methode die Ausführung zu beenden.

private void btnStop_Click(object sender, EventArgs e)
{
  btnStart.Enabled = true;
  asynchOn = false;
}

Der Quellcode:
    Das Beispiel kann heruntergeladen werden von:

  http://cid-fd4d63530af59c99.skydrive.live.com/self.aspx/.Public/Asynch.zip

.csharpcode, .csharpcode pre
{
	font-size: small;
	color: black;
	font-family: consolas, "Courier New", courier, monospace;
	background-color: #ffffff;
	/*white-space: pre;*/
}
.csharpcode pre { margin: 0em; }
.csharpcode .rem { color: #008000; }
.csharpcode .kwrd { color: #0000ff; }
.csharpcode .str { color: #006080; }
.csharpcode .op { color: #0000c0; }
.csharpcode .preproc { color: #cc6633; }
.csharpcode .asp { background-color: #ffff00; }
.csharpcode .html { color: #800000; }
.csharpcode .attr { color: #ff0000; }
.csharpcode .alt 
{
	background-color: #f4f4f4;
	width: 100%;
	margin: 0em;
}
.csharpcode .lnum { color: #606060; }
.csharpcode, .csharpcode pre
{
	font-size: small;
	color: black;
	font-family: consolas, "Courier New", courier, monospace;
	background-color: #ffffff;
	/*white-space: pre;*/
}
.csharpcode pre { margin: 0em; }
.csharpcode .rem { color: #008000; }
.csharpcode .kwrd { color: #0000ff; }
.csharpcode .str { color: #006080; }
.csharpcode .op { color: #0000c0; }
.csharpcode .preproc { color: #cc6633; }
.csharpcode .asp { background-color: #ffff00; }
.csharpcode .html { color: #800000; }
.csharpcode .attr { color: #ff0000; }
.csharpcode .alt 
{
	background-color: #f4f4f4;
	width: 100%;
	margin: 0em;
}
.csharpcode .lnum { color: #606060; }</description>
			<link>http://blogs.ppedv.de/felixr/archive/Asynchrones-Verarbeiten-von-WinFormEvents-Ein-Beispiel</link>
			<author>Felix Ruthenberg </author>
			<pubDate>Fri, 03 Apr 2009 12:59:49 GMT</pubDate>
			<category domain="http://blogs.ppedv.de?tag=">
			C#</category><category>.Net</category><category>
			</category>
			
		</item>
	
		<item>
			<title>[Felix Ruthenberg] Verschieben von Controls via Drag  Drop in WinForms Anwendungen</title>
			<description>Problem:      Ähnlich unserer beliebten IDE soll es möglich sein Controls, die auf unserer Form platziert wurden mit Drag &amp; Drop zu verschieben und so auf eine neue Stelle in unserer WinForm abzulegen.  Beispiel:      In dem Beispiel, das hier beschrieben ist geht es darum Buttons anzupacken und auf der Form an neuer Stelle abzulegen.&#160; Dazu müssen mehrere Events des Buttons abgefragt werden wie folgt beschrieben.  Built-In Drag and Drop Funktionalität:     Auch wenn es verlockend klingt, aber was man allgemein unter Drag&amp;Drop versteht hat nichts mit der Verschiebung von Controls zu tun.&#160; Beim klassischen Drag&amp;Drop geht es vielmehr darum Objekte aus einem Control zu entnehmen (oder auch das Control selbst) und dieses in einem anderen Control wieder fallen zu lassen.&#160; Zur Demonstration dieser Funktionalität ist die Beispiel-Form zweigeteilt, im unteren Bereich enthält sie ein FlowLayoutPanel, dass Elemente vom Typ Button aufnehmen kann.&#160; Die Vorgehensweise dazu ist weiter unten beschrieben.  Verschieben von Controls auf der Form:      Prinzipielle Vorgehensweise:     Im MouseMove Event wird die aktuelle Position des Mauszeigers abgefragt und die Location des Controls daraufhin geändert.     Problem:     Die MouseEventArgs geben nur die aktuelle Position der Maus innerhalb des Buttons wieder, wichtig ist allerdings die Position der Maus auf der Form.&#160; Außerdem muss ein Offset beachtet werden, der die Position der Maus innerhalb des Buttons berücksichtigt, denn sonst würde beim Zuweisen der neuen Button-Location das Control immer am Mauszeiger “kleben”.     Lösung:     Mit Hilfe der Methode Control.PointToScreen(Point p) lässt sich für jede Position innerhalb eines Controls (und auch der Form selbst) die absolute Bildschirmkoordinate berechnen.&#160; (Das beutet, dass man in die PointToScreen Methode des Controls eine Koordinate relativ zur linken oberen Ecke des Controls eintragen kann und man bekommt den Wert der Koordinate zurück, die sich rechnerisch aus der Distanz vom linken oberen Bildschirmrand und der angegeben Koordinate errechnet.)&#160; Die Idee ist nun vor dem Verschieben (also beim MouseDown Event) die derzeitige Position der Form zu merken.&#160; Genauer gesagt wird ein virtueller Punkt berechnet, der sich aus der Position der Form und der aktuellen Position des Mauszeigers innerhalb des Buttons ergibt.&#160; Das ist der rote Punkt im Tafelbild.&#160; Der Code dazu ist hier zu sehen:  private void btn_MouseDown(object sender, MouseEventArgs e)
{
  Button btn = sender as Button;
  ptStartPosition = this.PointToScreen(e.Location);
}

Beim Verschieben der Maus muss nun also die neue Koordinate berechnet werden, die angibt welche Position der Button in der Form einnehmen soll.&#160; Der Wert ergibt sich aus der aktuellen Mausposition (natürlich wieder vom Bildschrimrand) minus dem zuvor errechneten virtuellen Punkt:

private void btn_MouseMove(object sender, MouseEventArgs e)
{
  Point ptEndPosition = btn.PointToScreen(e.Location);
  ptEndPosition.Offset(-ptStartPosition.X, -ptStartPosition.Y);
  btn.Location = ptEndPosition;
}

Damit sind alle Berechnung abgeschlossen und das Control kann einfach verschoben werden.

Fazit: 

  Viel Gedanken für ein bisschen Code, manchmal ist das halt so!

Das Tafelbild zum Artikel:

 


.csharpcode, .csharpcode pre
{
	font-size: small;
	color: black;
	font-family: consolas, "Courier New", courier, monospace;
	background-color: #ffffff;
	/*white-space: pre;*/
}
.csharpcode pre { margin: 0em; }
.csharpcode .rem { color: #008000; }
.csharpcode .kwrd { color: #0000ff; }
.csharpcode .str { color: #006080; }
.csharpcode .op { color: #0000c0; }
.csharpcode .preproc { color: #cc6633; }
.csharpcode .asp { background-color: #ffff00; }
.csharpcode .html { color: #800000; }
.csharpcode .attr { color: #ff0000; }
.csharpcode .alt 
{
	background-color: #f4f4f4;
	width: 100%;
	margin: 0em;
}
.csharpcode .lnum { color: #606060; }

.csharpcode, .csharpcode pre
{
	font-size: small;
	color: black;
	font-family: consolas, "Courier New", courier, monospace;
	background-color: #ffffff;
	/*white-space: pre;*/
}
.csharpcode pre { margin: 0em; }
.csharpcode .rem { color: #008000; }
.csharpcode .kwrd { color: #0000ff; }
.csharpcode .str { color: #006080; }
.csharpcode .op { color: #0000c0; }
.csharpcode .preproc { color: #cc6633; }
.csharpcode .asp { background-color: #ffff00; }
.csharpcode .html { color: #800000; }
.csharpcode .attr { color: #ff0000; }
.csharpcode .alt 
{
	background-color: #f4f4f4;
	width: 100%;
	margin: 0em;
}
.csharpcode .lnum { color: #606060; }



Nutzen der Drag&amp;Drop Funktionalität:
    Im Beispiel, das hier verwendet wird, ist neben dem Verschieben der Controls eine Drag&amp;Drop Funktionalität eingebaut, die folgendermaßen aufgebaut ist:

Beim Ziehen eines Buttons (mit der linken Maustaste) soll es möglich sein, diesen Button dem FlowLayoutPanel im unteren Bildschirmbereich hinzuzufügen.&#160; Dazu werden drei Events und ein Property benötigt:

Das FlowLayoutPanel (flowLayoutPanel1) muss in der Eigenschaft AllowDrop auf true gesetzt werden.

Im MouseDownEvent des entsprechenden Buttons muss die DoDragDrop Methode aufgerufen werden.&#160; In ihr muss außerdem spezifiziert werden welche DragDrop Aktionen möglich sind.

private void btn_MouseDown(object sender, MouseEventArgs e)
{
  Button btn = sender as Button;
  btn.DoDragDrop(btn, DragDropEffects.Move);
}

Im DragEnter Event des flowLayoutPanel1 muss nun abgeprüft werden ob ein bekanntes Element hineingezogen wurde und der entsprechende DragDropEffekt angewandt werden:

private void flowLayoutPanel1_DragEnter(object sender, DragEventArgs e)
{
  if (e.Data.GetDataPresent(typeof(Button)))
    e.Effect = DragDropEffects.Move;
  else
    e.Effect = DragDropEffects.None;
}

Zu guter letzt führt das DragDrop Event des flowLayoutPanel1 die eigentliche Verschiebung des Buttons durch.&#160; Dazu wird der Button von der Form gelöst und dem flowLayoutPanel1 hinzugefügt:

private void flowLayoutPanel1_DragDrop(object sender, DragEventArgs e)
{
  Button btn = e.Data.GetData(typeof(Button)) as Button;
  flowLayoutPanel1.Controls.Add(btn);
  this.Controls.Remove(btn);
}

.csharpcode, .csharpcode pre
{
	font-size: small;
	color: black;
	font-family: consolas, "Courier New", courier, monospace;
	background-color: #ffffff;
	/*white-space: pre;*/
}
.csharpcode pre { margin: 0em; }
.csharpcode .rem { color: #008000; }
.csharpcode .kwrd { color: #0000ff; }
.csharpcode .str { color: #006080; }
.csharpcode .op { color: #0000c0; }
.csharpcode .preproc { color: #cc6633; }
.csharpcode .asp { background-color: #ffff00; }
.csharpcode .html { color: #800000; }
.csharpcode .attr { color: #ff0000; }
.csharpcode .alt 
{
	background-color: #f4f4f4;
	width: 100%;
	margin: 0em;
}
.csharpcode .lnum { color: #606060; }

Quellcode:

  Das ganze kann zum Nachvollziehen und Ausprobieren hier heruntergeladen werden:

  http://cid-fd4d63530af59c99.skydrive.live.com/self.aspx/.Public/DragAndDrop.zip</description>
			<link>http://blogs.ppedv.de/felixr/archive/Verschieben-von-Controls-via-Drag-amp-Drop-in-WinForms-Anwendungen</link>
			<author>Felix Ruthenberg </author>
			<pubDate>Fri, 03 Apr 2009 11:40:51 GMT</pubDate>
			<category domain="http://blogs.ppedv.de?tag=">
			.Net</category><category>C#</category><category>Windows</category><category>
			</category>
			
		</item>
	
		<item>
			<title>[Felix Ruthenberg] Kaskadierendes Setzen von WebControls aus Stautsinformationen</title>
			<description>Problem:     In Web Anwendung kann es notwendig sein ListBound Controls einer Seite dynamisch nach einem vorher gespeicherten Muster wieder aufzubauen.&#160; Solange sich der Benutzer auf einer Seite bewegt speichert ASP.NET solche Informationen im Viewstate ab, sobald man allerdings zwischen verschiedenen Seiten navigiert ist auch diese Information verloren.&#160; (Anmerkung:&#160; Wenn mit   Server.Transfer(string path, bool preserveForm);


.csharpcode, .csharpcode pre
{
	font-size: small;
	color: black;
	font-family: consolas, "Courier New", courier, monospace;
	background-color: #ffffff;
	/*white-space: pre;*/
}
.csharpcode pre { margin: 0em; }
.csharpcode .rem { color: #008000; }
.csharpcode .kwrd { color: #0000ff; }
.csharpcode .str { color: #006080; }
.csharpcode .op { color: #0000c0; }
.csharpcode .preproc { color: #cc6633; }
.csharpcode .asp { background-color: #ffff00; }
.csharpcode .html { color: #800000; }
.csharpcode .attr { color: #ff0000; }
.csharpcode .alt 
{
	background-color: #f4f4f4;
	width: 100%;
	margin: 0em;
}
.csharpcode .lnum { color: #606060; }

auf dem Server navigiert wird kann der Formstatus, also auch der Viewstate an die nächste Seite übergeben werden, preserveForm=true.&#160; In diesem Artikel sollen allerdings die Möglichkeiten der seitenübergreifenden Statusverwaltung benutzt werden).



Beispiel: 

  Das Beispiel an dem dieser Artikel sich orientiert ist eine Datanbank mit 3 Tabellen, die folgendermaßen aufgebaut sind:

Genres:


    
      Spaltenname

      Typ

      Beschreibung
    

    
      GenreId

      int, Primary, NotNull

      Key für das Genre
    

    
      GenreName

      nvarchar(50)

      Name des Genres
    
  

Series:


    
      Spaltenname

      Typ

      Beschreibung
    

    
      SeriesId

      int, Primary, NotNull

      Key für die Serie
    

    
      SeriesName

      nvarchar(50)

      Name der Serie
    

    
      GenreId

      int, NotNull

      Fremdschlüssel aus Genres
    
  

Characters:


    
      Spaltenname

      Typ

      Beschreibung
    

    
      CharacterId

      int, Primary, NotNull

      Key für den Rollencharakter
    

    
      CharacterName

      nvarchar(50)

      Name des Rollencharakters
    

    
      DubberName

      nvarchar(50)

      Name des deutschen Synchronsprechers
    

    
      SeriesId

      int, NotNull

      Fremdschlüssel aus Series
    
  



Szenario: 

  Der Benutzer einer Webanwendung wählt aus zwei ListBound Controls (Dropdown-Listen) Filter aus, auf die sich eine darunter liegende GridView (grdvwCharactersTable) bezieht.&#160; Dabei regelt die erste DropDown-List (ddlstGenres) den Inhalt der zweiten DropDown-List (ddlstSeries).&#160; Jede Dropdown-List ist dafür mit einer eigenen SqlDataSource (sqldtsrcDdlstGenres um ddlstGenres mit den Werten aus Genres zu befüllen, respektive sqldtsrcDdlstSeries um ddlstSeries mit den Werten aus Series zu befüllen) verbunden.&#160; Die Datenquelle sqldtsrcDdlstSeries&#160; verwendet als Where Paramter den momentan gesetzten Wert von ddlstGenre um nur Serien eines bestimmten Genres anzuzeigen.&#160; Ebenso ist die Where Bedinung der Datenquelle der Gridview (grdvwCharactersTable) an das Control ddlstSeries geknüpft.

Wenn der Benutzer nun Werte in den DropDown Listen ändert, die Seite verlässt und wieder zurückkehrt sind alle DropDown-Listen und die GridView wieder in ihrem Ursprungszustand.&#160; Dieser Effekt soll umgangen werden, der Status seit dem Verlassen der Seite muss wieder hergestellt sein. 
  

Lösung:

Beim Verlassen der Seite muss darauf geachtet werden, die Statusinformationen (Werte der Dropdown-Listen) für den aktuellen Benutzer zu speichern.&#160; Hierzu bittet sich das ASP.NET Session Objekt an.&#160; Im Click Event des LinkButtons, der die Seite verlässt, wird dazu erst ein Dictionary Objekt erzeugt, das die aktuellen Werte beider DropDown-Listen enthält und das dann zur Session gespeichert werden kann.

protected void LinkButton1_Click(object sender, EventArgs e)
{
  Dictionary&lt;string, string&gt; dictState = new Dictionary&lt;string, string&gt;
  {
    {&quot;GenreId&quot;, ddlstGenres.SelectedValue},
    {&quot;SeriesId&quot;, ddlstSeries.SelectedValue}
  };
  Session[&quot;State&quot;] = dictState;
  Response.Redirect(@&quot;~&quot;Default2.aspx&quot;);
}

Beim wiederholten Laden der Seite muss also erst geprüft werden ob die Session vorhanden ist.&#160; Ist das der Fall kann das Dictionary wieder neu aufgebaut werden.&#160; Nun ist es wichtig die Reihenfolge beim Wiederherstellen des Statuses zu beachten:

protected void Page_Load(object sender, EventArgs e)
{
  if (Session[&quot;State&quot;] != null)
  {
    Dictionary&lt;string, string&gt; dictState = (Dictionary&lt;string, string&gt;)Session[&quot;State&quot;];
    ddlstGenres.DataBind();
    ddlstGenres.Items.FindByValue(dictState[&quot;GenreId&quot;]).Selected = true;
    ddlstSeries.DataBind();
    ddlstSeries.Items.FindByValue(dictState[&quot;SeriesId&quot;]).Selected = true;
    Session[&quot;State&quot;] = null;
  }
}

.csharpcode, .csharpcode pre
{
	font-size: small;
	color: black;
	font-family: consolas, "Courier New", courier, monospace;
	background-color: #ffffff;
	/*white-space: pre;*/
}
.csharpcode pre { margin: 0em; }
.csharpcode .rem { color: #008000; }
.csharpcode .kwrd { color: #0000ff; }
.csharpcode .str { color: #006080; }
.csharpcode .op { color: #0000c0; }
.csharpcode .preproc { color: #cc6633; }
.csharpcode .asp { background-color: #ffff00; }
.csharpcode .html { color: #800000; }
.csharpcode .attr { color: #ff0000; }
.csharpcode .alt 
{
	background-color: #f4f4f4;
	width: 100%;
	margin: 0em;
}
.csharpcode .lnum { color: #606060; }


  Zuerst muss die ddlstGenres ein DataBind ausführen, damit die ListItem Collection bekannt wird, die für dieses Control gilt.

  Das entsprechende ListItem muss als Selected gekennzeichnet werden.&#160; Dazu kann der Funktion FindByValue() der Wert aus dem Dictionary übergeben werden.

  Nachdem nun in der ersten DropDown-List der Wert wieder hergestellt wurde kann das DataBind an ddlstSeries ausgeführt werden (das sich ja auf diesen ersten Wert bezieht).

  Nun muss auch hier das ListItem gefunden werden das zuvor angewählt war um ihm dann den Selected=true Status zu verpassen.

  Die Session wird dann nicht mehr benötigt und muss auf null gesetzt werden (Der Viewstate kümmert sich ab sofort wieder um Änderungen, die auf der Seite statt finden)

  Anmerkung:&#160; Auch das GridView muss an dieser Stelle kein DataBind ausführen, das passiert automatisch im Page_PreRender Event des Page Life Cycles (Schaden wird es allerdings auch nicht).


Zur Verdeutlichung wann welche DataBind Funktionen aufgerufen werden wurden im Beipsiel Programm die entsprechenden DataBind und DataBound Events abgefangen und im Trace Output sichtbar gemacht.

Außerdem gibt es einen Bugfix, der in der Methode ddlstGenres_SelectedIndexChanged behandelt wird.&#160; Wenn sich das Genre ändert (bei Zugriff auf die gleiche Seite) muss auch die Series DropDown-List neu gebunden werden (damit aktualisiert sich dann auch das GridView):

protected void ddlstGenres_SelectedIndexChanged(object sender, EventArgs e)
{
  ddlstSeries.DataBind();
}

.csharpcode, .csharpcode pre
{
	font-size: small;
	color: black;
	font-family: consolas, "Courier New", courier, monospace;
	background-color: #ffffff;
	/*white-space: pre;*/
}
.csharpcode pre { margin: 0em; }
.csharpcode .rem { color: #008000; }
.csharpcode .kwrd { color: #0000ff; }
.csharpcode .str { color: #006080; }
.csharpcode .op { color: #0000c0; }
.csharpcode .preproc { color: #cc6633; }
.csharpcode .asp { background-color: #ffff00; }
.csharpcode .html { color: #800000; }
.csharpcode .attr { color: #ff0000; }
.csharpcode .alt 
{
	background-color: #f4f4f4;
	width: 100%;
	margin: 0em;
}
.csharpcode .lnum { color: #606060; }

Der Source Code zum Artikel kann hier runter geladen werden:

Demo zum Artikel</description>
			<link>http://blogs.ppedv.de/felixr/archive/Kaskadierendes-Setzen-von-WebControls-aus-Stautsinformationen</link>
			<author>Felix Ruthenberg </author>
			<pubDate>Thu, 26 Mar 2009 16:07:58 GMT</pubDate>
			<category domain="http://blogs.ppedv.de?tag=">
			
			</category>
			
		</item>
	
		<item>
			<title>[Felix Ruthenberg] Rckgabewerte von Programmen</title>
			<description>Wenn man einen Prozess aus einer Applikation heraus startet m&#246;chte man unter Umst&#228;nden nach Beendigung des &quot;Slave&quot; Programmes wissen, ob der Prozess erfolgreich beendet wurde, bzw. ob es Fehler gegeben hat.  Jeder Prozess gibt an seinen Host (das ist &#252;blicherweise das Betriebssystem, kann aber auch eine andere Applikation sein) einen Exit Code zur&#252;ck.&#160; Der Exit Code ist 0 bei erfolgreichem Beenden, oder gr&#246;&#223;er 0 im Fehlerfall.&#160; &#220;ber den Wert des Exit Codes kann bestimmt werden welcher Fehler eingetreten ist.  Zum Starten eines Prozesses aus einem anderen heraus muss zuerst ein ProcessStartInfo Objekt angelegt werden, das Informationen zu dem zu startenden Prozess enth&#228;lt.&#160; Nach dem Starten und Beenden des Slave Prozesses steht der Exit Code zur Verf&#252;gung und kann ausgelesen werden.  ProcessStartInfo processInfo = new System.Diagnostics.ProcessStartInfo(@&quot;..&quot;..&quot;..&quot;SlaveProgram&quot;bin&quot;Release&quot;SlaveProgram.exe&quot;);

// Ein neuer Prozess wird gestartet
Process p = Process.Start(processInfo);

// Der Exit Code kann nat&#252;rlich erst ausgelesen werden, wenn die aufgerufene
// Applikation beendet wurde.
p.WaitForExit();

// Auslesen des Exit Codes
switch (p.ExitCode)
{
    case 0:
        Console.WriteLine(&quot;Das Programm wurde ordnungsgem&#228;&#223; beendet. (Error Code 0)&quot;);
        break;
    default:
        Console.WriteLine(&quot;Das Programm wurde nicht ordnungsgem&#228;&#223; beendet. (Error Code {0})&quot;, p.ExitCode);
    break;
}

In der Slave Applikation gibt es zwei Wege den Exit Code zu setzen, als return value der Main Methode, oder &#252;ber Environment.Exit(int ExitCode).

Return Value:
  Ist die Main Methode also int definiert, also

static int Main(string[] args)
{  ... }

so kann (und muss) zum Beenden der Methode ein return value &#252;bergeben werden:

return i;

Es kann allerdings darauf verzichtet werden, die Signatur der Main Methode zu &#228;ndern und im Fehlerfall wird die Applikation &#252;ber

Environment.Exit(i);

geschlossen.&#160; Dies hat den Vorteil, dass nur im Fehlerfall ein Exit Code ungleich 0 &#252;bergeben werden muss und die Anwendung ansonsten automatisch 0 zur&#252;ck gibt beim Beenden.

Das Beispielprojekt ist hier hochgeladen:
  http://cid-fd4d63530af59c99.skydrive.live.com/self.aspx/.Public/ExitCode.zip</description>
			<link>http://blogs.ppedv.de/felixr/archive/Ruumlckgabewerte-von-Programmen</link>
			<author>Felix Ruthenberg </author>
			<pubDate>Fri, 13 Mar 2009 12:50:05 GMT</pubDate>
			<category domain="http://blogs.ppedv.de?tag=">
			.Net</category><category>C#</category><category>
			</category>
			
		</item>
	
		<item>
			<title>[Felix Ruthenberg] Reset WPF Dependency Property</title>
			<description>We have seen how dependency properties inherit their values from another control they are nested in.&#160; We also saw that it&apos;s possible to break that chain of inheritance by setting the value of a certain property specifically.  But what can we do to reset the Dependency Property again, so that inherits its value from a higher hierachy level again?&#160; The answer is quite simple and done within one or two lines of code using the ClearValue() method of the control.  ClearValue() expects a parameter that tells which dependency property is to be reset as the following example shows:  private void Button_MouseRightButtonUp(object sender, MouseButtonEventArgs e)
{
  Button btn = e.Source as Button;
  btn.ClearValue(Button.FontSizeProperty);
}

.csharpcode, .csharpcode pre
{
	font-size: small;
	color: black;
	font-family: consolas, "Courier New", courier, monospace;
	background-color: #ffffff;
	/*white-space: pre;*/
}
.csharpcode pre { margin: 0em; }
.csharpcode .rem { color: #008000; }
.csharpcode .kwrd { color: #0000ff; }
.csharpcode .str { color: #006080; }
.csharpcode .op { color: #0000c0; }
.csharpcode .preproc { color: #cc6633; }
.csharpcode .asp { background-color: #ffff00; }
.csharpcode .html { color: #800000; }
.csharpcode .attr { color: #ff0000; }
.csharpcode .alt 
{
	background-color: #f4f4f4;
	width: 100%;
	margin: 0em;
}
.csharpcode .lnum { color: #606060; }</description>
			<link>http://blogs.ppedv.de/felixr/archive/Reset-WPF-Dependency-Property</link>
			<author>Felix Ruthenberg </author>
			<pubDate>Thu, 22 Jan 2009 09:08:32 GMT</pubDate>
			<category domain="http://blogs.ppedv.de?tag=">
			WPF</category><category>
			</category>
			
		</item>
	
		<item>
			<title>[Felix Ruthenberg] Encrypt App.settings</title>
			<description>If you google for an encryption algorithm for your configuration files in the .NET framework you&apos;ll find many ideas on how to encrypt the web.config file in ASP.NET rather than encryption methods for the App.config file.  However, of course it is possible to encrypt sections in the App.config file just as it is for the web.config file:  In order to get access to the static configuration classes you should implement the System.Configuration namespace into your application:  using System.Configuration;


.csharpcode, .csharpcode pre
{
	font-size: small;
	color: black;
	font-family: consolas, "Courier New", courier, monospace;
	background-color: #ffffff;
	/*white-space: pre;*/
}
.csharpcode pre { margin: 0em; }
.csharpcode .rem { color: #008000; }
.csharpcode .kwrd { color: #0000ff; }
.csharpcode .str { color: #006080; }
.csharpcode .op { color: #0000c0; }
.csharpcode .preproc { color: #cc6633; }
.csharpcode .asp { background-color: #ffff00; }
.csharpcode .html { color: #800000; }
.csharpcode .attr { color: #ff0000; }
.csharpcode .alt 
{
	background-color: #f4f4f4;
	width: 100%;
	margin: 0em;
}
.csharpcode .lnum { color: #606060; }Now we can access just any section within our application configuration file.&#160; And we can also easily use the ProtectSection() method on that section to encrypt it using a specified DataProtectionProvider.

The code would look similar to this:

Configuration config = ConfigurationManager.OpenExeConfiguration(Application.ExecutablePath);
ConfigurationSection section = config.GetSection(&quot;connectionStrings&quot;) // could be any section

if(!section.SectionInformation.IsProtected)

  {
    section.SectionInformation.ProtectSection(&quot;DataProtectionConfigurationProvider&quot;);
    config.Save();
  }

Don&apos;t forget to save your config, otherwise changes will not be applied

And also remember that your config file will be compiled into a file called NameOfApplication.exe.config and it will be available in your bin (or appropriate output) folder, so don&apos;t expect changes to happen in the App.config file (this is different to ASP.NET applications).

Your application may still access the configuration and read it without the need of decryption.&#160; However depending on the used encryption algorithm this may not be true if you move the assemblies to another computer.&#160; To read more about encryption algorithms you may want to start here:&#160; http://www.mycrypto.net/encryption/crypto_algorithms.html

Finally, let me show how to decrypt your settings:

// Given that the appropriate section is known as shown above

if (section.SectionInformation.IsProtected)

{
  section.SectionInformation.UnprotectSection();
  config.Save();
}

.csharpcode, .csharpcode pre
{
	font-size: small;
	color: black;
	font-family: consolas, "Courier New", courier, monospace;
	background-color: #ffffff;
	/*white-space: pre;*/
}
.csharpcode pre { margin: 0em; }
.csharpcode .rem { color: #008000; }
.csharpcode .kwrd { color: #0000ff; }
.csharpcode .str { color: #006080; }
.csharpcode .op { color: #0000c0; }
.csharpcode .preproc { color: #cc6633; }
.csharpcode .asp { background-color: #ffff00; }
.csharpcode .html { color: #800000; }
.csharpcode .attr { color: #ff0000; }
.csharpcode .alt 
{
	background-color: #f4f4f4;
	width: 100%;
	margin: 0em;
}
.csharpcode .lnum { color: #606060; }</description>
			<link>http://blogs.ppedv.de/felixr/archive/Encrypt-App.settings</link>
			<author>Felix Ruthenberg </author>
			<pubDate>Wed, 21 Jan 2009 11:31:13 GMT</pubDate>
			<category domain="http://blogs.ppedv.de?tag=">
			C#</category><category>
			</category>
			
		</item>
	
		<item>
			<title>[Felix Ruthenberg] How to get the ID of a newly inserted data tuple</title>
			<description>Imagine a scenarion where you want to insert a new data row into a database and the database automatically generates an entry for the ID of that data tuple (which is the case in most business scenarios).  If you use Linq to Sql you can easily access the ID after you have committed the SubmitChanges() method on the data context.&#160; And how?&#160; Just ask the object for its appropriate property:  NorthwindDataContext ndc = new NorthwindDataContext();
Order newOrder = new Order { CustomerID = &quot;ALFKI&quot;, EmployeeID = 4 };
ndc.Orders.InsertOnSubmit(newOrder);
ndc.SubmitChanges();
Console.WriteLine(&quot;The ID of the newly inserted order is: {0}&quot;,newOrder.OrderID);

One of my attendees in Darmstadt already mentioned it could be as simple as this and I am happy to announce him right!</description>
			<link>http://blogs.ppedv.de/felixr/archive/How-to-get-the-ID-of-a-newly-inserted-data-tuple</link>
			<author>Felix Ruthenberg </author>
			<pubDate>Wed, 21 Jan 2009 10:35:50 GMT</pubDate>
			<category domain="http://blogs.ppedv.de?tag=">
			C#</category><category>LINQ
			</category>
			
		</item>
	
		<item>
			<title>[Felix Ruthenberg] Lambda Expressions - a simple way to write inline code blocks</title>
			<description>During the last training event we covered the way from delegates to Lambda Expressions and we have seen some examples when and how to use lambda expressions (mostly in combination with the new LINQ technology).  If you look at the MSDN websites (at http://msdn.microsoft.com/en-us/library/bb397687.aspx) you will find a proper definition of Lambda Expressions.  You will also find the following definition which should answer any open questions:     Lambda expressions provide a simple way to write inline code blocks where delegates are expected. Their behavior is strikingly similar to anonymous methods. In fact, they are syntactic sugar in terms of syntax. They can take multiple parameters, explicit or implicit.</description>
			<link>http://blogs.ppedv.de/felixr/archive/Lambda-Expressions---a-simple-way-to-write-inline-code-blocks</link>
			<author>Felix Ruthenberg </author>
			<pubDate>Wed, 21 Jan 2009 10:06:30 GMT</pubDate>
			<category domain="http://blogs.ppedv.de?tag=">
			C#</category><category>
			</category>
			
		</item>
	
		<item>
			<title>[Felix Ruthenberg] AnonymousTypes and their properties</title>
			<description>When you instantiate a new object using the keyword new without actually giving it a name (see below), the C# compiler automatically generates an anymous type.  static void Main(string[] args)
{

  var anoType = new { FName = &quot;Felix&quot;, LName = &quot;Ruthenberg&quot; };
  Console.WriteLine(&quot;FName: {0} LName: {1}&quot;,anoType.FName,anoType.LName);
}

This type has two properties (called key properties, not fields!) which are read-only. That means that the framework creates &quot;on-the-fly classes&quot; and istantiates the object as shown in the example.

Refer to the MSDN websites for more details: http://msdn.microsoft.com/en-us/library/bb397696.aspx

Unfortunately I couldn&apos;t find a reference or explanation why the property values cannot be changed once they have been set. If you find out anything about that please just leave me a comment.

.csharpcode, .csharpcode pre
{
	font-size: small;
	color: black;
	font-family: consolas, "Courier New", courier, monospace;
	background-color: #ffffff;
	/*white-space: pre;*/
}
.csharpcode pre { margin: 0em; }
.csharpcode .rem { color: #008000; }
.csharpcode .kwrd { color: #0000ff; }
.csharpcode .str { color: #006080; }
.csharpcode .op { color: #0000c0; }
.csharpcode .preproc { color: #cc6633; }
.csharpcode .asp { background-color: #ffff00; }
.csharpcode .html { color: #800000; }
.csharpcode .attr { color: #ff0000; }
.csharpcode .alt 
{
	background-color: #f4f4f4;
	width: 100%;
	margin: 0em;
}
.csharpcode .lnum { color: #606060; }</description>
			<link>http://blogs.ppedv.de/felixr/archive/AnonymousTypes-dive-into</link>
			<author>Felix Ruthenberg </author>
			<pubDate>Wed, 21 Jan 2009 09:51:05 GMT</pubDate>
			<category domain="http://blogs.ppedv.de?tag=">
			C#</category><category>
			</category>
			
		</item>
	
		<item>
			<title>[Felix Ruthenberg] Cookieless Forms Authentication</title>
			<description>Im vergangenen ASP.NET Kurs haben wir uns die Frage gestellt ob es m&#246;glich ist Forms Authentication zu nutzen, ohne allerdings dabei Cookies zu benutzen. ; Die Antwort war: Ja, es ist m&#246;glich, und hier zeige ich auch kurz wie.
&#196;hnlich dem "cookieless" state in der &#220;bermittlung der SessionID gibt es auch f&#252;r die Forms Authentication ein entsprechendes Attribut. ; Zu setzen ist dies in der web.config in diesem Pfad:&lt;system.web&gt;

    &lt;authentication mode="Forms"&gt;
      &lt;forms name=".ASPXAUTH" cookieless="UseUri" loginUrl="Login.aspx"  /&gt;
    &lt;/authentication&gt;

    &lt;authorization &gt;
      &lt;deny users="?"/&gt;
    &lt;/authorization&gt;

&lt;/system.web&gt;
Wie zu vermuten ist kann das "cookieless" Attribut mehrere Werte annehmen: - AutoDetect; Benutzt Cookies wenn m&#246;glich - UseCookies; Benutzt immer Cookies - UseDeviceProfile; Nimmt die Information aus der machine.config - UseUri; Benutzt keine Cookies, der QueryString wird um die Anmeldeinformationen erweitert, siehe Beispiel unten:
Typischer Authentication Query String:http://localhost:50828/WebSite2/(F(k57F8sN_f1CyBi4FzonU74GkKCtkFQZXZEzeuAbR1P-Pi03myPerV9h6ahdCRFgU7jgN-HjEgcCV0umSAzD3BHAmZf1Xr4hJVbHP5emIqms1))/Default.aspx



.csharpcode, .csharpcode pre
{
	font-size: small;
	color: black;
	font-family: consolas, "Courier New", courier, monospace;
	background-color: #ffffff;
	/*white-space: pre;*/
}
.csharpcode pre { margin: 0em; }
.csharpcode .rem { color: #008000; }
.csharpcode .kwrd { color: #0000ff; }
.csharpcode .str { color: #006080; }
.csharpcode .op { color: #0000c0; }
.csharpcode .preproc { color: #cc6633; }
.csharpcode .asp { background-color: #ffff00; }
.csharpcode .html { color: #800000; }
.csharpcode .attr { color: #ff0000; }
.csharpcode .alt 
{
	background-color: #f4f4f4;
	width: 100%;
	margin: 0em;
}
.csharpcode .lnum { color: #606060; }
</description>
			<link>http://blogs.ppedv.de/felixr/archive/Samples-zu-ASP.NET-Koumlln-8.12.---11.12.2008</link>
			<author>Felix Ruthenberg </author>
			<pubDate>Mon, 15 Dec 2008 13:55:37 GMT</pubDate>
			<category domain="http://blogs.ppedv.de?tag=">
			.Net</category><category>
			</category>
			
		</item>
	
		<item>
			<title>[Felix Ruthenberg] Samples zu ASP.NET K&#246;ln 8.12. - 11.12.2008</title>
			<description>Wie versprochen findet Ihr hier die Samples des ASP.NET 3.5 Kurses.  Erst mal die Datenbanken zum Download:  DataBases  Und hier sind die Samples, die ich erstellt habe (F&#252;r ADO.NET ist nun auch ein einfaches LINQ Sample mit Select, Update, Insert und Delete enthalten):  Samples</description>
			<link>http://blogs.ppedv.de/felixr/archive/Samples-zu-ASP.NET-Koumlln-8.12.---11.12.2008</link>
			<author>Felix Ruthenberg </author>
			<pubDate>Fri, 12 Dec 2008 12:19:07 GMT</pubDate>
			<category domain="http://blogs.ppedv.de?tag=">
			.Net</category><category>
			</category>
			
		</item>
	
	        </channel>
		</rss>
	
    
    

