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

Forenbeiträge von userid14268 Ingesamt 1.578 Beiträge

03.08.2010 - 15:47 Uhr

In dem Thread ist die Frage unter gegangen, mich würde es aber tatsächlich interessieren.

Ich habe ein Fenster wo ich ein string zusammen bauen kann mit platzhaltern.
Oben ist eine ListBox und eine ListView darunter, sobald ich in der ListView ein Item doppel klickt, wird die Selektion in der TextBox mit dem Wert ausgetauscht und der Eingabe Fokus liegt auch in der TextBox.

Wie kann man das korrekt in MVVM realisieren?

Ich mach das derzeit so:

private void ListViewItem_MouseDoubleClick(object sender, MouseButtonEventArgs e)
{
	Placeholder item = ((ListViewItem)sender).Content as Placeholder;
	if (item != null &&
		item.Pattern.Contains("%"))
	{
		int startPos = String_TextBox.SelectionStart;
		string content = String_TextBox.Text;
		content = content.Remove(startPos, String_TextBox.SelectionLength);
		content = content.Insert(startPos, item.Pattern);
		String_TextBox.Text = content;
		String_TextBox.SelectionStart = startPos;
		String_TextBox.SelectionLength = item.Pattern.Length;
		GiveTextBoxFocus();
	}
}

private void GiveTextBoxFocus()
{
	String_TextBox.Dispatcher.BeginInvoke(new Action(delegate
	{
		String_TextBox.Focusable = true;
		String_TextBox.Focus();
		Keyboard.Focus(String_TextBox);
	}),
	DispatcherPriority.Render);
}

Das Ganze Fenster macht sonst nichts, es geht nur um den Zusammenbau eines Strings mit platzhaltern.

Aufruf ist dann einfach

private void OnDo()
{
	FileNameWindow window = new FileNameWindow();
	if (window.ShowDialog() == true)
	{
		string newFileName = window.FileName;
	}
}

PS. das soll keine Diskusion über MVVM im allgemeinen werden.

03.08.2010 - 14:12 Uhr

Hmm, ok das mit der Planung klingt einleuchtend.
Ich finde es des weiteren aber auch besser wenn man die Methoden innerhalb der Klasse auch einzeln testet, so kann man viel einfacher alle möglichen cases abdecken.

Ich habe zb die private Methode die ermittelt die Qualität des Kafeefilters, dann schreib ich ein Unit zu dieser Methode und kann die mit allen möglichen Parametern voll spamen.

Ein Test für den Gesamtablauf ist sowieso dabei, nur durch dieses detailierte Testen kann ich dann schneller Fehler finden, wenn die Klasse mit der Methode "KocheKaffee" fehlt schlägt, kann ich vorher schon sagen das es daran liegt das die Filterqualität falsch berechnet wird.

Also ich teste im Prinzip alles was in der Klasse da ist.

@SeboStone
Mit Mocks habe ich derzeit (leider) noch nichts gemacht, bin noch sehr bei den Anfängen von CCD, sehe mich noch beim Roten Grad (Überprüfe es hiermit: http://github.com/DavidWCSL/CC-Watcher).

Man könnte sagen, das klingt logisch, aber was machst Du wenn Du nach zwei Wochen weitere Features hinzufügen musst oder sie etwas ändern musst? Wann ist denn dann der Beste Zeitpunkt fürs Testen?

Nach Deiner Logik nach wäre es das Beste so lange mit den Tests zu warten bis die Klasse keinerlei Änderung mehr erfahren soll. Also eigentlich nie.

Mein Zeitpunkt wann ich die Units erstelle ist immer nach Fertigstellung der Klasse, dh wenn keine weiteren Änderungen geplant sind. Auch wenn neue Features kommen werden diese implementiert, dann die Units aufgefrischt. Nebenbei können die bereits vorhandenen Units verifizieren das ich beim erweitern nichts zerstöre.
Laufe bisher recht gut damit.

Zu TDD selber sagte ich ja schon mehrfach das ich mir demnächst endlich mal ein Buch besorgen muss, damit ich da auch sicherer bin, habe bestimmt nur hier und da kleine Denkfehler.

03.08.2010 - 10:56 Uhr

Das refactorings innerhalb der Methoden für die Units ungefährlich sind ist schon klar.

Meine refactorings sind hin und wieder aber auch so das ich zb eine Methode in zwei kleinere aufteile, zb da die Methode mehr gemacht hat als sie sollte (Single Responsibility Principle).
Solche Sachen kann ich schlecht vorher sehen, oft merk ich das schon direkt beim entwickeln, dh ich müsste dann ein paar Units anpassen noch bevor ich am Code weiter mach.

Oder, ich plane eine Klasse und habe dort eine Methode KocheKaffee vorgesehen, dann kann ich nun die Units schreiben, aber ich weiß doch noch gar nicht welche Methoden KocheKaffee alles benötigt, klar kann ich schon eine "HoleKaffeeFilter" Methode mit einplanen, nur dann weiß ich auch noch nicht ob ich dort intern eine "ÜberprüfeQualität" benötige.
Solche Kleinigkeiten sind nicht in der Planung enthalten, aber die möchte ich ja erst noch abdecken.

Oder ich merke beim entwickeln das die Methode "HoleKaffeeFilter" überflüssig ist, da es eine Filterlose Maschine ist, dann Lösch ich die einfach.

Alles Aktionen die Anpassungen in den Units erfordern, da ist es doch praktischer wenn der Code dahin gehend bereits "fertig" ist. Vor allem bei kleineren Umstellungen während der Entwicklung.

Ich mach es wie gesagt so das ich die Units erst schreibe wenn die Klasse fertig ist, und dann versuche ich jede Methode komplett aus zu reizen, dh Blödsinn übergeben etc.

Ich versuche immer das alle Methoden einer klasse mit Units getestet werden (auch die Privaten etc), wenn ich nach TDD entwickel müsste ich beim dritten refactoring schritt ja ständig die Units anpassen-

//Dazu
Deine Rechnung mit den 90min kann ich schon nachvollziehen, und auch verstehen, aber das bezieht sich ja eher auf UnitTests überhaupt als auf die Entwicklung nach TDD.
Bei deinem Beispiel hast ja schon den Fertigen Code, ob du die Units durch TDD erstelltest oder nachträglich ist da doch irrelevant.

03.08.2010 - 10:32 Uhr

Die Properties in dem Args Objekt sind nicht dafür da zu erfahren ob es ein User klick war oder eine Zuweisung.
Es ist so das der sender immer der sender des Events ist, und bei e.OriginalSender (o.ä.) ist das konkrete Control welches dem sender veranlasste das Event zu schicken.

Was gehen könnte wäre das du mit HitTest das Control unter der Maus holst und dann schaust ob das der sender ist, dann ist die Wahrscheinlichkeit das es ein klick war deutlich höher.

Nur ob es den Aufwand wert ist? Ein boolean ist nicht teuer.

02.08.2010 - 20:15 Uhr

Versuch mal dieses

<Style TargetType="{x:Type FrameworkElement}">
    <Setter Property="TextBlock.FontSize" Value="20" />
</Style>

Aber ich glaube dann gilt das nur für die Controls die keinen eigenen Style haben, du müsstest dann bei allen Styles ein BasedOn definieren.

Ich glaub den Key in allen Window setzen ist die wenigste arbeit.

02.08.2010 - 17:31 Uhr

Selbstverständlich.
Nur er schrieb ja "Nie mehr ohne", also müsste er ja eine gute Lösung des Problems haben. Diese würde mich interessieren.

02.08.2010 - 17:29 Uhr

Also müssten doch eure Pattern nicht funktionieren da ihr alles klein schreibt.

02.08.2010 - 17:26 Uhr

Ein Window style hast du ja, im Prinzip reicht es ja wenn du in jedem Window den Style explizit setzt.

02.08.2010 - 17:00 Uhr

"Window" Styles werden nicht automatisch übernommen, das der Designer es zeigt ist eher der Fehler.

02.08.2010 - 16:23 Uhr

@Golo Roden
Mir tut sich gerade eine frage auf.

Du sagst

Das liegt daran, dass Du zuerst den Test schreibst, und dann nur gerade so viel Code, um den Test zu erfüllen

spricht das nicht etwas gegen die dynamic des Codes?
Hin und wieder ist es doch so, das wenn man eine klasse und deren Methoden das erste mal erstellt, sich später herausstellt das die Methoden etwas anders doch praktischer wären.
Wenn man dann Refactored, müsste man auch alle Unit neu beginnen -.-

Ich persönlich mach das immer so das ich die Units erst schreibe wenn die Klasse fertig ist, dann check ich per Units das die Klasse tut was sie soll bevor ich mich neuen aufgaben zu wende.

02.08.2010 - 16:04 Uhr

Und man kann doch bestimmt einbauen das es immer groß geschrieben ist, oder?

02.08.2010 - 13:39 Uhr

Einfach mit einem eigen flag "SelfChange" oder so merken ob es per vom User kommt oder nicht

im prinzip

private bool _selfChange;
private void OnDo()
{
    _selfChange = true;
    myComboBox.SelectedItem = "Text";
    _selfChange = false;
}

ComboBox.SelectionChanged(object sender, SelectionChangedEventArgs e)
{
    if (!_selfChange)
    {
        // eingabe kommt von dem User
    }
}

Ich glaube mich zu erinnern das es in Forms schon ein Build in Feature davon gibt aber in WPF nicht mehr

//Tags vergessen

02.08.2010 - 09:24 Uhr

Was hat den Linq mit den UnitTests zu tun?
Man testet die Methoden, ob intern manuell eine Liste iteriert wird oder es mittels Linq geschieht macht doch gar kein unterschied.

Eventuell ist er einfach noch dabei Linq zu lernen, zu beginn passieren nun mal mehr Fehler.

01.08.2010 - 21:45 Uhr

@CSL
Bei deinem Code muss ich ja in jedem Fenster noch eigenen Code implementieren, da ist mir meine Variante lieber.

Bei jedem Fenster? Ich habe solch ein Fenster bisher nur so selten gebraucht das es gar nicht lohnt da etwas "besseres" zu finden.

Wieso brauchst du diese Möglichkeit so oft?

01.08.2010 - 18:02 Uhr

Ich machs mir immer recht einfach

private SubWindow _subWindow;

private void ShowSubWindow()
{
    if (_subWindow == null)
    {
        _subWindow = new SubWindow();
    }
    _subWindow.Show();
}

private void CloseSubWindow(bool destroy)
{
    if (_subWindow != null)
    {
        _subWindow.Destroy = destroy; // Das Fenster cancelt "Closing" nicht wenn Destroy true (eigene Varable)
        _subWindow.Close();
        if (destroy)
        {
            _subWindow = null;            
        }
    }
}
01.08.2010 - 13:36 Uhr

Wenn man ein Spezifizierten ctor UND einen leeren anbieten will muss man den leeren auch angeben da durch den Spezifizierten der Default ctor überschrieben wird.

Das ist alles andere außer Coding Style Horror.

01.08.2010 - 13:25 Uhr

Das man alles mit Units abdeckt ist die Definition von TDD? Ich dacht bei TDD geht es auch um die Reihenfolge, also erst Tests und dann ausbauen der Methoden?
Was du beschreibst ist doch Standard Unittesting. Mach ich auch so, ohne das ich sage das ich nach TDD entwickel.
Muss mir endlich mal ein Buch darüber holen ^^

31.07.2010 - 18:10 Uhr

Ich glaube der Punkt Refactoring ist an der stelle besonders hervor zu heben.

Gerade wenn man weiß das man ein Modul komplett abgedeckt hat und sie mit einem Knopfdruck verifizieren kann, hilft das dabei das man schnell mal ein paar Sachen fixt oder abändert, man kann dann jederzeit einfach nochmal den Knopf drücken und schauen ob man etwas kaputt gemacht hat.

Auch im Buch von Fowler (http://www.amazon.de/Refactoring-Studentenausgabe-vorhandener-verbessern-Programmers/dp/3827322782/ref=sr_1_9?ie=UTF8&s=books&qid=1280592376&sr=8-9) sieht man das, wenn man Units hat, viel effektiver bestehenden Code verbessern kann.

Bei meinem Tool auf arbeit zb folge ich der regel das ich nach jedem Refactoring Schritt ein weiterhin funktionierendes Modul habe.

Ich entwickel nicht nach dem TDD; Wollte mir mal noch ein Buch darüber besorgen. Aber ich schreibe schon Unit Tests (aber noch nicht so lange).

Hatte erst gestern wieder den klassischen Fall.
Wir hatten ein Bug entdeckt, ich habe ihn mit einem UnitTest reproduzieren können.
Beim Fixen habe ich dann immer wieder alle Units dieses Moduls laufen lassen, und es war erst gefixt wenn alle units wieder gepasst haben.
Bug gefunden -> Reproduziert mit einer Unit -> Gefixt -> Verifiziert mit den Units.

31.07.2010 - 10:06 Uhr

Und ich hätte direkt mal eine Aufgabe:
Man hat eine TextBox und eine ListView, nach doppelklick auf ein Item wird ein Wert genommen und die Markierung in der TextBox damit ersetzt, der Focus liegt dann auch in der TextBox.

Ich mach das so:

private void ListViewItem_MouseDoubleClick(object sender, MouseButtonEventArgs e)
{
	Placeholder item = ((ListViewItem)sender).Content as Placeholder;
	if (item != null &&
		item.Pattern.Contains("%"))
	{
		int startPos = String_TextBox.SelectionStart;
		string content = String_TextBox.Text;
		content = content.Remove(startPos, String_TextBox.SelectionLength);
		content = content.Insert(startPos, item.Pattern);
		String_TextBox.Text = content;
		String_TextBox.SelectionStart = startPos;
		String_TextBox.SelectionLength = item.Pattern.Length;
		GiveTextBoxFocus();
	}
}

private void GiveTextBoxFocus()
{
	String_TextBox.Dispatcher.BeginInvoke(new Action(delegate
	{
		String_TextBox.Focusable = true;
		String_TextBox.Focus();
		Keyboard.Focus(String_TextBox);
	}),
	DispatcherPriority.Render);
}

Das Ganze Fenster macht sonst nichts, es geht nur um den Zusammenbau eines Strings mit platzhaltern.

Aufruf ist dann einfach

private void OnDo()
{
	FileNameWindow window = new FileNameWindow();
	if (window.ShowDialog() == true)
	{
		string newFileName = window.FileName;
	}
}

Warum sollte ich eine so kleine Klasse mit MVVM aufblähen, (Siehe "MVVM auch in kleinen Dialogen") (Die Klasse hat nur 3 Methoden + Ctor)
und wie würde man das mit MVVM korrekt lösen
zu welchen Vorteil?

Ich frag auch einfach mal so hinein:
Welchen Vorteil Bringt mir das MVVM Pattern allgemein?

31.07.2010 - 10:02 Uhr

von Aussagen wie

hei, wacht auf, ihr habt das Ziel aus den Augen verloren
...
Alter, das ist nur eine Billige TreeView, das ist Kindergarten -.-
kann ich gar nichts halten.

Ja OK, das war eventuell ein bisschen sehr reißerisch, vergessen wir das 😉

Das sind die Basisobjekte
Ja das sind sie 😉

Einige deiner genannten Beispiele betreffen nur die UI wie zB Focus in einer TextBox setzen. Warum sollte hier auch MVVM oder irgendein anderes Verfahren zur Trennung von UI und Logik (wenn ich das in der Antwort nochmals erwähne kürze ich das mit M* ab) angewandt werden? Es gibt keinen Grund dafür denn das ist UI-Aufgabe (-> Code-Behind, Behaviour, ...)

Genau da fängt es an kompliziert zu werden, denn wenn das Setzen des Focus aus dem Code heraus angetriggert wird, muss die ViewModel irgendwie der View sagen das es seine Focus Position verschieben muss, und da verschwimmt es dann etwas.

Das "Event holen" hab ich erst verstanden als ich "Attached Behavior" gelesen habe. Das zielt ja alles auf UI ab und hat mit Logik nichts zu tun. Hier ist klarerweise kein M* notwendig.

Du meinst also die View abonniert das Event in die Code Behind rein und ruft dann explizit etwas im ViewModel auf? Verletzt man damit nicht die Trennung? EIn Attached Behavior wäre die einzigste saubere Trennung wenn man eine ViewModel lose Binden will.

"Drag&Drop". Im UI wird ein Element von der D&D-Quelle zur D&D-Senke gezogen und anschießend muss diese "Transaktion" in den Datenobjekten durchgeführt werden. Hier liegt doch (auch ein) klassischer Fall für die Trennung von UI und Logik vor.
In deinem verlinkten Blog erinnert mich das sehr an meine WinForms-Anfänge wo alles in der Form.cs codiert wurde. Eine Trennung von UI und Logik ist nicht zu erkennen. UI-Code und Logik-Code in der selben Klasse halte ich für nicht sinnvoll. Diese Trennung wird mMn durch die Trennung von XAML und Code-Behind nicht hergestellt. Die Code-Behind leitet immerhin von UIControl ab und ist somit eindeutig UI 😉 Welche Logik? Die Drag&Drop Aktionen sind doch reine UI Aktionen, nur das umschieben der Objekte in den Listen, und auch das kann die View machen.

Für "Eine Liste von dynamisch erstellten UserControls in einer ListBox"
wenn es UCs zur Datenhaltung sind sollte das wohl auch getrennt werden und die Daten müssen eh in einer Liste im Model verwaltet werden.
Selbiges gilt für "sobald mehrere Objekte in einer UI angezeigt werden".

Angenommen wir haben 3 absolut unterschiedliche UserControls, diese müssten mit ViewModels versehen werden, und irgendwie mit etwas voodoo mit den Daten verbunden werden, und auch da kann es sein das das Selbe objekt in zwei verschiedene UserControls passen kann, d.h. DataTemplate anhand des Types geht nicht, das Binden der UC DataContexen gegen verschiedene ViewModels, diese ViewModels müssen die korrekten Daten bekommen .... Alles Problem die eigentlich leicht zu umgehen wären.

Ob nun die ViewModel der Proxy ist oder die Code Behind
Ein ViewModel ist kein Proxy für die UI - es gibt keine gemeinsame Basis - sondern eher ein Mediator 😉

Mit Proxy meinte ich eherdas die ViewModel zwischen Model und View vermittelt, so wird es ja auch immer beschrieben, aber lassen wir das.

Dass Trennung der Anliegen in mehr Code resultiert ist klar, aber ein Monolith ist auch nicht das Wahre.

Richtig, daher kann die CodeBehind sich um sachen kümmern die die UI betreffen, und weitere Aktionen landen dann in den entsprechenden klassen, so bleibt auch ohne MVVM die CodeBehind sehr schlank.

Ich entwickel nach einem "MVC" muster, ich setz es in quotes da es kein richtiges MVC ist, eher eine Abwandlung davon
View ist die Xaml, ist klar, und meine CodeBehind ist der Controller, die CodeBehind kümmert sich um aktionen UI betreffend, und Delegiert weitere aufgaben in verschiedene klassen. Somit habe ich meine View und meine Models problemlos getrennt.
Dort noch ein Objekt dazwischen schalten halte ich für unnötig.

Auch ohne MVVM bekommt man eine saubere Trennung
Da stimme ich dir zu. Vielleicht hast du ja bemerkt dass ich in dieser Antwort MVVM nie als Ideal dargestellt habe - immer nur die Trennung von UI und Logik. Ob MVVM das ideale Muster für WPF ist weiß ich nicht (hab noch zu wenig Erfahrung mit WPF, das ändert aber nichts an den Aussagen die ich hier mache). Es hat ja auch Nachteile (zB dass die UI fast zwangsweise WPF sein muss und nicht ein WinForms oder ASP.net sein kann). Obwohl ich mir beim Schreiben von Vor- und Nachteil fast schwer tue, denn ein Leitfaden ist so lose definiert dass es sich (fast) beliebig "verformen" lässt. Insofern sehe ich die Übergänge zwischen MVP, Presentation Model, MVVM, ... als "fast fließend" an. Bei Mustern gibt es keine harte Regeln wie in der Mathematik dass 0!=1 ist und somit kann und soll man diesen Spielraum zum Vorteil ausnutzen.

Jup, kann ich direkt zustimmen.

dann kann es auch gleich die Code Behind sein
Da fühle ich wieder in die WinForms-Anfänge zurückversetzt. Sorry, aber das sehe ich so.

Sie meine Aufführung von gerade eben, wenn du es sauber aufdröselst, hast du weiterhin eine schlanke code behind und die logik getrennt von der View. Man könnte meinen das die Code Behind die ViewModel ist.

Ich hab zufällig
>
gesehen und da finde ich deinen "Sinnenswandel" interessant.
Vor allem genau das was ich hier auch erwähnt habe:

ich kann mir nur vor stellen das die logic in der behind steckt und ui in der xaml
das ist aber keine trennung
Du wirst sicherlich die Gründe dafür haben - darauf müssen wir nicht eingehen.

Ich war zu beginn sehr Fanatisch, das ist korrekt, nach einer weite merkte ich aber das ich im Prinzip nur noch für dem MVVM entwickelt habe, das mein Focus völlig falsch war, ich dachte nie "Wie löse ich das Problem" sondern "Wie löse ich das problem auf dem MVVM weg"
Ich hatte sehr viel Mehrarbeit, nur weil ich unbedingt immer nach dem MVVM arbeiten wollte.
Bitte nicht falsch verstehen, ich bin kein MVVM Gegner geworden, wenn es angemessen ist entwickel ich auch nach dem MVVM Muster, nur meist brauchte ich die vorteile des MVVM nicht sodass es sich nicht lohnte, wobei die Vorteile mittlerweile schon recht verschwommen sind.

Schade dass ich diesen Beitrag nicht früher gefunden habe denn der
>
deckt sich ziemlich mit meiner Einstellung zum Thema.

Ich werde diese Diskussion aber nicht weiterführen denn wenn ich sehe wie du deine Meinung zum Thema geändert hast - wer weiß wie ich das sehen werde wenn ich mehr Erfahrung habe 😉

Man kann sagen das ich meine Meinung geändert habe da ich mal richtig nach gedacht habe das ich überhaupt alles für Aufwand betreibe, und ob sich das alles überhaupt lohnt. Reflektion & Hinterfragen

Es hat sich in der WPF "szene" irgendwie dazu entwickelt das alle gleich rufen man sollte dies und das mit MVVM machen, das liest sich meistens so als wäre MVVM der einzigst gangbare weg (Auch dein Startbeitrag in diesen Thread liest sich so).
Nur bei MVVM ist es genauso wie hier geschrieben wird, nicht pauschal alles mit ein Pattern erschlagen wollen (so wie auch ich das machte) sondern abwägen ob es sinn macht.

Siehe auch winsharps comment in den von dir verlinkten Beitrag:
"Stattdessen kann man IMHO ohne MVVM mit der WPF keine anständige, komplexere Anwendung schreiben"
Das sehe ich ganz und gar nicht so.
Nur weil man die Code Behind verwendet heißt das nicht das man nicht Bindet, das man Controls.Add oder so aufruft...

30.07.2010 - 18:46 Uhr

desktop auf arbeit - win xp

Hei, Litestep, lang nicht mehr gesehen, wusste gar nicht das es das noch gibt 😄

Meine Desktops (arbeit und daheim) sind meist eines dieser bilder hier:

http://pictures.my-libraries.de/Wallpapers/
Immer ungestreckt über beide Monitore, ich mag es nicht wenn die Bilder doppelt sind.
Die Originalen Desktops zeige ich nicht da es nichts zu zeigen gibt, sind immer absolut Leer, den Desktop benutz ich nie.

30.07.2010 - 18:39 Uhr

Das sind die Basisobjekte
Aber was ist mit Events, wenn man ein Window den DialogResult setzen will, Drag & Drop, alles Standard Aktionen die mit MVVM einiges an Arbeit erfordern.
Auch Standard Aktionen wie Synchronisieren einer List aus den Model zu einer ObservableCollection.
Alles zusätzliche arbeit die notwendig wird wenn man MVVM einsetzt.

Event holen:
Normal: EventHandler registrieren
MVVM: Ein Attached Behavior schreiben oder eine generische Klasse einsetzen

DialogResult:
Normal: Einfach this.DialogResult = true;
MVVM: http://stackoverflow.com/questions/501886/wpf-mvvm-newbie-how-should-the-viewmodel-close-the-form

Drag & Drop:
Normal: Events holen und direkt interagieren Link
MVVM: Behaviors schreiben und je nach Aktion anpassen Link

Focus in einer TextBox setzen:
Normal: Direkt this.Dispatcher.BeginInvoke(action)
MVVM: Keine Ahnung, bestimmt auch irgendwie wieder über ein Attached behavior.

Eine Liste von dynamisch erstellten UserControls in einer ListBox:
Normal: Die Controls in einer Liste im Code und die View bindet dagegen
MVVM: Da muss irgendwie wieder ein Wrapper dazwischen da die ViewModel die UserControls nicht halten darf und die UserControls alle auch eigene ViewModels bräuchten, ich hatte dafür mein UserControlsHelper.

Könnte das ewig fortsetzen.

Die Drei Objekte von dir sind wie gesagt die Basisobjekte, sobald mehrere Objekte in einer UI angezeigt werden hast du wieder Wrapper und dadurch alles *2.

Ich hatte mal ein Mittelgroßes Projekt von MVVM auf "MVC" refactored und erreichte dadurch 150 unnötige Dateien weniger, deine Deutlich einfachere Struktur (da der overhead weg fiel) und das bei gleichen Funktionsumfang.

http://www.codeproject.com/KB/WPF/TreeViewWithViewModel.aspx => Alter, das ist nur eine Billige TreeView, das ist Kindergarten -.-

[erledigt] Dialog schließen mit MVVM
WPF - Menu IsChecked
MVVM TabItem -> Selector.Selected Event an ViewModel übergeben
Bindingproblem, Property mit Event ändern (MVVM)
TreeView ParentItem selektieren (MVVM)

So viele Probleme nur weil Leute "dem MVVM gerecht sein wollen", hei, wacht auf, ihr habt das Ziel aus den Augen verloren, es geht nicht darum es ein Pattern recht zu machen, ein Pattern soll helfen und nicht unnötige Mehrarbeit machen.

Welchen vorteil bringt mir MVVM das es so viel Mehrarbeit rechtfertigt?
Und bitte nicht nur auf diese Frage eingehen und mein bisher geschriebenes ignorieren 😉

//Dazu: Auch ohne MVVM bekommt man eine saubere Trennung 😉 Die ViewModels sind meistens der View zugeschnitten, dann kann es auch gleich die Code Behind sein, und wenn man die sauber aufzieht ist sie genauso Testbar und Modular. Ob nun die ViewModel der Proxy ist oder die Code Behind, wayn

30.07.2010 - 16:00 Uhr

Anders im Code aufbauen.

Du hast eine Liste von "Folder" Objekten und Bindest das gegen den Tree, im Tree bindest du den angezeigten text wiederum an ein Property welches nur den aktuellen Pfad zurück gibt.
So kannst du auch sehr einfach ein Lazy Loading implementieren, indem zu das IsExpanded des TreeViewItems gegen ein Boolean bindest.

//Pseudo

internal class Folder : INotifyPropertyChanged
{
	public Folder(string path)
	{
		Folders = new List<Folder>();
                //dummy child erstellen wenn childs vorhanden
		Path = path;
	}

	public string Path { get; private set; } // D:\Bla\Fasel

	public string Name
	{
		get { return PathNameExtractor.GetName(Path); } // Fasel
	}

	public List<Folder> Folders { get; set; }

	public bool IsOpened
	{
		get { return _isOpened; }
		set
		{
			_isOpened = true;
                        // wenn nicht geladen war entferne dummy und lade die korrekten subfolders
			// load child folders
		}
	}
	private bool _isOpened;
}

Im Code arbeitest du nur mit dem "Folder" objekt, und der kennt sein "Path" 😉

30.07.2010 - 15:44 Uhr

@Xeres

Und wo hast du deine Eventhandler? Oder versuchst du aus dem Code heraus auf "btnTest" zu zu greifen? Das geht natürlich nicht da diese Objekt erst zur Laufzeit generiert werden.

Die Lösung des Problems ist entweder den EventHandler direkt in der Xaml zu zu weisen, oder ein Command zu binden.

Ein static RoutedCommand mit einem CommandBinding oder ein ICommand mit Binding, wie ist dir überlassen.
Wie ich sehe hast du das bereits.

@gfoidl
Ich glaube zero_x meinte eher das es nicht viel bringt gleich bei jeden Pups auf MVVM hin zu weisen wie es in WPF oft gemacht wird, ein einfachen hinweis das man gegen ein ICommand binden kann reicht vollkommen, Pattern hin oder her.

Dazu sei auch gesagt das man auch gegen die Code Behind binden kann, oder gegen ein Controler, oder...
es gibt viele Wege.

Speziell bei MVVM sehe ich deutlich zuviel overhead für ein nutzen der praktisch nicht da ist, man kann auch binden und keine direkten UI Zugriffe haben ohne gleich die ViewModel Objekte zu implementieren, wenn man mal schaut was für kKämpfe MVVM Libraries eingehen müssen, allein schon für die Verwendung von Events.
Wenn man sich die MVVM Diagramme an sieht, Tonnen an Objekten die nur nötig sind um MVVM ein zu setzen -> der Focus liegt völlig falsch.

30.07.2010 - 11:31 Uhr

Wann und wo kommt diese Exception?
Kannst du mal bitte den Xaml Code zeigen? (aufs wesentliche gekürzt)

30.07.2010 - 10:00 Uhr

Nuargs was is das nu.

Finde ich merkwürdig

Was ich gemacht habe

  1. In den Settings "Feeds alphabetisch Sortieren" aktiviert
  2. Nach dem neu laden der Feeds waren plötzlich alle Artikel alphabetisch sortiert
  3. Habe es wieder deaktiviert
  4. nun sind die Artikel wieder nicht mehr sortiert, aber die Feeds leider auch nicht mehr

Ist:
Wenn "Feeds alphabetisch Sortieren" ausgewählt ist werden die Feeds sowie die Artikel sortiert

Erwartet:
Wenn "Feeds alphabetisch Sortieren" ausgewählt ist werden die Feeds sortiert, die Artikel aber bleiben unverändert.

30.07.2010 - 09:53 Uhr

Stimmt, jetzt geht es wieder.
Hat beim ersten versucht aber gecrashed (Report ist gesendet) Hatte das Update aus dem Settings Dialog heraus aufgerufen, ein Update aus dem Contextmenü des Tray Icons hat funktioniert.

30.07.2010 - 09:48 Uhr

Das automatische Update funktioniert bei mir nicht mehr:

Während der Updatesuche ist folgender Fehler aufgetreten: Die zugrunde liegende Verbindung wurde geschlossen: Unerwarteter Fehler beim Senden

Die Verbindung mit dem Remoteserver kann nicht hergestellt werden.

Die jetzige Version des feedCarrier is 1.1.259.722.

Proxy wird automatisch ermittelt, aber auch manuelle Eintragung bringt nichts.

29.07.2010 - 20:00 Uhr

FYI: SlimDX muss installiert werden, die dll alleine reicht nicht. (Deswegen habe ich es bei mir nicht getestet)

29.07.2010 - 13:34 Uhr

Hallo,

Ich weiß nicht ob das wirklich Ajax ist, aber ich glaube schon.

Ich kenne es aus ein anderen Forum das man unter den Beiträgen eine TextBox hat wo man direkt Antworten kann ohne das man auf ein "Antworten" Button klicken muss und ein neues Fenster auf geht.

Ist sowas hier auch geplant? Wäre schon nett.
Dann könnte man den Beitrag dann auch unten neu dran packen ohne das die Komplette Seite neu geladen werden muss 😁

LG
CSL

29.07.2010 - 13:32 Uhr

Ne du läst den RadioButton schon im Xaml, im object hast du dann nur Boolean property

public bool IsChecked
{
	get { return _isChecked; }
	set
	{
		_isChecked = value;
		OnPropertyChanged("IsChecked"); // stichwort INotifyPropertyChanged
	}
}
private bool _isChecked;

und das Bindest du dann

<DataTemplate>
    <RadioButton IsChecked="{Binding IsChecked}" />
</DataTemplate>

In der Liste (ObservableCollection) wo die objekte dann sind kannst du immer einfach das PropertyChanged fangen, dort prüfst du ob "IsChecked" geändert wurde und hast dann direkt das entsprechende Objekt als sender.

=> Fällt alles unter WPF Basics 😉

29.07.2010 - 13:28 Uhr

Ich kenne solch eine Exception meist nur wenn versucht wird auf ein Property zu zu greifen was nicht existiert.

Bei dem hier:
(TextElement.Background).(SolidColorBrush.Color)
wird im Prinzip das gemacht:

((SolorColorBrush)myControl.Background).Color = value;

d.h. es muss ein SolorColorBrush im Background Liegen.

Ändere mal dein
<TextBlock FontSize="20" FontWeight="Bold" Padding="20 5">
nach
<TextBlock FontSize="20" FontWeight="Bold" Padding="20 5" Background="Transparent">

Was hast du eigentlich vor, bzw was willst du erreichen? Wo Steckt diese TextBox wenn du von irgendwelchen "Filtern" sprichst.

29.07.2010 - 07:38 Uhr

Das geht problemlos über die Margins des Controls.

28.07.2010 - 20:37 Uhr

In den Source auf der Seite sieht man
Storyboard.TargetProperty="(Background).(SolidColorBrush.Color)"

Das mal Probiert?

Blend gibt mir das hier:

<ColorAnimationUsingKeyFrames Storyboard.TargetProperty="(TextElement.Background).(SolidColorBrush.Color)">
    <EasingColorKeyFrame KeyTime="0" Value="Yellow"/>
    <EasingColorKeyFrame KeyTime="0:0:0.1" Value="Red"/>
</ColorAnimationUsingKeyFrames>

//Fix tag

28.07.2010 - 19:11 Uhr

Du brauchst nur ein konkretes Objekt pro Row, das kannst du mit einem Boolean Property ausstatten und den RadioButton dagegen Binden.
Nun fängst du nur noch das PropertyChanged des Objektes und bekommst gleich das entsprechende Objekt mit.

<Advertising>
Meine EnhancedObservableCollection hat ein ItemPropertyChanged event, sobald "CatchPropertyChanged" auf true steht fängt die Liste automatisch das PropertyChanged aller Items und schickt das ItemPropertyChanged event mit dem Objekt.
http://downloads.my-libraries.de/Libraries/Tulipa/Documentation/html/AllMembers_T_Tulipa_EnhancedObservableCollection_1.htm
</Advertising>

27.07.2010 - 22:41 Uhr

VERDAMMT - nun weiß ich noch schneller das es nix neues für mich gibt 😄

Die Geschwindigkeit ist echt beeindruckend 😃
(eigentlich AJAX geplant?)

26.07.2010 - 13:02 Uhr

Also bei mir ging es um dieses Control:
(Unwichtige Teile entfernt)

Ich wollte das die erste und letzte Column immer gleich groß sind, richtet sich also nach dem längsten Element.

<ItemsControl ItemsSource="{Binding ReleaseSummaries}" Grid.IsSharedSizeScope="true">
    <ItemsControl.ItemTemplate>
        <DataTemplate>
            <Grid>
                <Grid.ColumnDefinitions>
                    <ColumnDefinition Width="Auto" SharedSizeGroup="First" />
                    <ColumnDefinition />
                    <ColumnDefinition Width="Auto" SharedSizeGroup="Last" />
                </Grid.ColumnDefinitions>
                <TextBlock Text="{Binding Release}" Margin="10,2" />
                <ListBox ItemsSource="{Binding WorkingRanges}" Grid.Column="1" Background="Transparent" BorderThickness="0" />
                <TextBlock Text="{Binding Summary}" Grid.Column="2" Margin="10,2" />
            </Grid>
        </DataTemplate>
    </ItemsControl.ItemTemplate>
</ItemsControl>

Wenn ich dort IsSharedSizeScope weg lasse, sind die Columns immer auf Auto, also unterschiedlich groß, mit dem IsSharedSizeScope ist alles wie gewünscht.

//Dazu
Sobald das Grid im ItemTemplate ist hatt man ja pro Item ein Grid und somit > 2 😉

26.07.2010 - 11:24 Uhr

Wenn MyXaml aber ein dp sein muss, dann musst du natürlich noch eine Verbindung von der RichTextBox zum Property her stellen.

26.07.2010 - 11:04 Uhr

Genau, das sind aber WPF Basics, ich bin versucht dich auf Punkt 1.1.1 hin zu weisen => [Hinweis] Wie poste ich richtig?

26.07.2010 - 10:55 Uhr

Dann musst du das Xaml Property der RichTextBox gegen das Property des UserControls Binden.

26.07.2010 - 10:46 Uhr

Ich versteh immer noch nicht, das Property gibt doch korrekt dein Xaml Wert zurück, wo ist das Problem?

26.07.2010 - 09:55 Uhr

Ich versteh die frage nicht, wenn das dp korrekt definiert ist (snippet), kannst du auf das Property wie gewohnt zu greifen.

26.07.2010 - 09:18 Uhr

Ich hab gestern Abend das erste mal ein kleines Projekt bei GitHub gepushed, war gar nicht zu einfach eine Verbindung auf zu bauen wenn man keine Ahnung von SSH und Putty etc hat 😄

http://github.com/DavidWCSL/CC-Watcher

Mein Ziel ist dabei nicht meinen Marktwert zu steigern, vielmehr die Sourcen raus zu geben da andere eventuell Interesse haben. Völlig uneigennützig.
Werde die Binaries und Screens demnächst auf meinem Blog veröffentlichen.

26.07.2010 - 09:11 Uhr

Info: Ind er Lösung auf der Website wird Min und Max nicht gebücksichtigt 😉
Wir hatten das erst letztens hier:
WPF: Button statt Fenstertitel
Siehe mein Beitrag.

26.07.2010 - 09:07 Uhr

Ich bin mir da auch nicht sicher, aber ich hatte auch mal solch eine Liste und musste um die Columns im ItemTemplate zu sharen es in der Liste setzen.

Bei mir hatte das sharen nicht geklappt und war dann dort gelandet:
http://stackoverflow.com/questions/1102734/how-can-i-make-a-column-in-a-listbox-in-wpf-the-same-width-for-all-items
Und dort war die Lösung, welche bei mir funktionierte, dies Property in der Liste zu setzen.

25.07.2010 - 18:11 Uhr

Wenns statisch ist dann pack das Hallo doch einfach direkt ins Template

<DataTemplate x:Key="HalloTreeViewItemTemplate">
    <TextBlock Text="Hallo" />
</DataTemplate>

<TreeViewItem HeaderTemplate="{StaticResource HalloTreeViewItemTemplate}">
25.07.2010 - 10:09 Uhr

Hm?
Du hast doch noch das Grid in ItemTemplate wo SharedSizeGroup gesetzt ist -.-
Ohne dem sind doch alle deine Items wieder unterschiedlich lang - oder?

24.07.2010 - 22:48 Uhr

Ich meinte das du den angepassten Code mal Postest, eventuell hast du versehentlich was falsch gemacht

24.07.2010 - 22:36 Uhr

Nein das geht nicht.
Was möchtest du erreichen?

//Dazu
Du kannst in dem DataTemplate auch binden 😉