<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>C-Sharp.ch</title>
	<atom:link href="http://www.c-sharp.ch/feed/" rel="self" type="application/rss+xml" />
	<link>http://www.c-sharp.ch</link>
	<description>Alles rund um C# auf einer Seite</description>
	<lastBuildDate>Thu, 24 Dec 2009 09:34:42 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.0</generator>
		<item>
		<title>ClickOnce &#8211; Die .NET Antwort auf Java WebStart</title>
		<link>http://www.c-sharp.ch/2009/09/clickonce-die-net-antwort-auf-java-webstart/</link>
		<comments>http://www.c-sharp.ch/2009/09/clickonce-die-net-antwort-auf-java-webstart/#comments</comments>
		<pubDate>Sun, 13 Sep 2009 18:17:40 +0000</pubDate>
		<dc:creator>admin</dc:creator>
				<category><![CDATA[Allgemein]]></category>

		<guid isPermaLink="false">http://www.c-sharp.ch/?p=85</guid>
		<description><![CDATA[Java hat es vorgemacht: Ein einfaches Konzept namens Webstart ermöglicht eine einfache Verteilung einer Anwendung über das Web. Dabei wird die Applikation über einen Browser aufgerufen, welcher die benötigten Downloads automatisch tätigt und die Applikation startet. Diese Art der Softwareverteilung hat gewisse Vorteile wie beispielsweise die Zugreifbarkeit oder die Updatemöglichkeit ohne, dass der Benutzer aktiv [...]]]></description>
			<content:encoded><![CDATA[<p>Java hat es vorgemacht: Ein einfaches Konzept namens Webstart ermöglicht eine einfache Verteilung einer Anwendung über das Web. Dabei wird die Applikation über einen Browser aufgerufen, welcher die benötigten Downloads automatisch tätigt und die Applikation startet. Diese Art der Softwareverteilung hat gewisse Vorteile wie beispielsweise die Zugreifbarkeit oder die Updatemöglichkeit ohne, dass der Benutzer aktiv werden muss.</p>
<p>Die Antwort von .NET heisst ClickOnce. Das Prinzip dahinter ist grundsätzlich genau gleich. So können Applikationen direkt auf einem Webserver veröffentlicht werden. Die Veröffentlichung von ClickOnce-Applikationen ist dabei spielend einfach. Im Eigenschaften Fenster des Projekts müssten im Reiter &#8220;Publish&#8221; einfach der Exportpfad sowie der entgültige Pfad auf dem Webserver eingegeben werden. Der Entwickler hat dier noch mehrere Einstellmöglichkeiten welche sich hinter dem &#8220;Options&#8221; Button verbergen. Wurde der gesamte Export auf den Webserver geladen, kann die Applikation auf 2 Arten gestartet werden:</p>
<ul>
<li>Mit einem direkten Start über die &#8220;.application&#8221; Datei (funktioniert mit dem IE Einwandfrei, während Firefox dazu evtl. das Addon <a href="https://addons.mozilla.org/de/firefox/addon/9449" target="_blank">Microsoft .NET Framework Assistant</a> benötigt)</li>
<li>Mit einem vorherigen Download eines Setups, welches prüft ob die vorausgesetzten Software Packages installiert sind (Framework, Windows Installer, etc.).</li>
</ul>
<p>Als kleines Beispiel habe ich eine Hello World-Applikation gemacht, welche ganz einfach über einen Browser aufrufbar ist.</p>
<p><strong><a href="http://preview.c-sharp.ch/wp-content/uploads/2009/09/ClickOnceExample/publish.htm" target="_blank">Starte die ClickOnce-Demo</a></strong> (leitet dich auf eine Seite weiter, welche von Visual Studio generiert wurde und beide obengenannten Startmöglichkeiten verlinkt hat)</p>
]]></content:encoded>
			<wfw:commentRss>http://www.c-sharp.ch/2009/09/clickonce-die-net-antwort-auf-java-webstart/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Threadsichere Aktualisierung von GUIs</title>
		<link>http://www.c-sharp.ch/2009/09/threadsichere-aktualisierung-von-guis/</link>
		<comments>http://www.c-sharp.ch/2009/09/threadsichere-aktualisierung-von-guis/#comments</comments>
		<pubDate>Sat, 05 Sep 2009 07:22:46 +0000</pubDate>
		<dc:creator>admin</dc:creator>
				<category><![CDATA[Allgemein]]></category>
		<category><![CDATA[Forms]]></category>

		<guid isPermaLink="false">http://www.c-sharp.ch/?p=70</guid>
		<description><![CDATA[Standardmässig lässt C# es nicht zu, dass das GUI von einem anderen Thread aktualisiert wird, als von jenem der es erstellt hat. C# wirf eine InvalidOperationException mit dem hinweis, dass versucht wurde das GUI von einem Thread zu aktualisieren, welche nicht der Besitzer ist. Es gibt jedoch möglichkeiten wie man trotzdem von anderen Threads auf [...]]]></description>
			<content:encoded><![CDATA[<p>Standardmässig lässt C# es nicht zu, dass das GUI von einem anderen Thread aktualisiert wird, als von jenem der es erstellt hat. C# wirf eine InvalidOperationException mit dem hinweis, dass versucht wurde das GUI von einem Thread zu aktualisieren, welche nicht der Besitzer ist. Es gibt jedoch möglichkeiten wie man trotzdem von anderen Threads auf das GUI schreiben kann. Dazu dient beispielsweise die Eigenschaft</p>
<pre class="brush: csharp; collapse: false;">
Control.CheckForIllegalCrossThreadCalls
</pre>
<p>Diese ist in C# von Beginn weg auf True gestellt. Es gibt nun zwei verschiedene Möglichkeiten wie man von anderen Threads trotzdem die GUI Komponenten aufrufen kann:</p>
<ul>
<li>Man stellt die obengenannte Eigenschaft auf  false, womit keine Prüfung mehr erfolgt ob es ein threadübergreifender Vorgang ist</li>
<li>Man benutzt die InvokeRequired-Methode welche prüft ob ein threadübergreifender Vorgang vorliegt und Methode nochmals vom GUI-Thread aufgerufen werden soll.</li>
</ul>
<p>Da die erste Möglichkeit mit einer Codezeile erledigt wird, möchten wir uns die zweite Methode genauer anschauen. Dabei kommen Delegates zum Einsatz. Wie der Name schon sagt werden dabei Methodenaufrufe delegiert.  Der Methodenaufruf wird dabei an den den GUI-Thread übergeben, welche die Methode von sich aus aufruft. Damit haben wir das Problem des threadübergreifenden Zugriffs elegant gelöst!</p>
<p>Als kleines Beispiel habe ich ein Projekt erstellt welche einerseits mit der BeginInvoke-Methode arbeitet und andererseits keine Prüfung beinhaltet (also eine Exception wirft). Um die Abläufe der Aufrufe am besten zu verfolgen wird empfohlen das Projekt im Debugging-Modus auszuführen. So ist klar ersichtlich welche Aufrufe wann passieren und es ist leichter nachvollziehbar. Der zentrale Code mit den Delegates lautet folgendermassen:</p>
<pre class="brush: csharp; collapse: false;">
delegate void ChangeLabelSizeCallback(float newSize);
private void ChangeLabelSize(float newSize)
{
    if (lblTarget.InvokeRequired)
    {
        ChangeLabelSizeCallback lsc = new ChangeLabelSizeCallback(ChangeLabelSize);
        lblTarget.Invoke(lsc, new Object[] { newSize });
    }
    else
    {
        lblTarget.Font = new Font(lblTarget.Font.FontFamily, newSize);
        lblTarget.Text = &quot;FontSize: &quot; + newSize.ToString();
    }
}
</pre>
<p>Anbei steht das gesamte Beispiel noch zum Download bereit:</p>
<p><a href="http://preview.c-sharp.ch/wp-content/uploads/2009/09/InvokeExample.zip"><img class="alignnone size-thumbnail wp-image-19" title="Download" src="http://preview.c-sharp.ch/wp-content/uploads/2009/08/zip_icon1-150x150.jpg" alt="Download" width="60" height="60" /></a></p>
]]></content:encoded>
			<wfw:commentRss>http://www.c-sharp.ch/2009/09/threadsichere-aktualisierung-von-guis/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>WCF &#8211; Wir bilden einen Service</title>
		<link>http://www.c-sharp.ch/2009/08/wcf-wir-bilden-einen-service/</link>
		<comments>http://www.c-sharp.ch/2009/08/wcf-wir-bilden-einen-service/#comments</comments>
		<pubDate>Thu, 27 Aug 2009 19:28:03 +0000</pubDate>
		<dc:creator>admin</dc:creator>
				<category><![CDATA[Netzwerk]]></category>

		<guid isPermaLink="false">http://www.c-sharp.ch/?p=40</guid>
		<description><![CDATA[WCF (Windows Communication Foundation) ist eine neue Kommunikationsplattform für verteilte Anwendungen. Das Kerngebiet von WCF liegt dabei bei Serviceorientierten Anwendungen und deren Entwicklung. Um kurz zu zeigen wie einfach es ist seinen eigenen Service zu schreiben, habe ich wie immer ein kleines Beispiel hochgeladen. Das Beispiel beinhaltet dabei 2 Projekte. Ein Server (also der Dienserbringer) [...]]]></description>
			<content:encoded><![CDATA[<p>WCF (Windows Communication Foundation) ist eine neue Kommunikationsplattform für verteilte Anwendungen. Das Kerngebiet von WCF liegt dabei bei Serviceorientierten Anwendungen und deren Entwicklung.</p>
<p>Um kurz zu zeigen wie einfach es ist seinen eigenen Service zu schreiben, habe ich wie immer ein kleines Beispiel hochgeladen. Das Beispiel beinhaltet dabei 2 Projekte. Ein Server (also der Dienserbringer) und einen Client (der Dienstnutzer). In unserem Beispiel bietet der Server einen Service an, welche alle empfangenen Strings in umgekehrter Buchstabenfolge zurücksenden. Sendet der Client also &#8220;Hallo Welt&#8221; an den Server, so erhält er als Antwort &#8220;tleW ollaH&#8221;</p>
<p>Dazu müssen beide Applikationen den Namespace &#8220;System.ServiceModel&#8221; referenzieren, welcher die entsprechenden WCF-Klassen bereitstellt.</p>
<p><strong>Hinweise zum Server:</strong><br />
Da der Server eine bestimmte Service-URL reservieren und auf einen bestimmten Port horchen muss, müssen diese beiden Angaben eingerichtet werden. Um die URL zu reservieren gibt man in der Konsole folgendes ein (benötigt Administratorenrechte!):</p>
<ul>
<li>Windows Server 2003, XP:<br />
<em>httpcfg.exe set urlacl /u http://myhost:8000/ /a &#8220;O:AOG:DAD:(A;;RPWPCCDCLCSWRCWDWOGA;;;S-1-0-0)&#8221;</em></li>
<li>Windows Vista:<br />
<em>netsh http add urlacl url=http://+:80/MyUri user=DOMAIN\user</em></li>
</ul>
<p>Danach muss man den Port noch als Ausnahme bei der Windows Firewall hinzufügen:</p>
<ul>
<li>Windows Server 2003, XP:<br />
<em>httpcfg.exe set iplisten -i 0.0.0.0:8000</em></li>
<li>Windows Vista:<br />
<em>netsh http add iplisten ipaddress=0.0.0.0:8000</em></li>
</ul>
<p>Die genauen Angaben über die Befehle findet man auf: <a href="http://msdn.microsoft.com/en-us/library/ms733768.aspx"></p>
<p>http://msdn.microsoft.com/en-us/library/ms733768.aspx</a></p>
<p>Wenn die beiden Konsolenanwendungen laufen, sieht das ganze dann so aus:</p>
<p><strong>Client</strong>:<br />
<a href="http://preview.c-sharp.ch/wp-content/uploads/2009/08/screenshot_wcf1.gif"><img class="alignnone size-full wp-image-67" title="screenshot_wcf1" src="http://preview.c-sharp.ch/wp-content/uploads/2009/08/screenshot_wcf1.gif" alt="screenshot_wcf1" width="677" height="340" /></a></p>
<p><strong>Server:</strong><br />
<a href="http://preview.c-sharp.ch/wp-content/uploads/2009/08/screenshot_wcf2.gif"><img class="alignnone size-full wp-image-68" title="screenshot_wcf2" src="http://preview.c-sharp.ch/wp-content/uploads/2009/08/screenshot_wcf2.gif" alt="screenshot_wcf2" width="677" height="340" /></a></p>
<p><a href="http://preview.c-sharp.ch/wp-content/uploads/2009/08/WCF_Example.zip"><img class="alignnone size-thumbnail wp-image-19" title="Download" src="http://preview.c-sharp.ch/wp-content/uploads/2009/08/zip_icon1-150x150.jpg" alt="Download" width="60" height="60" /></a></p>
<p>Service- und OperationContract des Servers:</p>
<pre class="brush: csharp; collapse: false;">
using System;
using System.ServiceModel;

namespace WCF_Example
{
    [ServiceContract]
    public interface IReverseString
    {
        [OperationContract]
        String ReverseString(String strInput);
    }
}
</pre>
<p>Implementation des Servers:</p>
<pre class="brush: csharp; collapse: false;">
using System;

namespace WCF_Example
{
    public class StringOperation : IReverseString
    {

        public string ReverseString(string strInput)
        {
            String strOutput = String.Empty;

            Console.WriteLine(&quot;\nFolgender String wurde empfangen: &quot; + strInput);
            Console.WriteLine(&quot;String wird verarbeitet&quot;);
            for (int i = strInput.Length - 1; i &gt;= 0; i--)
            {
                strOutput += strInput.Substring(i, 1);
            }
            Console.WriteLine(&quot;Verarbeitung beendet&quot;);
            return strOutput;
        }

    }
}
</pre>
<p>Sourcecode des Clients:</p>
<pre class="brush: csharp; collapse: false;">
using System;
using System.ServiceModel;
using WCF_Example;

namespace WCF_Client
{
    public class Client
    {
        public String ReverseString(String strInput)
        {
            ChannelFactory&lt;IReverseString&gt; factory = new ChannelFactory&lt;IReverseString&gt;( new WSHttpBinding(), new EndpointAddress(&quot;http://localhost:43210/StringOperation&quot;));

            IReverseString revString = factory.CreateChannel();

            return revString.ReverseString(strInput);
        }
    }
}
</pre>
]]></content:encoded>
			<wfw:commentRss>http://www.c-sharp.ch/2009/08/wcf-wir-bilden-einen-service/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Custom Event</title>
		<link>http://www.c-sharp.ch/2009/08/custom-event/</link>
		<comments>http://www.c-sharp.ch/2009/08/custom-event/#comments</comments>
		<pubDate>Fri, 21 Aug 2009 17:35:33 +0000</pubDate>
		<dc:creator>admin</dc:creator>
				<category><![CDATA[Allgemein]]></category>

		<guid isPermaLink="false">http://www.c-sharp.ch/?p=36</guid>
		<description><![CDATA[Während der Softwareentwicklung hat man sehr viel mit Events zu tun. Meistens werden diese von bestimmten Klassen zur Verfügung gestellt. Die gängisten Events sind sicherlich dienenigen der GUI Komponenten. Häufig liefern die Events Zusatzinformationen in Form vom Parametern, welche man danach auswerten kann. Doch was ist, wenn man eigene Events programmieren und diesen eigene Parameter [...]]]></description>
			<content:encoded><![CDATA[<p>Während der Softwareentwicklung hat man sehr viel mit Events zu tun. Meistens werden diese von bestimmten Klassen zur Verfügung gestellt. Die gängisten Events sind sicherlich dienenigen der GUI Komponenten. Häufig liefern die Events Zusatzinformationen in Form vom Parametern, welche man danach auswerten kann. Doch was ist, wenn man eigene Events programmieren und diesen eigene Parameter übergeben möchte?</p>
<p>In C# ist dies wirklich sehr einfach gelöst. Es benötigt nur ein paar Zeilen Code und schon hat man einen eigenen Event erstellt, der von überallher angezapft werden kann. Als kleines Beispiel habe ich ein Konsolenanwendung geschrieben, welche eine boolsche Variable hat, welche regelmässig ihren Wert ändert. Da man aber zum Vornherein nicht genau weis, wann das sein wird, wird ein Event zur Verfügung gestellt welche alle horchenden Objekte benachrichtigt. Bei einer erhaltenen Benachrichtigung wird dies auf dem Konsolenfenster ausgegeben.</p>
<p><a href="http://preview.c-sharp.ch/wp-content/uploads/2009/08/CustomEvent.zip"><img class="alignnone size-thumbnail wp-image-19" title="Download" src="http://preview.c-sharp.ch/wp-content/uploads/2009/08/zip_icon1-150x150.jpg" alt="Download" width="60" height="60" /></a></p>
<p>Dies ist die Klasse die den Event zur Verfügung stellt und ihn nötigenfalls abfeuert:</p>
<pre class="brush: csharp; collapse: false;">
using System;
using System.Timers;

namespace EventExample
{
    public delegate void FlagValueChangedEventHandler(bool newValue);

    public class EventSource
    {
        public event FlagValueChangedEventHandler FlagValueChanged;
        private bool m_Flag;
        private Timer m_Timer = new Timer();
        private Random m_Random = new Random();

        /// &lt;summary&gt;
        /// Konstruktor
        /// &lt;/summary&gt;
        public EventSource()
        {
            //Event für Timer wird angezapt
            m_Timer.Elapsed += new ElapsedEventHandler(m_Timer_Elapsed);
        }

        /// &lt;summary&gt;
        /// Berechnet den neuen Interval und starten den Timer
        /// &lt;/summary&gt;
        public void Start()
        {
            //Zufälliges Intervall zwischen 1 und 10 Sekunden wird ermittelt
            m_Timer.Interval = (m_Random.Next(9) + 1) * 1000;

            //Timer wird gestartet
            m_Timer.Start();
        }

        /// &lt;summary&gt;
        /// Ereignis welches auftritt wenn die Intervalzeit abgelaufen ist
        /// &lt;/summary&gt;
        /// &lt;param name=&quot;sender&quot;&gt;&lt;/param&gt;
        /// &lt;param name=&quot;e&quot;&gt;&lt;/param&gt;
        void m_Timer_Elapsed(object sender, ElapsedEventArgs e)
        {
            //Timer wird gestoppt
            m_Timer.Stop();

            //Wert des boolschen Flags wird geändert
            m_Flag = !m_Flag;

            //Wenn jemand auf den Event horcht wird dieser abgefeuert
            if (FlagValueChanged != null)
            {
                FlagValueChanged(m_Flag);
            }

            //Spiel beginnt wieder von neuem
            Start();
        }

    }
}
</pre>
]]></content:encoded>
			<wfw:commentRss>http://www.c-sharp.ch/2009/08/custom-event/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>ColorComboBox</title>
		<link>http://www.c-sharp.ch/2009/08/colorcombobox/</link>
		<comments>http://www.c-sharp.ch/2009/08/colorcombobox/#comments</comments>
		<pubDate>Wed, 12 Aug 2009 22:03:30 +0000</pubDate>
		<dc:creator>admin</dc:creator>
				<category><![CDATA[Controls]]></category>

		<guid isPermaLink="false">http://www.c-sharp.ch/?p=23</guid>
		<description><![CDATA[C# (bzw. .NET) bietet uns die Möglichkeit eigene Controls zu erstellen, welche im Designer ebenso eingesetzt werden können wie die bestehenden Controls. Als kleines Beispiel wie man eine solches Control erstellt, habe ich eine kleine ColorComboBox entworfen. Dieses Control bietet noch sehr viel Erweiterungspotential und ist deshalb prima geeignet für diejenigen, welche sich noch nie [...]]]></description>
			<content:encoded><![CDATA[<p>C# (bzw. .NET) bietet uns die Möglichkeit eigene Controls zu erstellen, welche im Designer ebenso eingesetzt werden können wie die bestehenden Controls. Als kleines Beispiel wie man eine solches Control erstellt, habe ich eine kleine ColorComboBox entworfen. Dieses Control bietet noch sehr viel Erweiterungspotential und ist deshalb prima geeignet für diejenigen, welche sich noch nie mit dem erstellen von eigenen Controls beschäftigt haben. Es soll lediglich der Demonstratien dienen, wie eigene Controls erstellt werden.</p>
<p>Als Grundlage dient eine normale Combobox (Stichwort: Vererbung). Dieser Combobox werden einige neue Eigenschaften und Methoden hinzugefügt. Das Herzstück des neuen Controls ist jedoch die Methode &#8220;OnDrawItem&#8221;, welche die ComboBox in ihrer neuen (farbigen) Form erscheinen lässt. Diese Methode wird implizit aufgerufen, sobald das Control sich neu zeichnen muss. In unserer Variante haben wir die Möglichkeit einen Text und daneben eine beliebige Farbe anzeigen zu lassen. Dies sieht dann etwa so aus:</p>
<p><a href="http://preview.c-sharp.ch/wp-content/uploads/2009/08/ColorComboBoxSmall.jpg"><img class="alignnone size-full wp-image-24" title="ColorComboBoxSmall" src="http://preview.c-sharp.ch/wp-content/uploads/2009/08/ColorComboBoxSmall.jpg" alt="ColorComboBoxSmall" width="226" height="172" /></a></p>
<p>Der unten aufgeführt Code ist lediglich für die ColorComboBox. Das Demoprogramm welches heruntergeladen werden kann, zeigt wie die ColorComboBox gefüllt werden kann und wie im Design-Modus von Visual Studio daherkommt.</p>
<p><a href="http://preview.c-sharp.ch/wp-content/uploads/2009/08/ColorComboBox.zip"><img class="alignnone size-thumbnail wp-image-19" title="Download" src="http://preview.c-sharp.ch/wp-content/uploads/2009/08/zip_icon1-150x150.jpg" alt="Download" width="60" height="60" /></a></p>
<pre class="brush: csharp; collapse: false;">

using System;
using System.Collections.Generic;
using System.Drawing;
using System.Windows.Forms;
using System.ComponentModel;

namespace ColorComboBoxDemo
{
    public class ColorComboBox : System.Windows.Forms.ComboBox
    {
        private bool bCustomColor;
        private List&lt;ColorItem&gt; arrColorItems = new List&lt;ColorItem&gt;();
        private ColorItem currentItem;
        private const string strCustom = &quot;Benutzerdefiniert...&quot;;

        public ColorComboBox ()
        {
            //Zeichungsmodus wird festgelegt
            this.DrawMode = DrawMode.OwnerDrawFixed;

            //Eventhandler werden hinzugefügt
            this.DrawItem += new DrawItemEventHandler(OnDrawItem);
            this.SelectedIndexChanged += new System.EventHandler(OnSelectedIndexChanged);
            this.DropDown += new System.EventHandler(OnDropDown);
        }

        private void OnDrawItem(object sender, System.Windows.Forms.DrawItemEventArgs e)
        {
            //Ränderabstand wird festgelegt
            int padXl = 20;
            int padXr = 10;
            int padY = 2;

            if (e.Index &lt; 0)
            {
                return;
            }

            //Momenan aktives ColorItem wird ausgelesen
            currentItem = arrColorItems[e.Index];

            if (currentItem.ShowOnlyColor == true)
            {
                padXl = 3;
            }

            //Grafikzeichner wird instanziert
            Graphics grfx = e.Graphics;

            //Pinsel für Farbige Rechtecke werden definiert
            Color brushColor = currentItem.CurrentColor;
            SolidBrush brush = new SolidBrush(brushColor);

            //Zeichnungsbereiche werden definiert
            Rectangle rectFillBackground = new Rectangle(e.Bounds.X, e.Bounds.Y, e.Bounds.Width, e.Bounds.Height);
            Rectangle rectFillColor = new Rectangle(e.Bounds.X + padXl, e.Bounds.Y + padY, e.Bounds.Width - (padXl + padXr), e.Bounds.Height - (2 * padY));
            Rectangle rectText;

            //Hintergrund wird gezeichnet
            grfx.FillRectangle(new SolidBrush(Color.White), rectFillBackground);

            if (currentItem.ShowOnlyText == false)
            {
                //Textbereich wird definiert
                rectText = new Rectangle(e.Bounds.X, e.Bounds.Y, e.Bounds.X + padXl, e.Bounds.Height - (2 * padY));

                //Farbiges Rechteck wird gezeichnet
                grfx.FillRectangle(brush, rectFillColor);

                //LinieOben
                grfx.DrawLine(new Pen(Color.Black, (float)0.1), new Point(e.Bounds.X + padXl, e.Bounds.Y + padY), new Point(e.Bounds.X + padXl + (e.Bounds.Width - padXl - padXr), e.Bounds.Y + padY));
                //LinieRechts
                grfx.DrawLine(new Pen(Color.Black, (float)0.1), new Point(e.Bounds.X + padXl + (e.Bounds.Width - padXl - padXr), e.Bounds.Y + padY), new Point(e.Bounds.X + padXl + (e.Bounds.Width - padXl - padXr), e.Bounds.Y + e.Bounds.Height - (2 * padY) + 1));
                //LinieUnten
                grfx.DrawLine(new Pen(Color.Black, (float)0.1), new Point(e.Bounds.X + padXl, e.Bounds.Y + e.Bounds.Height - (2 * padY) + 1), new Point(e.Bounds.X + padXl + (e.Bounds.Width - padXl - padXr), e.Bounds.Y + e.Bounds.Height - (2 * padY) + 1));
                //LinieLinks
                grfx.DrawLine(new Pen(Color.Black, (float)0.1), new Point(e.Bounds.X + padXl, e.Bounds.Y + padY), new Point(e.Bounds.X + padXl, e.Bounds.Y + e.Bounds.Height - (2 * padY) + 1));
            }
            else
            {
                //Textbereich wird definiert
                rectText = new Rectangle(e.Bounds.X, e.Bounds.Y, e.Bounds.X + e.Bounds.Width, e.Bounds.Height);
            }

            //Text wird gezeichnet
            grfx.DrawString(currentItem.Text, e.Font, new SolidBrush(Color.Black), rectText);

            //Markierung wird gelöscht
            this.SelectionStart = 0;
            this.SelectionLength = 0;

        }

        private void OnSelectedIndexChanged(object sender, System.EventArgs e)
        {
            //Ausgewähltes Element wird ausgelesen
            currentItem = arrColorItems[this.SelectedIndex];

            //Wenn es das Benutzerdefinierte Item ist, wird der Farben Dialog angezeigt
            if (currentItem.ShowOnlyText == true)
            {
                ColorDialog dlgColor = new ColorDialog();

                if (dlgColor.ShowDialog(this) == DialogResult.OK)
                {
                    //Item mit gewählter Farbe wird eingefügt und selektiert
                    ColorItem col = new ColorItem();
                    col.ShowOnlyColor = true;
                    col.CurrentColor = dlgColor.Color;
                    arrColorItems.Insert(arrColorItems.Count - 1, col);
                    this.Items.Insert(this.Items.Count - 1, col);
                    this.SelectedIndex = this.Items.Count - 2;
                }
            }
        }

        private void OnDropDown(object sender, System.EventArgs e)
        {
            //Ausgewähltes Element wird ausgelesen
            if (this.SelectedIndex &gt; -1)
            {
                currentItem = arrColorItems[this.SelectedIndex];
            }
        }

        public void AddColorItem(Color col, string itemText)
        {
            ColorItem c = new ColorItem();
            c.CurrentColor = col;
            c.Text = itemText;

            if (bCustomColor == true)
            {
                if (this.Items.Count == 0)
                {
                    arrColorItems.Insert(0, c);
                    this.Items.Insert(0, c);
                }
                else
                {
                    arrColorItems.Insert(this.Items.Count - 1, c);
                    this.Items.Insert(this.Items.Count - 1, c);
                }
            }
            else
            {
                arrColorItems.Add(c);
                this.Items.Add(c);
            }
        }

        public bool EnableCustomColor
        {
            get
            {
                return bCustomColor;
            }
            set
            {
                if (bCustomColor == false &amp;&amp; value == true)
                {
                    bCustomColor = value;

                    //Benutzerdefiniertes Item wird eingefügt
                    ColorItem c = new ColorItem();
                    c.CurrentColor = Color.White;
                    c.Text = strCustom;
                    c.ShowOnlyText = true;
                    arrColorItems.Add(c);
                    this.Items.Add(c);
                }

                if (bCustomColor == true &amp;&amp; value == false)
                {
                    bCustomColor = value;

                    //Benutzerdefiniertes Item wird entfernt
                    for (int i = 0; i &lt;= arrColorItems.Count - 1; i++)
                    {
                        ColorItem c = (ColorItem)arrColorItems[i];
                        if (c.ShowOnlyText == true)
                        {
                            arrColorItems.RemoveAt(i);
                            this.Items.RemoveAt(i);
                        }
                    }
                }

            }
        }

        [Browsable(false)]
        public Color SelectedColor
        {
            get
            {
                return currentItem.CurrentColor;
            }
            set
            {
                //Item mit gewählter Farbe wird eingefügt und selektiert
                ColorItem col = new ColorItem();
                col.CurrentColor = value;
                col.ShowOnlyColor = true;
                arrColorItems.Insert(arrColorItems.Count - 1, col);
                this.Items.Insert(this.Items.Count - 1, col);
                this.SelectedIndex = this.Items.Count - 2;
            }
        }

        [Browsable(false)]
        public new String SelectedText
        {
            get
            {
                return currentItem.Text;
            }
            set
            {
                //Item mit entsprechendem Text wird gesucht und selektiert
                for (int i = 0; i &lt;= arrColorItems.Count - 1; i++)
                {
                    ColorItem col = (ColorItem)arrColorItems[i];
                    if (col.Text == value)
                    {
                        this.SelectedIndex = i;
                        break;
                    }
                }
            }
        }

    }

    //************************************************************************************************
    //------------------------------------------------------------------------------------------------
    //************************************************************************************************

    public class ColorItem
    {
        private Color m_Color;
        private String m_Text = &quot;&quot;;
        private bool m_bOnlyText;
        private bool m_bOnlyColor;

        public ColorItem()
        {

        }

        public Color CurrentColor
        {
            get { return this.m_Color; }
            set { this.m_Color = value; }
        }

        public String Text
        {
            get { return this.m_Text; }
            set { this.m_Text = value; }
        }

        public bool ShowOnlyText
        {
            get { return this.m_bOnlyText; }
            set { this.m_bOnlyText = value; }
        }

        public bool ShowOnlyColor
        {
            get { return this.m_bOnlyColor; }
            set { this.m_bOnlyColor = value; }
        }
    }

    //************************************************************************************************
    //------------------------------------------------------------------------------------------------
    //************************************************************************************************
}
</pre>
]]></content:encoded>
			<wfw:commentRss>http://www.c-sharp.ch/2009/08/colorcombobox/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Multithreading</title>
		<link>http://www.c-sharp.ch/2009/08/multithreading/</link>
		<comments>http://www.c-sharp.ch/2009/08/multithreading/#comments</comments>
		<pubDate>Mon, 10 Aug 2009 22:14:34 +0000</pubDate>
		<dc:creator>admin</dc:creator>
				<category><![CDATA[Allgemein]]></category>

		<guid isPermaLink="false">http://preview.c-sharp.ch/?p=3</guid>
		<description><![CDATA[Multithreading kommt dann zum Zug wenn im Hintergrund mehrere Dinge gleichzeitig geschehen sollen. Dies kann die unterschiedlichsten Gründe haben. Ein bekannter Grund um Multithreading einzusetzen ist sicherlich der Umstand, dass das GUI nicht mehr auf Benutzereingaben reagiert, solange im Hintergrund eine komplexe Berechnung stattfindet. Um nun auf eine einfache Art und Weise zu zeigen wie [...]]]></description>
			<content:encoded><![CDATA[<p>Multithreading kommt dann zum Zug wenn im Hintergrund mehrere Dinge gleichzeitig geschehen sollen. Dies kann die unterschiedlichsten Gründe haben. Ein bekannter Grund um Multithreading einzusetzen ist sicherlich der Umstand, dass das GUI nicht mehr auf Benutzereingaben reagiert, solange im Hintergrund eine komplexe Berechnung stattfindet. Um nun auf eine einfache Art und Weise zu zeigen wie Multithreading in C# funktioniert, habe ich eine kleine Konsolen-Applikation geschrieben. Diese führt immer den gleichen Code aus, mit dem Unterschied, dass man nach dem Starten der Anwendung wählen kann ob man im Multithreading-Modus weiterfahren möchte oder nicht. Das Programm gibt lediglich Outputs auf das Konsolenfenster. Durch diese Ausgabe ist klar ersichtlich, wann welcher Thread die Rechenzeit zugesprochen erhalten hat. Hat man das Multithreading eingeschaltet, wechseln sich die beiden Threads ab, während im &#8220;normalen&#8221; Modus alles nacheinander ausgegeben wird.</p>
<p><a href="http://preview.c-sharp.ch/wp-content/uploads/2009/08/MultiThreading.zip"><img class="alignnone size-thumbnail wp-image-19" title="zip_icon" src="http://preview.c-sharp.ch/wp-content/uploads/2009/08/zip_icon1-150x150.jpg" alt="zip_icon" width="60" height="60" /></a></p>
<pre class="brush: csharp; collapse: false;">

using System;
using System.Threading;

namespace MultiThreading
{
    class Program
    {
        static void Main(string[] args)
        {
            ConsoleKeyInfo keyAnswer;

            //Solange Fragen bis entweder Y oder N gedrückt wurde
            do
            {
                Console.Clear();
                Console.WriteLine(&quot;Möchten Sie die Applikation im Multithreading Modus starten? (Y/N)&quot;);
                keyAnswer = Console.ReadKey(true);
            }
            while (keyAnswer.Key != ConsoleKey.Y &amp;&amp; keyAnswer.Key != ConsoleKey.N);

            //Je nach dem was gewählt wurde, die Methoden im entsprechenden Modus ausführen
            switch (keyAnswer.Key)
            {
                case ConsoleKey.Y:
                    //Threading Modus
                    Thread t1 = new Thread(new ThreadStart(ThreadOneOutput));
                    Thread t2 = new Thread(new ThreadStart(ThreadTwoOutput));
                    t1.Start();
                    t2.Start();
                    break;

                case ConsoleKey.N:
                    //Normaler Modus
                    ThreadOneOutput();
                    ThreadTwoOutput();
                    break;
            }

            //Wartet auf irgendeine Eingabe und beendet das Programm danach
            Console.ReadKey(true);

        }

        /// &lt;summary&gt;
        /// Methode welche als erster Thread ausgeführt werden kann
        /// &lt;/summary&gt;
        private static void ThreadOneOutput()
        {
            for (int i = 1; i &lt;= 50; i++)
            {
                Console.WriteLine(&quot;Thread 1: Output Nr. &quot; + i.ToString());
            }
        }

        /// &lt;summary&gt;
        /// Methode welche als zweiter Thread ausgeführt werden kann
        /// &lt;/summary&gt;
        private static void ThreadTwoOutput()
        {
            for (int i = 1; i &lt;= 50; i++)
            {
                Console.WriteLine(&quot;Thread 2: Output Nr. &quot; + i.ToString());
            }
        }
    }
}
</pre>
]]></content:encoded>
			<wfw:commentRss>http://www.c-sharp.ch/2009/08/multithreading/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
	</channel>
</rss>

