Laden...
U
Benutzerbeschreibung
Konto auf Wunsch des Benutzers gesperrt

Forenbeiträge von userid14268 Ingesamt 1.578 Beiträge

26.08.2010 - 21:25 Uhr

Wenn man erst die UI macht besteht aber die Gefahr das man u.u:

  • "mal eben" eine Funktionalität ein hackt,
  • das man Dummy Templates erstellt die die Funktionalität erst viel Später bekommen (wichtige Zeit verloren),
  • das man UnitTests weg lässt um die UI "schnell mal eben" mit Funktionalität aus zu statten,
  • das man weniger Abstrahiert sondern direkt mit der UI verknüpft (Ruf die Komponente einfach mal schnell auf()
  • und zu guter letzt das man die UI immer wieder umbauen muss da sich bei der Implementation der Funktionalität neue Erkenntnisse ergaben.

Zu beginn steht sowieso die Planung, und in der Praxis wird man vermutlich beides benutzen, eine einfache UI zur Präsentation von UX für die Kunden und/oder das C Level, und aus der Gegenrichtung komme die Implementation entgegen. Gerade wenn es in unterschiedlichen Teams gemacht wird wäre es für die Komponenten blöd wenn sie auf die Applikation warten müssten, da entwickeln sich beide entgegen und am ende handen die framework/platform group zur application group über.

26.08.2010 - 11:34 Uhr

Was ich meinte hat mit Bottom-Up/Top-Down nichts zu tun, mir geht es darum das man erst Funktionalität macht und dann den Aufruf.
Das kann bei MVC der Controller sein, und bei MVVM das ViewModel oder direkt eine Klasse in der Logik, spielt keine Rolle wo man anfängt. Das ist ja das schöne dabei, man hat auch mit TDD weiterhin alle Freiheiten.
Eventuell habe ich mich da nicht deutlich genug ausgedrückt, sorry dafür.

Vorher hatte ich immer erst die UI gemacht und die Controls mit Commands und dort mit Methoden verbunden und das dann aus implementiert. Das hatte den nachteil das ich die UI immer wieder anpassen musste und es fester verdratete sodass es schlechter testbar war. Jetzt Fang ich tiefer an, ich kann so die UI machen wenn es definitiv nicht mehr geändert wird (also nicht geplant) und hab gleich meine volle test Abdeckung -> aber es muss nicht so tief sein das es gleich Buttom-Up ist.

26.08.2010 - 09:15 Uhr

Hätte ich dir auch sagen können (warum hab ich das nicht? 😄) in WPF ist das SelectedItem nicht immer gleich das Sichtbare Item.

Schau am besten mal ob das DataGrid "ScrollIntoView" hat, wenn ja benutz das.

26.08.2010 - 07:43 Uhr

Wenn TDD zu einem solchen Verhalten führt, dann werden dadurch natürlich erhebliche Mehrkosten verursacht. Entwicklung vom User Interface in Richtung Backend ist effizient, weil [...]

Kann ich nicht so unterschreiben.

keine Funktionalität implementiert wird, die nicht benötigt wird

Erst Planung dann Implementation, dn man implementiert die Funktionalität die vor gesehen ist als erstes, die UI kommt dann viel später. Man schreibt keineswegs unnötige Sachen.

seltener nachträgliche Änderungen gewünscht werden(wenn das UI vom Kunden abgenommen ist, man im Backend relativ frei)

Änderungen egal wo muss man immer an gehen, wenn die Funtionalität bereits steht ist jede Anpassung der UI absolut einfach, und in sehr kurzer Zeit zu realisieren.

Alleine die Auffassung "nur noch eine UI davor packen" widerspricht jeglichen agilen Prinzipien. Und TDD kommt nun einmal aus genau dieser Richtung.

Von daher finde ich es natürlich falsch, hier im Thread zu suggerieren, TDD wuerde die Entwicklungsweise in dieser Hinsicht quasi umkehren.

Hä? Es fördert doch ungemein die unabhängigkeit, man schreibt seine Funktionalität und muss dann mit nem Designer nur noch die Schnittstelle auskeksen.
Zudem schließt das alles nicht aus das man die Funktionalität nicht noch erweitert oder anpasst nachdem die UI steht. Man schafft mit "Erst Funktionalität dann UI" schon eine solide Basis.

Da ist eben der unterschied, unser Vor/Zurück hat keine Logik die ein Button deaktiviert oder ähnliches, ...

Genau DAS meinte ich. Wenn keine Logik, dann ist es sinnlos mit Vor- und Zurück-Buttons zu arbeiten. Mindestanforderung, um soetwas einem TabControl vorzuziehen ist eine notwendige Sequenz.

30 Items in einem TabControl ist aber absolut unübersichtlich, und eine ListBox+ContentControl wurde abgelehnt, die Konsequenz ist ein Control wo man durch Blättert.

Ich denke diese gehört eng zusammen(wieso sonst sollte es hier aufgetaucht sein?). Der Nutzen von Unit-Test hängt auch mit dem Verständnis von verschiedenen Controls zusammen. Ich muss zum Teil die Business-Logik aus diesen Controls rausziehen, um wirklichen Nutzen aus TDD oder überhaupt Unit-Tests ziehen zu können.

Versteh ich das richtig, nur wegen den Controls siehst du kein Nutzen von TDD und UnitTests? Controls sind mit der kleinste Teil einer Applikation!

Ich warte das auch noch andere TDD Menschen (am besten erfahrene) sich hier zu Wort melden 😁

26.08.2010 - 07:30 Uhr

Nimm ein ItemsControl und im ItemTemplate kannst du ein Button erstellen, bei diesen Bindest du Content gegen den namen und Command gegen die aus zu führende Aktion bei Click.

25.08.2010 - 17:23 Uhr

Nimm lieber eine ListView statt ein Grid, dort kannst du die Header definieren und hast eine ScrollBar automatisch dabei sodass du ScrollIntoView aufrufen kannst.

25.08.2010 - 14:26 Uhr

Genau, also man erstellt im Test dann Objekte und benutzt Methoden die es noch nicht gibt, aber man hat meist vorher schon eine konkrete implementations Idee.

Was mir dabei gefällt ist das man in der Test Methode bevor man etwas erstellt alles nochmal überblickt um dann von den Best Case der Benutzung aus zu gehen.
In VS kann man dann auch mit CTRL+. -> New Type direkt die neue klasse und dessen Methoden in das Ziel assembly rein erstellen lassen.

Ich hatte es schon öfter das ich ne Klasse aus dachte die etwas macht, und als ich dann die Test methode fertig hatte (die konkreten Objekte noch nicht) merkte ich das eine leicht andere verwendung des Objektes viel angenehmer ist, dann hab ich das angepasst und erst als ich glücklich damit war das konkrete Objekt erstellt.

Zu beginn ist man zwar langsamer, aber das gleicht sich schnell aus, man muss sich auch daran erst gewöhnen.

Man löst Probleme auch von der anderen Richtung, ich für mein Fall hatte oft mit der UI angefangen und dann stück für stück zur Funktionalität vor gearbeitet. Jetzt erstell ich erst die Funktionalität und muss dann nur noch eine UI davor packen.

25.08.2010 - 11:25 Uhr

Ich denke schon.
Nur man könnte ja ein Control Property im CodeBehind zur Verfügung stellen und die View dagegen binden lassen.
Ist dann auch recht eindeutig.

<ContentControl Content="{Binding MyProp, RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type Window}}}" />

In in der CodeBehind kanns dann im Getter des Properties erstellt werden.
Macht mMn kein unterschied.

Die CodeBehind ist ja die selbe Klasse wie auch das Xaml, wie du weißt, also ist es auch in der View klasse.

25.08.2010 - 09:41 Uhr

Jetzt wo es abgetrennt ist kann ich ja nochmal nach haken.

Wieso unterscheidest du ob die Erstellung im einen Converter gemacht wird oder in der CodeBehind?

25.08.2010 - 09:07 Uhr

Exceptions sollten doch aber nicht dem Kontrollfluss der Applikation dienen, also Exceptions zeigen nur Fehler, und das der Benutzer auch mal eben ein "ungültiges" Verzeichnis auswählt ist normal und kein Fehler.

25.08.2010 - 08:57 Uhr

Hei die Idee finde ich gut, vielen Dank 😃 Melde mich wieder wie ich es dann final gemacht habe 😃

25.08.2010 - 08:34 Uhr

Die gezeigten Objekte befinden ich in der "Models" Assembly und alle Zugriffe sollen nur über den Manager laufen, dh der Aufrufer kann nur manager.Load und manager.Save aufrufen, wie es der Manager intern ab speichert und läd braucht den Aufrufer nicht zu interessieren, entsprechend ist es da mit einem Stream auch unpraktisch.

Der Manager delegiert es intern auch bloß an separate Objekte weiter, diese übernehmen dann das tatsächliche Speichern und Laden.

//Dazu

Das Problem wird doch eher sein, dass die Methode, die die Datei schreibt, eine solche Exception gar nicht abhandeln kann sondern sie einfach nach oben durchreicht.

Stimmt, so habe ich das noch gar nicht gesehen.
Dann wäre es doch möglich das FooLoader und FooSaver nur XmlDocument<->Stream handhabt und das tatsächliche Speichern der Manager übernimmt? Dafür müsste ich dann den FooLoader und FooSaver public machen (und umbenennen) -.- (Und mein Code Coverage würde dann mein Manager.Load/Save als nicht getestet monieren)

25.08.2010 - 08:29 Uhr

Also ich habe mich mit "Test Driven Development" von Kent Beck eingearbeitet, kann es absolut weiter empfehlen 😃 Es ist auch Unabhängig von irgend einer Library, dh du kannst es mit MSTest machen oder mit NUnit, spielt keine Rolle.

25.08.2010 - 08:06 Uhr

Also ich könnte ein Objekt erstellen welches mir schon mal das XDocument erstellt, das kann ich dann Validieren und kann es mit einen ein zeiler speichern lassen so wie Arithmetika es vor schlägt.
Nur dann habe ich den Fall nicht abgedeckt das die Datei wegen fehlenden Rechten nicht gespeichert werden konnte, der Benutzer wählt das Zielverzeichnis aus, und wenn er unter Vista/Seven "Programme" aus wählt muss ich das ja auch entsprechend handeln.
Auf jeden fall kann ich das, so denk ich, in zwei Teile Splitten.

Ein Objekt welches ein XmlDocument erstellt, das kann ich dann separiert Testen, und eines welches tatsächlich speichert, da bräuchte ich nur noch die Existenz prüfen, richtig?

Nehmen wir mal etwas Code Beispiel dazu, dann wird es einfacher.

So habe ich das bisher:

public class Foo
{
    // komplexeres Objekt welches gespeichert werden soll
}

public class FooManager
{
    public Foo Load(string sourcePath)
    {
        return new FooLoader().Load(sourcePath);
    }

    public bool Save(Foo foo, string targetPath)
    {
        return new FooSaver().Save(foo, targetPath);
    }
}

internal class FooSaver
{
    internal bool Save(Foo foo, string targetPath)
    {
        // tatsächlich speichern und return true wenn fertig ohne fehler
    }
}

internal class FooLoader
{
    internal Foo Load(string sourcePath)
    {
        // tatsächliches laden, null wenn nicht möglich
    }
}

Wie könnte och nun "Load" und "Save" korrekt testen? Bei meiner Idee müsste ich den FooSaver und FooLoader so ab ändern das er nicht mit einem Pfad arbeitet sondern mit einem XmlDocument, und das müsste ich dann public machen.

25.08.2010 - 07:30 Uhr

Es geht um folgendes.

Man hat ja immer wieder den Fall das man Daten Laden und Speichern muss sowie Ordner erstellen, nehmen wir Xml Dateien in einem Unterordner zum Beispiel.

Dafür gibt es Objekte die können Ordner validieren und erstellen sowie Dateien speichern und laden.
Die Frage die sich mir stellt ist, wie kann man das vernünftig Testen? Gibt es da gute Praktiken?

Das Assert müsste dann ja auch noch selber die Datei laden können und zu überprüfen das sie korrekt gespeichert wurde... die bloße Existenz reicht nicht immer.

24.08.2010 - 21:27 Uhr

Oh. Es gab ja noch antworten, gar nicht gesehen 😄

Was ist aber mit den "Vor"- und "Zurück"- respektive "Fertig"-Buttons? Sowas baut man nicht "zwecks Übersicht" ein. Ganz im Gegenteil. Dadurch gebe ich dem Benutzer die Hand und leite ihn. Entweder durch einen bestimmten Prozess oder aber durch ein bestimmtes Schema, welches dem besseren Verständnis dient. Unter Umständen kann ich sogar den "Weiter"-Button nicht klicken, weil eine gewissen Voraussetzung auf der aktuellen Seite nicht erfüllt ist.
Das sind alles Geschichten, die meiner Meinung nach ganz klar nicht mehr der View gehören, das ist Business-Logik.

TabControl und "Vor, Zurück"-Dialog sind also semantisch gar nicht äquivalent.

Da ist eben der unterschied, unser Vor/Zurück hat keine Logik die ein Button deaktiviert oder ähnliches, es zeigt nur an, es hat genauso viel Funktionalität wie das TabControl, es ist praktisch genau das selbe, nur das der User nicht weite Sprünge machen kann. Man könnte es direkt mit ein TabControl austauschen und nichts würde sich verändern, es würde nur die Übersicht leiden da es zu viele Objekte sein können.
"Fertig" gibt es auch nicht, es ist kein Wizard sondern nur eine andere Ansicht der Daten.
Auch der Logic dahinter ist völlig desinteressiert welches Objekt gerade angezeigt ist, für die Logic ist es einfach eine Liste von Objekten, die View kann es in einer ListBox oder einem TabControl konsumieren.

Tatsächlich hat dieses Control weniger "Logik" als alle WPF Controls (z.b.: das StackPanel).

Ich könnte das Control so wie es ist auch in Tulipa packen und für die Applikation würde sich nichts ändern 😄

Ich würde aber vor schlagen das Thema hier sein zu lassen, da das nicht mehr zum Thema gehört.

Ursprünglich hatte ich aber diesen Thread aber gesucht weil ich nur was erzählen wollte.
Ich entwickel seit nun einiger Zeit nach TDD (wie schnell die Zeit vergeht -.-) und muss sagen das macht echt Spaß, hat sich gelohnt dort rein zu schnuppern 😃
Man überlegt auch viel mehr wie man etwas auf zieht statt einfach los zu legen. Ich würde nicht sagen "Nie ohne" aber eine angenehme art der Entwicklung ist es schon 😃

24.08.2010 - 20:35 Uhr

Hmm, also mir fällt bisher keine gute Lösung ein, werde es also so lassen müssen.

Ich hatte noch die Idee das der ctor von Foo den FooManager bekommen muss, aber das ist mir dann eine zu starke Verbindung in beide Richtungen.

internal muss also reichen, dann ist es wenigstens nur innerhalb dieser Assembly zugreifbar.

24.08.2010 - 19:58 Uhr

Heiho,

Folgendes, ich habe in der selben Assembly ein konkretes objekt
"Foo" und ein "FooManager", der FooManager kann Foo erstellen, laden und speichern.

Nun will ich das man Foo nicht selber erstellen kann sondern FooManager.CreateFoo aufrufen muss um Foo zu erhalten.
Zuerst dachte ich natürlich an ein Interface, nur da die konkrete Implementation in der selben Assembly steckt könnte man es trotzdem weiterhin selber erstellen.

Jemand ne Idee?

LG
CSL

24.08.2010 - 19:52 Uhr

Also hätte unser OP das selbe Problem in dem Converter statt in der CodeBehind 😄

Gut dann hatte ich dich falsch verstanden, ich dachte zu beziehst dich auf das erstellen von WPF Controls im Code allgemein.

24.08.2010 - 19:40 Uhr

Das Control wird im Code erzeugt, nur halt in einem Converter statt in der Code Behind.

<ContentControl Content="{Binding MyProp, Converter={StaticResource TextToControlConverter}}" />
24.08.2010 - 19:26 Uhr

Aber noch der obligatorische Hinweis: 😉
Controls sollte man in der WPF wirklich nie im Codebehind erzeuge

Seh ich anders, es gibt selbstverständlich anwendungsfälle wo so etwas notwendig wird.

Angenommen man braucht so etwas in der View:

"Search for the string wich contains [TEXTBOX] in the source and in the target" sowie
"[TEXTBOX] exist in the source but not in the target".

[TEXTBOX] ist zur Laufzeit eine echte TextBox.
Man könnte es mit nem StackPanel schachteln, das ist korrekt, nur dann ist es nicht mehr lokalisierbar!

"Search for the string wich contains "
" in the source and in the target"
" exist in the source but not in the target"
ist nicht übersetzbar, zum einen da es grammatikalisch nicht funktioniert, und der Übersetzer an der Stelle nicht weiß das es zusammen gehört und auch nicht was dazwischen liegt.
In der jeweiligen Zielsprache ist der Satzaufbau oft absolut anders sodass die TextBoxen womöglich ans ende gehören. Daher darf man Strings auch nicht selber Concatinaten.

Daher ist der korrekte Weg das man "Search for the string wich contains [TEXTBOX] in the source and in the target" sowie "[TEXTBOX] exist in the source but not in the target" übersetzt as is und [TEXTBOX] zur Laufzeit (zb durch ein Converter) austauscht.

=> Localization checklist

24.08.2010 - 10:05 Uhr

Kennt doch jeder, ein Bewerbungsgespräch in der nächste großen Stadt, von der Adresse nie was gehört und man muss rum suchen, da kann man mit GSV schon vorher schauen wo der Eingang ist und wie es mir Parkplätzen aussieht 😁

Wie oft werden die Bilder in GSV überhaupt aktualisiert? Nach ein Paar Monaten/Jahren sind die Bilder eh obsolet.

//Smilies aktiviert

23.08.2010 - 13:29 Uhr

Ja das stimmt, so lange niemand dieses "Expression" konstrukt für andere Sachen missbraucht 😄
Wie ist das eigenlich bei Refactorings? Werden umbenannte Properties in den expressions auch abgefangen? Ist wird bei WPF nicht gemacht und ist sehr ärgerlich.

23.08.2010 - 12:07 Uhr

Genau, die Anweisung nach dem zweiten Semikolon wird erst ausgeführt wenn der Anweisungsblock durch ist

for (int i = 0; i < myList.Count(); i++)
{
    TuWas(myList[i]);
}

ist äquivalent zu

int i = 0;
while (i < myList.Count())
{
    TuWas(myList[i]);
    i++;
}
23.08.2010 - 12:00 Uhr

Genau, ein a.b.c sowie x.y[0].z ist zwar elegant wenn es funktioniert, das Binding von WPF kann das auch Problemlos, ist aber was suaberen Code an geht ziemlich schlecht, so hat man eine ziemlich feste Verbindung wie die Objekte aus sehen müssen.
Im Beispiel auf der CCD Seite heißt es ja auch

int margin = config.Pages.Margins.Left;
Würde man hier das Law of Demeter anwenden, wäre nur der Zugriff auf config.Pages gestattet.

Anhand des "würde" sieht man das man LOD nicht immer beachten muss wenn es um einfache Datenhalter geht, so stehts auch dort. Ich wollte es nur erwähnt haben.

22.08.2010 - 20:49 Uhr

Schau mal hier: WPF Image Control Update

BitmapImage bitmap = new BitmapImage();
bitmap.BeginInit()
bitmap.UriSource = new Uri(path);
bitmap.UriCachePolicy = new RequestCachePolicy(RequestCacheLevel.BypassCache);
bitmap.CreateOptions = BitmapCreateOptions.IgnoreImageCache; // <== hier
bitmap.EndInit();
i.Source = bitmap;

das Image Binden könnte auch helfen, also gegen ein Property binden welches das PropertyChanged absetzt.

22.08.2010 - 11:49 Uhr

Aber man sagt doch auch

"inkrementiere i" => Increment(i); => ++i; 😁

ich glaube kaum das man i++ vermeiden muss, mir persönlich gefällt der pre-inkrement einfach besser. immer wenn ich i++ sehe zuckts in den fingern.
Heißt es nicht auch das man Rückgabewerte von Methoden immer beachten sollte?

Den post verwende ich tatsächlich nur wenn ich den Rückgabewert benötige bevor ich inkrementiere, dafür isser ja da, ich verwende doch nichts was ich nicht benötige.

20.08.2010 - 17:42 Uhr

Würd ich auch sagen, n Custom Tab Control ist das einfachste 😃

18.08.2010 - 22:25 Uhr

Die Applikation läuft bereits und eine Leere ListView ist zu sehen
Dann startet der User eine suche, die suche wird in nem Thread ausgeführt und der weile wird dann ein Please Wait mit Progress angezeigt.
Sobald die Suche Beendet ist und Die Daten fertig sind, werden diese in die ObservableCollection gepackt und das PleaseWait zerstört.
In der Zeit ist das Fenster eine weile eingefroren.

Ich habe gemessen und gesehen das das Hinzufügen in die Liste genauso schnell ist wie das zerstören des PleaseWait Fensters, nur das aufbauen der UI (Stink normale ListView) dauert so lange -.-

18.08.2010 - 21:52 Uhr

Hajo,

was wäre denn die richtige Lösung meines Problems?

1 -> Applikation Startet
2 -> Thread startet
3 -> Please Wait wird angezeigt
4 -> Im Thread werden viele Daten geholt
5 -> Thread schickt Event das es Beendet ist mit den Fertigen Daten
6 -> PleaseWait wird zerstört
7 -> Daten werden in einer Liste gepackt
8 -> Applikation Zeigt die Liste

Bis 5 ist alles in Ordnung, sobald der Thread zu ende ist und das PleaseWait zerstört wurde ist das Fenster eingefrohren, dh man sieht das PleaseWait Fenster so lange bis 8 fertig ist.
Das Splash bringt eventuell nichts da es WPF nicht einmal schafft das PleaeWait Fenster korrekt zu löschen.

Ich habe gar keine Position wo ich das Splash Fenster wieder manuell zerstören könnte, da zu dieser Zeit gar kein Code mehr von mir läuft.

18.08.2010 - 17:25 Uhr

Davon hab ich auch schon gehört.

Geht das eigentlich auch zwischendurch?

Ich lass Aktionen in einem Thread ausführen und zweige derweil ein PleaseWait an, nachdem der Thread durch ist sollten die Objekte in einer ListView angezeigt werden.
D.h. ich beende das PleaseWait Fenster und füge es in die ObservableCollection ein.
Das dauert leider manchmal recht lange sodass das PleaseWait noch eingefroren dargestellt wird.
Meine Nachforschungen ergaben das zu der Zeit wo es einfriert kein Code mehr von mir ausgeführt wird, es ist also der reine Measurement, Arrange und Render Prozess von WPF der da rum fummelt.
Ärgerlich.
Da ich das nicht in einem Thread auslagern kann würde ich dann auch so ein Bild anzeigen mit den Inhalt "Create Result List" oder ähnliches.
Geht das?

18.08.2010 - 12:59 Uhr

Dann halt Background, war nur hier im Forum getippt 😁

17.08.2010 - 20:52 Uhr

Und was möchtest du erreichen?
Erstelle doch einfach immer das selbe Objekt in einer liste, und i ist dann dein indexer.

17.08.2010 - 18:04 Uhr

TiPP: ItemContainerStyle

17.08.2010 - 14:52 Uhr

Die Stink normalen Borders haben doch CornerRadius

<UserControl ...>
    <Border BorderThickness="10" BorderBrush="White" CornerRadius="0,10,10,10" Fill="Yellow">
        <Border BorderThickness="3" BorderBrush="DarkGray" CornerRadius="0,10,10,10" Fill="White">
            <!-- Your Content -->
        </Border>
    </Border>
</UserControl>

Muss man nur noch das verschieben einbauen.

17.08.2010 - 13:41 Uhr

Theoretisch kann WPF das anstandslos, mach ich auch meist.

Ich wollte anfangs ein eigenes DependencyProperty machen, aber da hatte ich Probleme das immer in Sync mit Text in der TextBox zu halten.

Und zudem unterstützen die NumberBoxen ja zwei verschiedene Objekte, double und int, dann müsste das DependencyProperty ein gemeinsames object sein.

16.08.2010 - 19:48 Uhr

Wie zu erkennen sein sollte verwendet die NumericUpDown intern die NumberBox:
http://github.com/DavidWCSL/Tulipa/blob/master/Tulipa/NumberBox/NumberBox.cs

Und dort siehst du die Methode OnPreviewTextInput, die müsste aufgerufen werden sobald sich das Binding ändert, und validiert wird der Text über Parse mit
*.TryParse(input, System.Globalization.NumberStyles.*, CultureInfo.CurrentUICulture, out value)

D.h. zum Validieren wird CultureInfo.CurrentUICulture verwendet, und somit wird es auch so dargestellt.

Ich empfehle die CurrentCulture und CurrentUICulture der Applikation ein zu stellen, dann müsste es passen.
FYI: Für Xaml muss es separat gesetzt werden, am Ende sieht das so aus wie hier bei Punkt 4.: http://www.my-libraries.de/2010/01/30/localization-is-your-application-ready-for-a-checklist/

Als NumberStyle nehm ich System.Globalization.NumberStyles, unerstützt ist Integer und Float. Ist auch an den NumberBox code zu erkennen.

16.08.2010 - 13:33 Uhr

FooBar muss sich einfach im getter selber auflösen, oder du schubst ein Converter dazwischen.

15.08.2010 - 18:42 Uhr

Super Feature! Habe es direkt in Benutzung.
Nur wenn man gerade eine Thread Liste offen hat, dann ist unten das "Gehe zu" nicht gefiltert, in den ebenen darüber schon, evtl was vergessen.

LG
CSL

15.08.2010 - 18:37 Uhr

Ich hab noch diesen Code hier rum liegen:

public class AbortableBackgroundWorker : BackgroundWorker
{
    private Thread _workerThread;

    protected override void OnDoWork(DoWorkEventArgs e)
    {
        _workerThread = Thread.CurrentThread;
        try
        {
            base.OnDoWork(e);
        }
        catch (ThreadAbortException)
        {
            e.Cancel = true;
            Thread.ResetAbort();
        }
    }

    public void Abort()
    {
        if (_workerThread != null)
        {
            _workerThread.Abort();
            _workerThread = null;
        }
    }
}

Ich weiß aber nicht ob der funktioniert.

15.08.2010 - 10:51 Uhr

Das wäre schonmal ein Beispiel, wo der Testname nicht passt

Jup, weil ich den Code ein klein wenig angepasst hatte bevor ich ihn hier Postete, ursprünglich gav es die six variable nicht sondern five wurde doppelt verwendet, hatte vergessen den titel zu ändern.

Dann bewegen wir uns schon gar nicht mehr im Bereich von Unit-Tests. Das sind Integrationstests. 😉

Ah, siehste, ich wollte schon lange mal nach lesen wo da der unterschied ist 😁

Ansonsten kann ich deiner Argumentation komplett folgen und stimme zu, danke dir 🙂

14.08.2010 - 23:06 Uhr

Wie wär es damit, gerade gefunden in mein TDD Material:

[TestMethod]
public void Plus_FileDollarPlusFiveDollar_ReturnsSumExpression()
{
	Money five = Money.Dollar(5);
	Money six = Money.Dollar(6);

	IExpression result = five.Plus(six);
	Sum sum = (Sum)result;

	Assert.AreEqual(five, sum.Augend);
	Assert.AreEqual(six, sum.Addend);
}

"Sum" ist eine Expression die die beiden Zahlenwerte enthält, hier wurde überprüft das "Plus" korrekt "Sum" erstellt hat.
Das in zwei Tests wäre schon recht absurd.

Alle anderen Tests haben aber tatsächlich nur ein Assert, laut Buch nicht, habe es aber selber so gemacht.
Habe auch gerade mal die anderen Projekte durch geschaut wo ich Units habe, Mehr als 1 Assert habe ich bisher nicht gefunden, scheint bisher gut zu laufen 😁

Dazu fällt mir etwas ein, habe ich gerade in einem Projekt gesehen.

Ich bekomme von einer Methode eine Liste von Dokumenten, die Dokumente wiederum haben eine Liste von Sprachen.
Ich muss prüfen das die Sprachen alle korrekt sind, also Gültige Sprachen.
Ich hatte zu dem Zweck einfach die Dokumente geloop und in dem loop das Assert per Linq auf die Sprach liste los gelassen.
Wie würde man so etwas korrekt Testen?

14.08.2010 - 19:11 Uhr

Ok zurück zum Thema

Bzgl mein:
"Mir ist schon klar das mehrere Asserts nicht "böse" sind, mir fehlt aber noch das Gefühl wann mehrere Asserts benutzt werden könnten oder ich es lieber aufteilen sollte."

Gibt es eventuell ein paar Tipps und Tricks wie man raus findet ob mehrere Asserts oder nicht?

14.08.2010 - 14:32 Uhr

Da die Tests immer in VS ausgeführt werden und sogar beim entwickeln hilft, sehe ich kein Anlass etwas zu wechseln.

Nehmen wir einfach TDD.
Beim entwickeln der app brauch ich eine Klasse "Bank", nach TDD erstelle ich eine BankTest klasse, gebe dort Bank bank = new Bank(); ein, und mit CTRL+. Kann ich mir direkt eine Bank erstellen lassen.
Nun brauch ich die Rate USD->EUR, dann tipp ich einfach
Rate rate = bank.GetRate("USD", "EUR"); und kann mir direkt mit shortcut die Methode GetRate und die klasse Rate erstellen lassen.
Sobald die Methode GetRate erstellt ist, CTRL+Klick auf den namen, und schon kann ich dort die erste Fake Implementation einhacken um den Test passen zu lassen.

Siehe z.b. hier: Test-Driven Development with Visual Studio 2010

Die super Integration in VS macht es ziemlich handlich.
Kann die Tests auch in Test listen verwalten und einzelne Listen aufrufen lassen, wenn was failed kann ich direkt dort hin springen, usw usf.

Scheint auch mehr ne Glaubensfrage zu sein 😄
Stop the war between NUnit and MSTest : Make them friends

Aber wie gesagt, ich sehe kein Anlass zu wechseln, ich finde es gut das ich mit VSTS alles in einen habe welches such super zusammen arbeitet 😃

14.08.2010 - 13:48 Uhr

Stimmt, da hast du recht.

Mir ist schon klar das mehrere Asserts nicht "böse" sind, mir fehlt aber noch das Gefühl wann mehrere Asserts benutzt werden könnten oder ich es lieber aufteilen sollte.

Bzgl NUnit, Ich hatte bisher nicht das Bedürfnis NUnit zu verwenden, wo doch in VS 2010 MsTest richtig gut integriert ist (zudem brauch ich dann keine 3rdParty lib).

14.08.2010 - 12:24 Uhr

Also ich arbeite auch sehr intensiv mit einer COM api, und deren aufgaben werden immer in eigenen Thread gepackt, dann hat man dieses Problem gar nicht.

PS. Methoden können später aber Zeitkritisch werden, entsprechend lieber Vorsicht walten lassen.

Ich hatte mir zu diesen Zweck ein eigenen ThreadQueue gebastelt, dort hab ich dann Worker Threads die nacheinander die COM Aktionen ausführen und das Ergebnis brav weiterreichen.