Biggle's Blog

Web- und Software Development

by Mario Priebe

Biggle ist kein Palindrom

Eine kleine Übungsaufgabe für mich, die es zu lösen gab. Es sollte heraus gefunden werden, ob es sich bei einem String um ein Palindrom handelt.

Mein Lösungsansatz lautet wie folgt:
Ich befreie zunächst die Buchstaben von Sonder- und Leerzeichen und konvertiere alle Zeichen zu Kleinbuchstaben. Dann durchlaufe ich eine for-Schleife mit eine Länge des Stringparameters.

Ich zerlege den String in ein CharArray und vergleiche innerhalb der Schleife, den vorderen mit den letzten Buchstaben. Sind diese gleich wird der nächste vordere und der nächste hintere Buchstabe verglichen. Das geht so lange bis diese sich in der Mitte treffen.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
public static class ExtensionMethods
{
    public static bool IsPalindrome(this string value)
    {
        //von Leer- und Sonderzeichen befreien
        value = value.ToLower().RemoveSpecialCharacters();
 
        int minValue = 0;
        int maxValue = value.Length - 1;
 
        var charArray = value.ToCharArray();
 
        for (int i = 0; i < value.Length - 1; i++)
        {
            if (charArray[minValue] == charArray[maxValue])
            {
                minValue++;
                maxValue--;
                continue;
            }
            else
                return false;
        }
        return true;
    }
 
    public static string RemoveSpecialCharacters(this string value)
    {
        return Regex.Replace(value, @"[^a-zA-Z0-9]", string.Empty);
    }
}

Verwendung:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
class Program
{
    static void Main(string[] args)
    {
        PalindromFactory factory = new PalindromFactory();
        var palindrome = factory.GetPalindrome();
        string output = "{0} ist {1}ein Palindrom";
 
        foreach (var palindrom in palindrome)
        {
            Console.WriteLine(String.Format(output, palindrom, palindrom.IsPalindrome() ? "" : "k"));
        }
 
        var palindromSaetze = factory.GetPalindromSaetze();
        foreach (var palindrom in palindromSaetze)
        {
            Console.WriteLine(String.Format(output, palindrom, palindrom.IsPalindrome() ? "" : "k"));
        }
    }
}

Ich hoffe ich habe nichts vergessen, getestet jedoch habe ich diese Methode mit der Liste deutscher Palindrome aus Wikipedia. Nicht-Palindrome natürlich mit einbegriffen : )

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
/// Stellt eine Sammlung von Palindrome und Palindromsätze bereit
/// Quelle Wikipedia
/// http://de.wikipedia.org/wiki/Liste_deutscher_Palindrome
public class PalindromFactory
{
    private List<string> Palindrome { get; set; }
 
    public List<string> GetPalindrome()
    {
        Palindrome = new List<string>
        {
            "Aha",
            "Amokoma",
            "Amoralaroma",
            "Anina",
            "Anna",
            "Annasusanna",
            "Aua",
            "Bob",
            "Bub",
            "Burggrub",
            "Biggle", //kein Palindrom
            "Mario", //kein Palindrom
            "Mongognom",
            "Nebelleben",
            "neben",
            "Neffen",
            "nennen",
            "netten",
            "netzten",
            "Neozoen",
            "nun",
            "Omo",
            "Otto",
            "Priebe" //kein Palindrom
            };
 
        return Palindrome;
    }
 
    public List<string> GetPalindromSaetze()
    {
        Palindrome = new List<string>
        {
            "Die Liebe fleht: Helfe bei Leid!",
            "Die Liebe geht, hege Beileid!",
            "Die Liebe, ist sie Beileid?",
            "Die Liebe ist Sieger, rege ist sie bei Leid.",
            "Die Liebe ist Sieger, stets rege ist sie bei Leid.",
            "Die Niere bot Komik: nass sank im Oktober ein Eid.",
            "Die Rede — ist sie der Eid?",
            "Dreh Magiezettel um, Amulette zeig am Herd!",
            "Du, erfror Freud?",
            "Der Fred",
            "Eine güldne, gute Tugend: Lüge nie!",
            "Eine Horde bedrohe nie!",
            "Eine Hure ruhe nie.",
            "Eine Note betone nie.",
            "Eine so Kesse kose nie.",
            "Eine treue Familie bei Lima feuerte nie.",
            "Einhorn roh? Nie!",
            "Eins nutzt uns: Amore. Die Rederei da, die Rederei der Omas nutzt uns nie.",
            "Eis feil! Ei, wo Eis feil lief sie, o wie lief sie.",
            "Elietta hat Teile.",
            "Ella rüffelte Detlef für alle.",
            "Elly biss Sibylle.",
            "Emma, behend 'ne Hebamme!",
            "Emma, so litt Tilos Amme!",
            "Emmas Amme",
            "Er habe nie eine Bahre.",
            "Erhabene Bahre",
            "Erhöre nie eine Röhre.",
            "Erika feuert nur untreue Fakire.",
            "Erol, red nie in der Lore.",
            "Alles hat seine Zeit, nur die alten Weiber nicht.", //Kein Palindromsatz
            "Es eilt, immer ahnend Nebel, reger der Flegel Fred, reg' erlebend nen Harem mit Liese.",
        };
 
        return Palindrome;
 
    }
}

Für einen schnellen Verwendungszeck (weil man das auch so oft braucht oO)  habe ich das ganze als ExtensionMethod implementiert.

Wie schaut’s aus, hast du Verbesserungsvorschläge? Würdest du es anders machen, wenn ja wie? Du kannst im Kommentarfeld mit

<strong>var* </strong>deinCodeSnippet = 0;

posten.


Viel Spaß beim entwickeln : )


* = Var oder nicht var…

by Mario Priebe

Windows Phone 7 – Push Notification

Push Notifications erstellen einen Nachrichtenkanal zwischen dem Microsoft Push Notification (MPN) Service und einem Push Client wie z.B. das Windows Phone 7. Ein MPN Service kann einem Client, welcher diesen externen Service abonniert hat, Nachrichten schicken ohne das dieser ständig nach Nachrichten triggern, oder eine Verbindung aufrecht erhalten muss. Einen Überblick der Funktionsweise bekommt man im MSDN.

Ich hab mich mal ran gemacht und eine Applikation erstellt, die  diesen Service konsumiert. Die Beispielapplikation besteht aus einen WCF Service, einer WPF Applikation und einer Windows Phone 7 Applikation. Die WPF Applikation sendet eine Nachricht an den WCF Service und die WP7 Applikation abonniert eine Push Notification um diese Nachricht zu erhalten.

Projektstruktur

Dazu erstellen wir uns eine Solution mit einem Windows-Phone Projekt (WindowsPhonePushNotification), fügen eine WCF Dienstbibliothek (WindowsPhonePushNotificationService)  und eine WPF-Anwendung (WindowsPhonePushNotificationClient) hinzu.

Der WCF Service

Der Contract besteht aus zwei Methoden. Subscribe und SendToast:

1
2
3
4
5
6
7
8
9
[ServiceContract]
public interface IService1
{
    [OperationContract]
    void Subscribe(string url);
 
    [OperationContract]
    void SendToast(string title, string message);
}

Die Implementierung des Contracts sieht wie folgt aus:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
private static Uri _uri;
public void Subscribe(string url)
{
    _uri = new Uri(url);
}
 
public void SendToast(string title, string message)
{
    string toastMsg = "<?xml version=\"1.0\" encoding=\"utf-8\"?>" +
        "<wp:Notification xmlns:wp=\"WPNotification\">" +
            "<wp:Toast>" +
                "<wp:Text1>" + title + "</wp:Text1>" +
                "<wp:Text2>" + message + "</wp:Text2>" +
            "</wp:Toast> " +
        "</wp:Notification>";
 
    byte[] messageBytes = System.Text.Encoding.UTF8.GetBytes(toastMsg);
    SendMessage(_uri, messageBytes);
}
 
private static void SendMessage(Uri uri, byte[] message)
{
    HttpWebRequest request = (HttpWebRequest)WebRequest.Create(uri);
    request.Method = WebRequestMethods.Http.Post;
    request.ContentType = "text/xml";
    request.ContentLength = message.Length;
    request.Headers.Add("X-MessageID", Guid.NewGuid().ToString());
    request.Headers["X-WindowsPhone-Target"] = "toast";
    request.Headers.Add("X-NotificationClass", "2");
 
    var requestStream = request.GetRequestStream();
    requestStream.Write(message, 0, message.Length);
}

Das Binding in der App.config muss auf basicHttpBinding geändert werden:

1
<endpoint address ="" binding="basicHttpBinding" contract="WindowsPhonePushNotificationService.IService1">

WPF Push Application

Den eben erstellen WCF Service werden wir hier in der WPF Applikation als Service Reference hinzufügen.

Die WPF Applikation versendet unter Verwendung des WCF Services eine Nachricht an das Windows Phone. Hier werden wir lediglich zwei Textboxen für Titel und Nachricht und einen Button zum Absenden erstellen.

1
2
3
4
5
6
7
8
9
<StackPanel>
    <Label Content="Titel" />
    <TextBox Name="txtBoxTitle" />
 
    <Label Content="Nachricht" />
    <TextBox Height="50" AcceptsReturn="True" Name="txtBoxMessage" />
 
    <Button Content="Push Message" Click="Button_Click" Height="25" Width="150" />
</StackPanel>

Der Button ruft nun die Methode SendToast am ServiceClient auf. Da der NotificationService manchmal etwas Zeit benötigt, packen wir den Aufruf in einen BackgroundWorker.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
private void Button_Click(object sender, RoutedEventArgs e)
{
    Title = txtBoxTitle.Text;
    Message = txtBoxMessage.Text;
 
    BackgroundWorker worker = new BackgroundWorker();
    worker.DoWork += new DoWorkEventHandler(worker_DoWork);
    worker.RunWorkerAsync();
}
 
void worker_DoWork(object sender, DoWorkEventArgs e)
{
    using (var client = new Service1Client())
    {
        client.SendToast(Title, Message);
    }
}


Windows Phone 7 Push Notification Implementierung

Wie in der WPF Anwendung müssen wir auch hier den WCF Service referenzieren. Visual Studio erstellt nun eine Datei namens “ServiceReferences.ClientConfig”. Diese müssen wir nun öffnen und den Service konfigurieren.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
<configuration>
  <system.web>
    <compilation debug="true" />
  </system.web>
  <system.serviceModel>
    <bindings>
      <basicHttpBinding>
        <binding name="myService" closeTimeout="00:01:00"
          openTimeout="00:01:00" receiveTimeout="00:10:00" sendTimeout="00:01:00"
          maxReceivedMessageSize="65536" />
        <binding name="BasicHttpBinding_IService1" maxBufferSize="2147483647"
          maxReceivedMessageSize="2147483647">
          <security mode="None" />
        </binding>
      </basicHttpBinding>
    </bindings>
    <client>
      <endpoint address="http://localhost:8732/Design_Time_Addresses/WindowsPhonePushNotificationService/Service1/"
        binding="basicHttpBinding" bindingConfiguration="myService"
        contract="ServiceReference1.IService1" name="myService" />
    </client>
  </system.serviceModel>
</configuration>

Nun ziehen wir uns im Designer eine TextBox auf unser Phone und setzen diese etwas in Position.

Nun wechseln wir in die  CodeAnsicht und implementieren folgenden Code:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
private HttpNotificationChannel _channel;
private string _channelName = "MeinPushNotificationService";
 
public MainPage()
{
    InitializeComponent();
    SetupNotificationChannel();
}
 
private void SetupNotificationChannel()
{
    _channel = HttpNotificationChannel.Find(_channelName);
 
    if (_channel == null)
    {
        _channel = new HttpNotificationChannel(_channelName);
 
        _channel.ChannelUriUpdated += (notificationChannel_ChannelUriUpdated);
        _channel.Open();
    }
    else
        RegisterForNotfication();
}
 
private void notificationChannel_ChannelUriUpdated(object sender, NotificationChannelUriEventArgs e)
{
    _channel = HttpNotificationChannel.Find(_channelName);
 
    if (!_channel.IsShellToastBound)
        _channel.BindToShellToast();
    RegisterForNotfication();
}
 
private void RegisterForNotfication()
{
    var client = new ServiceReference1.Service1Client();
    client.SubscribeAsync(_channel.ChannelUri.ToString());
    client.SubscribeCompleted += new EventHandler<System.ComponentModel.AsyncCompletedEventArgs>(client_SubscribeCompleted);
    _channel.ShellToastNotificationReceived += (s, e) => Deployment.Current.Dispatcher.BeginInvoke(() => ToastReceived(e));
}
 
void client_SubscribeCompleted(object sender, System.ComponentModel.AsyncCompletedEventArgs e)
{
    textBlock1.Text = "PushService active";
}
 
private void ToastReceived(NotificationEventArgs e)
{
    textBlock1.Text = String.Format("Title: {0} \nMessage: {1}", e.Collection["wp:Text1"], e.Collection["wp:Text2"]);
}


Projekt starten

Als Startprojekte legen wir alle Projekte fest, die sich in der Solution befinden.


Jetzt debuggen wir das Ganze mit F5. Wenn in der WP7 Anwendung “PushService active” erscheint, wurde vom  MPN Service eine URL zugwiesen.

Und wir können in der WPF Applikation Title und Nachricht eingeben und absenden. Wenn alles glatt geht, sollte im Windows Phone Emulator nun die Nachricht erscheinen:


Wer möchte kann sich das Beispielprojekt hier herunterladen.

Viel Spaß beim entwickeln: )


Informationsmaterial:

by Mario Priebe

Bing API Beispiel – C# Quicky

Am folgenden Beispiel möchte ich zeigen, wie man die Bing Api verwendet.

Vorerst muss man sich im Bing Developer Center einen API Key registrieren. Das geht recht einfach und ist schnell erledigt.

Nun fügt man seinem Projekt eine ServiceReferenz über folgender URL hinzu:

http://api.bing.net/search.wsdl?AppID=YourAppId&amp;Version=2.2

YourAppId muss mit dem Key ersetzt werden.

Der nachfolgende Code zeigt eine Beispiels-Implementierung in einer Konsolenapplikation.

Klasse Bing:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
using System;
using BIngApiTest23432.BingService;
using System.Threading;
 
namespace BIngApiTest23432
{
    public class Bing
    {
        private static string Api { get; set; }
 
        public string Url { get; set; }
        public string DisplayUrl { get; set; }
        public string Title { get; set; }
        public string Desc { get; set; }
        public bool IsLoading { get; set; }
        public SourceType SourceType { get; set; }
 
        public Bing(string api) { Api = api; }
 
        public SearchResponse Lookup(string query)
        {
            IsLoading = true;
            Thread tr = new Thread(new ThreadStart(Loading));
            tr.Start();
 
            var response = new SearchResponse();
            using (var service = new BingPortTypeClient())
            {
                try
                {
                    var request = new SearchRequest();
                    request.AppId = Api;
                    request.Query = query;
                    request.Sources = new SourceType[] { SourceType };
                    response = service.Search(request);
                    IsLoading = false;
                }
                catch (System.Net.WebException ex) { }
            }
 
            return response;
        }
 
 
        public void Loading()
        {
            while (IsLoading)
            {
                Console.Write(".");
                Thread.Sleep(100);
            }
        }
    }
}

Klasse Program

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
using System;
using BIngApiTest23432.BingService;
using Microsoft.CSharp.RuntimeBinder;
using System.Collections.Generic;
using System.Diagnostics;
 
namespace BIngApiTest23432
{
    class Program
    {
        private const string API = "YOUR API KEY";
        static List<string> _urls;
 
        static void Main(string[] args)
        {
            CallBingMethod();
        }
 
        public static void CallBingMethod()
        {
            Bing bing = new Bing(API);
 
            var menu = "choose the search :\r\n(W)eb, (I)mage, (S)pell, (R)elated Search, (P)honebook, (C)lear, E(x)it";
 
            Console.WriteLine(menu);
            ConsoleKeyInfo key;
 
            do
            {
                key = Console.ReadKey();
 
                SearchResponse response = new SearchResponse();
 
                switch (key.Key)
                {
                    case ConsoleKey.C:
                        Console.Clear();
                        break;
                    case ConsoleKey.W:
                        Console.WriteLine("\r(W)ebsuche \r\nBitte Begriff eingeben: ");
                        bing.SourceType = SourceType.Web;
                        response = bing.Lookup(Console.ReadLine());
                        break;
                    case ConsoleKey.I:
                        Console.WriteLine("\r(I)magesuche \r\nBitte Begriff eingeben: ");
                        bing.SourceType = SourceType.Image;
                        response = bing.Lookup(Console.ReadLine());
                        break;
                    case ConsoleKey.S:
                        Console.WriteLine("\r(S)pellsuche \r\nBitte Begriff eingeben: ");
                        bing.SourceType = SourceType.Spell;
                        response = bing.Lookup(Console.ReadLine());
                        break;
                    case ConsoleKey.R:
                        Console.WriteLine("\r(R)elated Search \r\nBitte Begriff eingeben: ");
                        bing.SourceType = SourceType.RelatedSearch;
                        response = bing.Lookup(Console.ReadLine());
                        break;
                    case ConsoleKey.P:
                        Console.WriteLine("\r(P)honebook Search \r\nBitte Begriff eingeben: ");
                        bing.SourceType = SourceType.Phonebook;
                        response = bing.Lookup(Console.ReadLine());
                        break;
                    default:
                        break;
                }
 
                if (key.Key != ConsoleKey.C && key.Key != ConsoleKey.X)
                    DisplayResult(response, bing.SourceType);
 
 
                if (_urls != null && _urls.Count > 1)
                {
                    Console.WriteLine("choose the number to call the url in your browser");
                    key = Console.ReadKey();
 
                    if (key.Key >= ConsoleKey.D0 && key.Key <= ConsoleKey.D9)
                    {
                        var k = Convert.ToInt32(key.Key.ToString().TrimStart('D'));
                        k = k == 0 ? 10 : k;
 
                        Console.WriteLine(" - you choosed: {0}", _urls[k]);
                        Process.Start(_urls[k]);
                    }
 
                }
 
                Console.WriteLine("\n" + menu);
 
            }
            while (key.Key != ConsoleKey.X); //|| key.Modifiers != ConsoleModifiers.Alt);
 
        }
 
        public static void DisplayResult(SearchResponse searchResponse, SourceType sourceType)
        {
            dynamic results = null;
            _urls = new List<string>();
            _urls.Add(String.Empty);
 
            switch (sourceType)
            {
                case SourceType.Spell:
                    results = searchResponse.Spell != null ? searchResponse.Spell.Results : null;
                    break;
                case SourceType.Web:
                    results = searchResponse.Web != null ? searchResponse.Web.Results : null;
                    break;
                case SourceType.Image:
                    results = searchResponse.Image != null ? searchResponse.Image.Results : null;
                    break;
                case SourceType.RelatedSearch:
                    results = searchResponse.RelatedSearch != null ? searchResponse.RelatedSearch.Results : null;
                    break;
                case SourceType.Phonebook:
                    results = searchResponse.Phonebook != null ? searchResponse.Phonebook.Results : null;
                    break;
                case SourceType.Video:
                    results = searchResponse.Video.Results != null ? searchResponse.Video.Results : null;
                    break;
                case SourceType.InstantAnswer:
                    results = searchResponse.InstantAnswer.Results != null ? searchResponse.InstantAnswer.Results : null;
                    break;
                case SourceType.News:
                    results = searchResponse.News.Results != null ? searchResponse.News.Results : null;
                    break;
                case SourceType.MobileWeb:
                    results = searchResponse.MobileWeb.Results != null ? searchResponse.MobileWeb.Results : null;
                    break;
                case SourceType.Translation:
                    results = searchResponse.Translation.Results != null ? searchResponse.Translation.Results : null;
                    break;
                default:
                    break;
            }
 
 
            if (results != null)
            {
                Console.WriteLine("\r\nResult:");
                foreach (var result in results)
                {
                    try
                    {
                        Console.WriteLine(result.Url);
                        _urls.Add(result.Url);
                    }
                    catch (RuntimeBinderException) { Console.WriteLine(result.Value); }
                }
            }
            else
                Console.WriteLine("\r\nLeider nichts gefunden");
        }
    }
}

Resources:

Viel Spaß beim entwickeln : )


by Mario Priebe

Einfaches Beispiel eines asynchronen Methodenaufrufs

Threading ist ein sehr komplexes Thema und es gibt auch genügend Alternativen Prozesse zeitgleich zu starten. Siehe BackgroundWorker, Task, Linqextension Parallel und Konsorten sowie asynchronen Methoden an WebServices und mehr…

Im Folgenden wird an einem recht einfachen Beispiel versucht zu veranschaulichen, wie man Arbeitsaufgaben mit einfachen .NET Mitteln parallel erledigen kann. Also wie man quasi eine Methode in einem anderen Thread aufrufen kann, die die Arbeit im Hintergrund erledigen soll ohne den anderen, aufrufenden Thread zu blockieren.

Ich erstelle mir dazu eine Methode welche aus der Programmlogik aufgerufen werden soll. Diese verwendet eine weitere Methode, die die eigentliche Arbeit übernimmt. Damit ich der asynchronen Methode auch Parameter mitgeben kann, verwende ich zusätzlich der normalen Thread-Klasse die Klasse ParameterizedThreadStart, weil es durch diese ermöglicht wird, Parameter an die Jobmethode weiterzuleiten.

Die notwendigen Parameter halte ich in der Klasse Namens “AsyncData”, die zu den Daten auch eine boolesche Variable beinhaltet. Mit dieser Variable ist es mir möglich zu prüfen wann der asynchrone Prozess denn erledigt ist. Damit ich keine Problem bekomme, wenn beide Threads auf diese Variable zugreifen wollen verwende ich das Schlüsselwort volatile.

Klasse Asyncdata:

1
2
3
4
5
6
protected class AsyncData
{
    public List<Person> Personen = new List<Person>();
    public int PersonenRequired { get; set; }
    public volatile bool IsCompleted;
}

Dieses Methode erstellt die den Arbeitsthread und lässt über eine weitere Methode den Job erledigen.

1
2
3
4
5
6
private static void GetPersonen(AsyncData data)
{
    ParameterizedThreadStart pts = new ParameterizedThreadStart(GetPersonenJob);
    Thread thread = new Thread(pts);
    thread.Start(data);
}

Die folgende Methode erledigt den Job und setzt die boolesche Variable, wenn die Arbeit erledigt ist auf true

1
2
3
4
5
6
7
8
9
10
11
12
13
private static void GetPersonenJob(object result)
{
    AsyncData asyncData = (AsyncData)result;
 
    //Beispiel Job, der viel zeit in Anspruch nimmt (ggfl. Anzahl der Personen erhoehen)
    for (int i = 0; i < asyncData.PersonenRequired; i++)
    {
        var p = new Person() { Age = i, Firstname = "Bla" + i, Name = "Blubb" + i };
        asyncData.Personen.Add(p);
    }
    //Job erledigt
    asyncData.IsCompleted = true;
}

Der Aufruf im Programm, stellt sich wie folgt dar:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
static void Main(string[] args)
{
    AsyncData asyncData = new AsyncData();
    asyncData.PersonenRequired = 1000000;
    GetPersonen(asyncData);
 
    //an der Stelle verwende ich die boolesche Variable und zu pruefen ob der Job erledigt ist.
    while (!asyncData.IsCompleted)
        Thread.Sleep(1);
 
    foreach (var person in asyncData.Personen)
    {
        Console.WriteLine("{0},{1} Alter: {2}", person.Name, person.Firstname, person.Age);
    }
 
    Console.ReadLine();
}

//Beispielklasse

1
2
3
4
5
6
internal class Person
{
public string Name { get; set; }
public string Firstname { get; set; }
public int Age { get; set; }
}

Viel Spass beim entwickeln : )

by Mario Priebe

Das WPF Control “Popup” – HowTo

Das WPF Control Popup kann ein eigenständiges Fenster in einer WPF Applikation darstellen und wie ein Tooltip beim Überfahren von Elementen angezeigt werden. Ein Popup kann als Kindelement ein weiteres UIElement aufnehmen, was so einem weiteren Design des Popups, nichts im Wege stehen sollte.

Die Position kann relativ zum Element oder zur Applikation geöffnet werden. Das Popup verhält sich auch wie ein eigenständiges Fenster, das heisst wird die Mainapplikation verschoben, bleibt das Popup an der letzten Position stehen.

Ein Popup wird nicht wie ein Tooltip automatisch geöffnet, sondern muss explizit durch dessen Eigenschaft IsOpen geöffnet und geschlossen werden.

Die Anzeigeposition wird durch die Placement-Eigenschaften festgelegt. Zu welchem Element sich die Placements beziehen, legt man an der Property PlacementTarget fest. Die X und die Y Koordinate HorizontalOffset und VertracalOffset setzt man bei einem gewählten “Absolute” oder “Relative” Placement aus der Enumeration PlacementMode.

Weitere Eigenschaften an dem Control sind PopupAnimation und AllowsTransparency. Will man ein Popup animieren (Fade, None, Scroll, Slide) muss AllowsTransparency auf true gesetzt werden.

Das folgende Beispiel soll das gesagte etwas verdeutlichen. Hier beziehe ich mein Placement relativ zur Applikation(window), den Bezug stellt man über ElementName her.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
<Window x:Class="PopupHowTo.Window1"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    Title="Window1" Height="300" Width="300" Name="myWindow">
<StackPanel HorizontalAlignment="Left">
 
<TextBox Width="100" Name="txtBox" MouseEnter="txtBox_MouseEnter" MouseLeave="txtBox_MouseLeave" />
 
<Popup Name="popUp" PlacementTarget="{Binding ElementName=myWindow}" Placement="Relative" VerticalOffset="30" HorizontalOffset="100"
   PopupAnimation="Slide" AllowsTransparency="True">
</Popup>
 
</StackPanel>
</Window>

CodeBehind

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
public partial class Window1 : Window
{
MyUserControl uc;
public Window1()
{
    InitializeComponent();
    Loaded += new RoutedEventHandler(Window1_Loaded);
}
 
void Window1_Loaded(object sender, RoutedEventArgs e)
{
    uc = new MyUserControl();
    popUp.Child = uc;
}
 
private void txtBox_MouseEnter(object sender, MouseEventArgs e)
{
    uc.HelpText = "Ich bin ein Hilfetext für eine TextBox";
    popUp.IsOpen = true;
}
 
private void txtBox_MouseLeave(object sender, MouseEventArgs e)
{
    popUp.IsOpen = false;
}
}

HelpText ist ein ViewModelProperty in MyUserControl.

Viel Spass beim entwickeln : )


by Mario Priebe

WCFService testen

Um einen WCFService zu testen, muss man diesen sowohl als Client als auch als Host bereitstellen. Um den WCFService auch als Host bereitzustellen ergänzt man im TestProjekt die app.config innerhalb <system.servicemodel> um folgendes Element

1
2
3
4
5
6
<services>
	<service name="MyDataService">
		<endpoint address="http://localhost:8731/Design_Time_Addresses/MyDataService/MyDataService/"
            binding="wsHttpBinding" bindingConfiguration="" contract="MyDataService.Contract.IMyDataService" />
	</service>
</services>

Im TestFixtureSetUp der Testklasse, muss der ServiceHost dann geöffnet werden.

1
2
_host = new ServiceHost(typeof(MyDataService));
_host.Open();

_host ist eine Instanz von ServiceHost aus System.ServiceModel

Im TestFixtureTearDown sollte dieser dann auch wieder geschlossen werden

1
2
3
4
5
try { _host.Close(); }
finally
{
    ((IDisposable)_host).Dispose();
}

“MyDataService” natürlich anpassen ; )