Laden...

Forenbeiträge von vita85 Ingesamt 20 Beiträge

19.06.2012 - 09:02 Uhr

Hallo,
ich bin gerade dabei mir ein Programm zu basteln, bei dem die Oberfläche komplett selbst gestaltet ist, also sprich: mit den Attributen

AllowsTransparency="True" WindowStyle="None" Background="Transparent"

versehen ist.

Dies hat den Nachteil, dass ich leider die Fenstergröße nicht ändern kann, obwohl der "ResizeMode" auf "CanResize". Ich denke mal das hängt damit zusammen, dass der Rahmen des Standard-Layout nicht mehr verfügbar ist.

Ist es dennoch irgendwie möglich das Fenster in der Größe zu verändern?

28.09.2011 - 08:10 Uhr

Da du geschrieben hast das du dein Projekt in Richtung MVVM umgestaltet hast gehe ich mal davon aus das du noch nicht damit fertig bist (oder eben noch nicht richtig verstanden 😉

Beides 😄.
Wobei mir das Design mehr Schwierigkeiten bereitet der Code an sich.

27.09.2011 - 16:56 Uhr

Du kannst den DataContext auch in der MainWindow.xaml setzen:

    <Window.DataContext>  
        <ViewModels:MainWindowViewModel/>  
    </Window.DataContext>  

Ok, habe ich jetzt so gemacht (hat was gedauert, weil ich noch mit meinem Chef reden musste). Danke dir.
Also habe ich es richtig verstanden, dass die Codebehind-Dateien nach Möglichkeit leer bleiben sollten.
Das macht es für mich jetzt dann erstmal was schwerer die "umfangreicheren" Methoden - wie zum Beispiel die Verbindung zu einem Server (siehe Menüleiste) - zu implementieren.

27.09.2011 - 13:56 Uhr

Also wenn ich mir das so ansehe würde ich mal behaupten dass
>
für dich interessant sein könnte

Ich hab keine Zeit mehr noch großartig viel zeit fürs lernen zu "verschwenden". Dies ist mein IHK Abschlussprojekt, ich hab nur noch 5 Wochen Zeit und es geht auch so nur schleppend voran. Da kann ich leider keine Zeit erübrigen mir noch auf eigene Faust ein Framework beizubringen 😕. Wenn ich alles abgegeben habe, dann gern. Werde dann so oder so noch Feinheiten justieren müssen.

27.09.2011 - 13:47 Uhr

Ich hab mehrere Datacontexts fürs MainWindow, weil einer zu gigantisch werden würde... Habe mal ein Bild in den Anhang gepackt, damit du dir ein Bild von der GUI machen kannst.

Ich wollte ein ViewModel für die Statusleiste, eines für die Menüleiste und ein ViewModel pro Tabitem.

27.09.2011 - 13:39 Uhr

Titel geändert. Danke für den Hinweis. Hatte irgendwie noch was anderes im Kopf, als ich das getippt habe.

Zum Thema: Ok, also den Datacontext, der zu Komponenten im MainWindow gehört, trag ich dann auch im Konstruktor des MainWindow ein?
Das klingt auf Anhieb zwar logisch, aber ich meine mal gelesen zu haben, dass die Code-behind Dateien, die an den Views hängen immer leer sind.

Datenkontext im Konstruktor des Mainwindow funktioniert jedenfalls. Danke schonmal.

Edit: In der Statusleiste ist ein Label. Das wird nicht geändert, wenn ich den Datenkontext versuche in der App.xaml.cs zu setzen. Setze ich den Datenkontext in MainWindow.xaml.cs (im Konstruktor), dann gehts.

27.09.2011 - 13:14 Uhr

Hallo. Nach den gestrigen Problemen und der damit zusammenhängenden Lösungsfindung habe ich mich dazu entschlossen mein aktuelles Projekt komplett über den Haufen zu werfen und neu aufzusetzen. Diesmal alles gut lesbar, strukturiert und vor allem vorher durchgeplant. Also sprich: ich habe neu angefangen, aber diesmal nach dem MVVM-Pattern.

Nachdem ich nun Ordner für View, Model und ViewModel erstellt habe und einiges an Code getippt habe, musste ich feststellen, dass meine Statusleiste (mal wieder 😦 ) nicht funktioniert. Ich denke es hängt damit zusammen, dass der DataContext nicht richtig erkannt wird, aber nach einigem, erfolglosem durchprobieren komme ich zu keiner funktionierenden Lösung.

Das MainWindow.xaml befindet sich im Ordner "View" (habe es vom Standard Projektordner verschoben).
Meine App.xaml.cs sieht folgendermaßen aus:


using System.Windows;
using BBS_EMC_v2.ViewModel;

namespace BBS_EMC_v2 {
    /// <summary>
    /// Interaction logic for App.xaml
    /// </summary>
    public partial class App : Application {
        protected override void OnStartup(StartupEventArgs e) {
            base.OnStartup(e);

            MainWindow window = new MainWindow();
            ViewModelStatusleiste VMStatusLeiste = new ViewModelStatusleiste();

            window.statusbar1.DataContext = VMStatusLeiste;

            window.Show();
        }
    }
}

Füge ich testweise alles in den Konstruktor der MainWindow.xaml.cs ein, läuft es.

Hat jemand von euch vielleicht eine Idee?

26.09.2011 - 09:27 Uhr

Hallo, habe mal wieder ne Kleinigkeit, die mir zu schaffen macht und ich bekomme es nicht richtig hin 😦.

Ich habe ein Array, in dem eine Liste von Programmen (Name, Directory, Status, Description) hinterlegt ist.
Die Attribute "Name" und "Status" werden über Databinding in einer ListView angezeigt. Das funktioniert soweit auch ganz gut.

Das Problem ist nun: Ich habe neben der ListView 4 weitere Labels, die alle Attribute des gewählten ListView-Eintrags (also Name, Description, Status und Directory) anzeigen sollen und ich hab absolut keine Idee, wie ich diese Labls so an das Array binde, dass die Informationen des ausgewählten Programms aus der ListView im Label angezeigt werden.

Hoffe ich habe alles verständlich genug formuliert.

09.09.2011 - 19:27 Uhr

Perfekt, danke dir schonmal soweit 😁

09.09.2011 - 19:20 Uhr

Das kannte ich noch nicht. Beim überfliegen ist mir aufgefallen, dass der Code noch etwas zu hoch für mich ist. Zu viele Elemente, die ich noch nicht kenne, aber ich versuche mal damit klar zu kommen.

Was mein Problem angeht: So wie ich es nun herausgelesen habe, wäre der richtige Weg die Erstellung einer Repository-Klasse, die über Get bzw. Set meine Daten aus der CSV in eine Liste pumpt und weiterreicht.

Ich habe nun vier Namespaces erstellt: Model, DataAccess, View, ViewModel.
Die Repository-Klasse kommt ins DataAccess. In der Repository-Klasse werden dann aus der CSV-Datei Objekte der Klasse Ausgabe (welche sich im Namespace Model befindet) erzeugt und in einer Liste zusammengefasst.
Die Änderung wird ans ViewModel weitergegeben und schlussendlich mittels Datenbindung in der View angezeigt.

Sind die Überlegungen im letzten Abschnitt so richtig?

09.09.2011 - 18:31 Uhr

Hallo zusammen,
ich bin gerade dabei mich in das Thema Model-View-ViewModel einzuarbeiten und wollte in dem Zusammenhang dann auch meine erste Demo-Applikation erstellen, an der ich mich in zukünftigen Projekten orientieren kann.

Das grundsätzliche Prinzip von MVVM habe ich soweit verstanden. Womit ich mich noch ein wenig schwer tue, ist die richtige Zuordnung der Klasse, die meine Daten einliest.

Konkret heißt dies folgendes:
Meine Demoapplikation soll ein Programm werden, in welches man ein Datum, einen Verwendungszweck und einen Euro-Betrag eingibt. Diese eingegebenen Daten fließen dann in eine CSV-Datei hinein.
Zusätzlich soll eine Tabelle (ListView) anzeigen, was bereits in der CSV-Datei drin steckt (also Daten, Verwendungszwecke und entsprechende Beträge).

Folgendermaßen sieht mein XAML-Code aus:


<Window x:Class="MVVM1.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        Title="Money Machine" Height="260" Width="320" Icon="/MVVM1;component/money.ico" 
        WindowStartupLocation="CenterOwner">
    <Grid>
        <ListView HorizontalAlignment="Stretch" VerticalAlignment="Stretch" Margin="0,0,0,76">
            <ListView.View>
                <GridView>
                    <GridViewColumn Header="Datum" Width="70" />
                    <GridViewColumn Header="Verwendungszweck" Width="140" />
                    <GridViewColumn Header="Betrag" Width="60" />
                </GridView>
            </ListView.View>
        </ListView>
        <DatePicker Height="25" HorizontalAlignment="Stretch" Margin="0,0,0,50" VerticalAlignment="Bottom" BorderBrush="#FF828790" DisplayDate="{Binding DateToday}" />
        <Label Content="Verwendungszweck: " Height="23" HorizontalAlignment="Left" VerticalContentAlignment="Center" VerticalAlignment="Bottom" Padding="0" Margin="0,0,0,25"/>
        <TextBox Height="23" HorizontalAlignment="Stretch" VerticalAlignment="Bottom" BorderBrush="#FF828790" Margin="110,0,0,25" />
        <Label Content="Betrag: " Height="23" HorizontalAlignment="Left" VerticalContentAlignment="Center" VerticalAlignment="Bottom" Padding="0" Margin="0,0,0,0"/>
        <Button Content="Eintragen" Height="23" HorizontalAlignment="Right" VerticalAlignment="Bottom" />
        <TextBox Height="23" HorizontalAlignment="Stretch" VerticalAlignment="Bottom" BorderBrush="#FF828790" Margin="42,0,53,0" />
    </Grid>
</Window>

Das dazugehörige Model sieht bis jetzt so aus:


using System;

namespace MVVM1.Model {
    public class Ausgabe {

        // Attribute definieren
        public DateTime Datum { get; set; }
        public string Verwendungszweck { get; set; }
        public double Betrag { get; set; }

        // Konstruktor zur Erstellung eines Objekts vom Typ Ausgabe
        public Ausgabe(DateTime datum, string verwendungszweck, double betrag) {
            Datum = datum;
            Verwendungszweck = verwendungszweck;
            Betrag = betrag;
        }
    }
}

Geplant war nun folgendes: Ich mache eine Liste von Objekten des Typs "Ausgabe" und binde diese Liste an die Tabelle (ListView), jedoch bin ich mir nicht ganz sicher an welcher Stelle bzw. in welcher Klasse ich dies machen sollte.
Also quasi: Kommt der CSV-Parser, welcher dann nachher die Liste mit Ausgabe-Objekten zurückgibt auch ins Model, oder pack ich das in eine andere Klasse?

Oder gehe ich das alles komplett falsch an?

25.08.2011 - 19:04 Uhr

Super, es läuft.
Vielen Dank. Dann starte ich den morgigen Tag mal motiviert... Nicht so wie die letzten beiden Tage 😁

25.08.2011 - 18:45 Uhr

Der Code von MusiuminCapitiss funktioniert bei mir irgendwie nicht richtig. Das Label zeigt nichts an.

Habe jetzt alles folgendermaßen testweise in eine Klasse gepackt und 2 Buttons zum starten bzw. stoppen hinzugefügt, aber das Laben zeigt nichts an.

Hier der Code (sicherheitshalber):


public partial class MainWindow : Window, INotifyPropertyChanged {

        public MainWindow() {
            InitializeComponent();
        }

        private static String _labelContent;
        private DateTime _startTime;
        private Dispatcher _parentDispatcher = Dispatcher.CurrentDispatcher;
        private DispatcherTimer dt = new DispatcherTimer();
        public event PropertyChangedEventHandler PropertyChanged;

        public string LabelContent {
            get { return _labelContent; }
            set {
                if (_labelContent == value)
                    return;

                _labelContent = value;
                if (PropertyChanged != null) {
                    PropertyChanged(this, new PropertyChangedEventArgs("LabelContent"));
                }
            }
        }

        public void StartTimer() {
            dt.Interval = TimeSpan.FromSeconds(1);
            dt.Tick += (s, e) => {
                _parentDispatcher.Invoke((Action)(() => { LabelContent = "Seconds: " + (DateTime.Now - _startTime).Seconds; }));
            };
            _startTime = DateTime.Now;
            dt.Start();
        }

        public void StopTimer() {
            dt.Stop();
        }

        private void Button_Start(object sender, RoutedEventArgs e) {
            StartTimer();
        }

        private void Button_Stop(object sender, RoutedEventArgs e) {
            StopTimer();
        }
    }

Und der XAML-Code:


<Window x:Class="Stoppuhr_WPF_Datenbindung.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        Title="MainWindow" Height="114" Width="176">
    <Grid>
        <Button Content="Start" Height="23" HorizontalAlignment="Left" Margin="12,12,0,0" Name="button1" VerticalAlignment="Top" Width="75" Click="Button_Start"/>
        <Button Content="Stop" Height="23" HorizontalAlignment="Left" Margin="12,41,0,0" Name="button2" VerticalAlignment="Top" Width="75" Click="Button_Stop"/>
        <Label Name="label1" Content="{Binding LabelContent}" Margin="93,0,0,0" />
    </Grid>
</Window>

25.08.2011 - 17:29 Uhr

Ok, das letzte Beispiel hab ich jetzt verstanden, nachdem ich es in einer einfacheren Form nachprogrammiert habe. Ich kannte die INotifyPropertyChanged Schnittstelle nicht. Das macht es irgendwie einfacher und ich kann die Daten des Timers vernünftig an das Label binden.

Zu dem Programm, was ich für unsere Citrix-Admins schreibe habe ich dennoch eine Frage: ist es design-technisch besser die Statusbar bzw. alle Operationen, die innerhalb der Statusbar ablaufen, in einer eigenen Klasse abzubilden?
Oder soll ich einfach alles in die Mainform reinschreiben?
Denn der Timer ist ja nicht das Einzige, was innerhalb der Statusbar aktualisiert werden soll. Ich soll zusätzlich noch eine fortlaufende Progressbar implementieren und in einem weiteren Label (in textueller Form) ausgeben, welche Operation genau da eigentlich gerade durchgeführt wird.

Wenn ersteres zutreffen sollte, dann muss ich meine Klasse Klasse "StatusbarUpdate" nochmal neu programmieren und mir in der Mainform ein Objekt davon erzeugen.

Habe wie gesagt sonst leider niemanden den ich fragen kann und da dies mein erstes richtiges Projekt ist, würde ich es gern richtig machen. Zumal das das IHK Abschlussprojekt ist und zu einem Drittel in meine Endnote einfließt.

Danke euch allen schonmal soweit.

25.08.2011 - 09:32 Uhr

Hallo MURO

was mir als erster aufällt: Thread.Sleep(1000) 8o
Sowas macht man nicht. Nimm irgend einen Timer.

Das ist halt leider der Nachteil, den man als Programmier-Azubi in einer Abteilung voller nicht-Programmierer hat. Ich kann nicht sagen ob es guter oder schlechter Stil ist. Solange ich was funktionstüchtiges auf die Beine stelle, ist es für meinen Ausbilder schon guter Stil 😄.
Wie dem auch sei: Ich behebe das zu einem späteren Zeitpunkt noch. Danke dir für den Hinweis.

Die Frage ist jedoch: Was geht nicht? Zeigt das Label nichts an oder wie.

Das Label zeigt was an. Wenn ich den gesamten Code, den ich oben aufgeführt habe in die Main packe, also so, dass wirklich alles in einer einzigen Klasse steckt, dann funktioniert die Aktualisierung auch. Die GUI blockiert also schonmal nicht.
Es ist halt einfach die Sache, dass ich durch die logische Aufteilung in zwei Klassen meine GUI-Elemente nicht mehr ansprechen kann.

WPF und Label direkt ansprechen: sind zwei Sachen die nicht getan werden sollten.
In WPF wird normalerweise alles über DataBinding erledigt.

Ich hab hier leider absolut keine Idee, wie ich das über DataBinding realisieren könnte 😕.

Aber ich denke dass sich alles mehr oder weniger auf
>
bezieht.

Das was in dem Thread gefragt ist funktioniert bei mir schon. Den Tipp, den du dem Threadstarter da gegeben hast, habe ich bei mir schon selbst umgesetzt (siehe Code oben).

Was mein Problem ist (ich habe mich eben wohl unverständlich ausgedrückt):
Es müssen zwei Dinge parallel laufen, nämlich die Ausführung des PowerShell Skripts, sowie die sekündliche Aktualisierung des Labels "labelActualStatus".
Die Aktualisierung und die Anzeige des Labels an sich funktioniert. GUI blockiert nicht.
Was ich bräuchte wäre in der Methode "startTimer()" irgendetwas, was das Statuslabel ansprechen kann. Also quasi:


        public static void startTimer() {
            start = true;

            while (start) {
                Thread.Sleep(1000); //wird noch geändert
                i++;
                //labelActualStatus.Update("Skript wird ausgeführt", i.ToString());
            }
        }

Das funktioniert leider nicht, da das entsprechende Label nicht statisch ist und ich es auch irgendwie nicht hinbekomme eine entsprechende Set-Methode dafür zu schreiben 😦.
Ich kann klassenübergreifend einfach nicht mit dem Label arbeiten.

25.08.2011 - 08:51 Uhr

Hallo Community,
ich hänge seit ziemlich genau 2 Tagen an einem Problem und würde mittlerweile am liebsten den Rechner an die Wand werfen und nach Hause gehen.
Ich sitze zur Zeit an meinem IHK-Abschlussprojekt. Die Aufgabe ist es, eine Management Konsole für Citrix Server zu entwickeln, da die von Citrix bereitgestellte Konsole nicht genug kann.
Mein Auftraggeber legt EXTREM viel Wert auf Kleinigkeiten. Eine dieser Kleinigkeiten macht mir total zu schaffen -> nämlich ein Label in der Statusleiste.

Um zu zeigen, dass das Programm noch reagiert und bei längeren Operationen nicht abgestürzt ist, soll unter Anderem ein Label im Sekundentakt aktualisiert werden und die Zeit in Sekunden anzeigen, die bereits verstrichen ist. Dazu habe ich mir eine Klasse "StatusbarUpdate" als statische Klasse geschrieben:


    public static class StatusbarUpdate {

        private static Action EmptyDelegate = delegate() { };
        private const string defaultMessage = "Ready";
        private static bool start;
        private static Thread t;
        public static int i = 0;

        public static void startTimer() {
            start = true;

            while (start) {
                Thread.Sleep(1000);
                i++;
            }
        }
        
        public static void startThread() {
            t = new Thread(new ThreadStart(startTimer));
            t.Start();
        }

        public static void stopThread() {
            start = false;
            t.Abort();
        }

        public static void Update(this Label uiElement, string _message) {
            // Labelcontent wird auf uebergebenen String gesetzt
            uiElement.Content = _message;
            
            // Hier wird das Label neu gerendert, also sprich: Die Anzeige wird sofort aktualisiert.
            uiElement.Dispatcher.Invoke(DispatcherPriority.Render, EmptyDelegate);
        }


        public static void UseDefault(this Label uiElement) {
            Update(uiElement, defaultMessage);
        }


    }

Der Code zu meiner MainForm sieht dann so aus:


StatusbarUpdate.startThread();

            //Dies kann nicht funktionieren, aber das ist das Label um das es geht.
            //Ich brauche eine Möglichkeit das Label aus der "startTimer()" Methode der Klasse "StatusbarUpdate" zu aktualisieren
            labelActualStatus.Update("Running script getFarmname.ps1 " + StatusbarUpdate.i);

            string farmname = PowershellInvoker.RunScript(@"PowerShell_Scripts\getFarmname.ps1");
            //Unwichtiges Label
            label28.Content = farmname;
            
            //Label wird nach Ablauf des PowerShell Skripts wieder auf Standard gesetzt
            labelActualStatus.UseDefault();

            StatusbarUpdate.stopThread();

Ich hoffe der Code ist verständlich genug.
Aber nochmal zum Ablauf an diesem konkreten Codebeispiel: Es soll der Name einer Citrix Serverfarm angezeigt werden. Dazu wird ein PowerShell Skript durchlaufen (weil die SDK für Citrix Xenapp 6 fast nur noch Windows PowerShell unterstützt). Solange dieses PowerShell Skript aktiv ist, soll das Label "labelActualStatus" im Sekundentakt aktualisiert werden.

Bei Google hab ich schon gesucht, aber quasi ohne Erfolg.
Den Eintrag in der FAQ ([FAQ] Controls von Thread aktualisieren lassen (Control.Invoke/Dispatcher.Invoke)) hab ich auch gefunden, aber der hilft mir leider nicht weiter 😦.
Die Leute, für die ich das Programm schreibe und generell die ganze Abteilung ist eine reine Administratorentruppe ohne Programmierhintergrund.

Das hier ist quasi meine letzte Anlaufstelle 8). Bitte um Hilfe.

18.05.2011 - 17:33 Uhr

Hallo, erstmal bitte ich um Entschuldigung für den Doppelpost, aber sonst wird der thread nicht als ungelesen markiert.

Folgendes: Ich habe mir den Ratschlag von Schlingel zu Herzen genommen und den Code erstmal in einen string geschrieben. Vorerst habe ich den String bearbeitet und mittels

wohlgeformt = wohlgeformt.Replace("%", "Prozent");

das Prozentzeichen ausgetauscht. Danach habe ich die Zeile weggelassen, sodass die methode nur noch wie folgt aussah:

public string googleWetterXmlWohlformer(string uDatei) {
            StreamReader reader = new StreamReader(uDatei);
            string wohlgeformt = reader.ReadToEnd();
            reader.Close();

            StreamWriter writer = new StreamWriter(uDatei);
            writer.WriteLine(wohlgeformt);
            writer.Close();

            return wohlgeformt;
        }

Also im Endeffekt nur die XML in einen string eingelesen und wieder zurück in eine XML Datei geschrieben.

Meine Frage ist nun: Ich habe im Endeffekt nichts geändert. Warum gilt die Datei vor der Operation jedoch nicht als wohlgeformt, nachher aber schon?

Habe jetzt zwei Tage immer mal wieder im Internet gesucht, aber nichts gefunden, was die Frage beantworten könnte, deswegen wende ich mich an euch.

Edit: Die Programmlogik funktioniert nun komplett fehlerfrei. Kann schon über die Konsole das aktuelle Wetter und das Wetter der nächsten 3 Tage sehen. Der nächste Schritt wird nun sein sich mit WPF auseinanderzusetzen und da eine GUI drauf zu bauen.

17.05.2011 - 08:31 Uhr

Jo, das hab ich mir schon gedacht.
Ich habe jetzt das komplette XML in einen String eingelesen und das %-Zeichen einfach rausgelöscht.
Werde dann eine neue XML erzeugen und damit weiterarbeiten.
Danke dir für die Hilfe. Ich kann das XML jetzt fehlerfrei durchlaufen.

16.05.2011 - 22:06 Uhr

Hallo Schlingel,
ich habe deine Lösung ausprobiert, aber ich kam nicht damit zurecht.
Ich habe das Problem jetzt in dem Sinne "gelöst", indem ich einfach mal eine andere Sprache ausprobiert habe. Standardmäßig ist die XML-Datei in der jeweiligen Landessprache verfasst, fügt man aber noch was hinten an (http://www.google.de/ig/api?weather=Koeln&hl=en), ist das Dokument komischerweise auf einmal wohlgeformt.
Ich denke ich werde nun mit der englischen Version weiterarbeiten, bis ich das Problem verstehe.

Edit: Stimmt... Auf die Idee das als Zeichenkette zu behandeln bin ich noch gar nicht gekommen 😄. Danke für den Tipp.

16.05.2011 - 19:26 Uhr

Hallo, erstmal vorab: ich bin noch recht neu auf dem C# bzw .NET-Gebiet.
Vor einigen Wochen habe ich angefangen das Visual C# 2010 Buch bei Galileo Openbooks durchzuarbeiten und bin auch ziemlich zufrieden mit dem Buch als Lernhilfe. Nachdem es dann an die "komplizierteren" Artikel bzw. Themen ging, habe ich beschlossen zwischendrin immer selbstgestellte Übungen zu machen.

Nachdem ich das Kapitel XML durchgelesen habe, wollte ich mir mithilfe der Google Wetter API (Beispiel für Köln: http://www.google.de/ig/api?weather=Koeln) ein kleines Tool zur Wettervorhersage bauen. Durch die Wetter API ist das im Prinzip ja nichts anderes als XML-Dokument auslesen und Daten irgendwie leserfreundlich aufbereiten.

Nachdem ich die Datei auf meine Festplatte gezogen habe, stoße ich aber auf ein Problem, wenn ich das XML Zeilenweise durchlaufe.
Mit folgendem Code erhalte ich eine XmlException:

XmlReader auslesen = XmlReader.Create(@"wetter.xml");
while (auslesen.Read()) {
}

Wer nun ins XML Dokument (den oben geposteten Link) mal reingeschaut hat, stellt fest, dass es unter dem Punkt "<current_conditions>" einen Unterpunkt "<humidity data="Feuchtigkeit: 77 **:::

Könnt ihr mir vielleicht sagen, wie ich das Problem eliminieren kann?

Wäre für jede Hilfe Dankbar.

Gruß,
vita