Autor Beitrag
UGrohne
ontopic starontopic starontopic starontopic starontopic starontopic starofftopic starofftopic star
Veteran
Beiträge: 5502
Erhaltene Danke: 220

Windows 8 , Server 2012
D7 Pro, VS.NET 2012 (C#)
BeitragVerfasst: Fr 03.04.09 16:42 
Hallo,

ich habe eine recht große Applikation mit dem MVVM-Pattern geschrieben und ein großes UI-Problem. Meine ChildWindows sind UserControls, die als Tabs dargestellt werden, wie in der MVVM-Demo-App von einem MSDN-Blog dargestellt. In diesen Controls habe ich teilweise beispielsweise TreeViews und TabControls. Wenn ich jetzt mehrere Tabs offen habe und von einem ins andere wechsel, wird beim Zurückwechseln der Inhalt zurückgesetzt, dabei beispielsweise aufgeklappte TreeView-Elemente wieder zugeklappt (ein Binding-Refresh denke ich mal), jedoch auch ausgewählte Tabs werden wieder zurückgesetzt.

Ich habe das in der MVVM-Demo-App, die ich angehängt habe, beispielhaft implementiert. Wenn Ihr die App startet, öffnet das "View All Customers"-Tab, danach das "Create New Customer"-Tab und wählt den Reiter Details aus. Da ist zwar nichts drin, das hab ich einfach mal zum Verifizieren reingebaut. Jetzt ins "View All Customers"-Tab wechseln und wieder zurück in das "Create New Customer"-Tab (also die geöffneten! Und dann seht Ihr, dass Ihr nicht mehr auf dem Details-Tab seid, sondern wieder auf dem Ersten.

Und genau das möchte ich verhindern, ich will nicht, dass der Inhalt des Fensters zurückgesetzt wird. Nur habe ich bisher keinerlei Ansatzmöglichkeit dafür gefunden. Die App habe ich mit Source angehängt.

Wahrscheinlich wird sich hier Kha als Erstes melden *g*.
Einloggen, um Attachments anzusehen!
Kha
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic star
Beiträge: 3803
Erhaltene Danke: 176

Arch Linux
Python, C, C++ (vim)
BeitragVerfasst: Fr 03.04.09 19:58 
Ich habe keine Ahnung, was da schief läuft :hair: . Aus irgendeinem Grund wird das User Control jedes Mal neu erstellt, aber ich kann mir erst recht nicht erklären, warum es im Projekt im Anhang anscheinend funktioniert (Debug-Output beachten).
Ich würde ja liebend gern mal mit dem Debugger reinschauen, aber da sich bei MS keiner mehr für den Source Server zu interessieren scheint... :roll:
Einloggen, um Attachments anzusehen!
_________________
>λ=
UGrohne Threadstarter
ontopic starontopic starontopic starontopic starontopic starontopic starofftopic starofftopic star
Veteran
Beiträge: 5502
Erhaltene Danke: 220

Windows 8 , Server 2012
D7 Pro, VS.NET 2012 (C#)
BeitragVerfasst: Fr 03.04.09 22:26 
user profile iconKha hat folgendes geschrieben Zum zitierten Posting springen:
Ich habe keine Ahnung, was da schief läuft :hair: . Aus irgendeinem Grund wird das User Control jedes Mal neu erstellt, aber ich kann mir erst recht nicht erklären, warum es im Projekt im Anhang anscheinend funktioniert (Debug-Output beachten).

Was funktioniert da? :shock:

user profile iconKha hat folgendes geschrieben Zum zitierten Posting springen:
Ich würde ja liebend gern mal mit dem Debugger reinschauen, aber da sich bei MS keiner mehr für den Source Server zu interessieren scheint... :roll:

*g*
Kha
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic star
Beiträge: 3803
Erhaltene Danke: 176

Arch Linux
Python, C, C++ (vim)
BeitragVerfasst: Fr 03.04.09 23:35 
user profile iconUGrohne hat folgendes geschrieben Zum zitierten Posting springen:
Was funktioniert da? :shock:
Sobald ich verschiedene Templates benutze, leider auch nichts mehr :( .
Wenn ich mir das TabControl-Template allerdings etwas genauer anschaue, dann wundere ich mich nicht mehr: Das eigentliche ItemsControl daran ist ja nur die Tab-Liste, der Inhalt des Tabs wird einfach über einen ContentPresenter gebunden:
ausblenden XML-Daten
1:
2:
3:
4:
5:
6:
7:
8:
<ContentPresenter
 Content="{TemplateBinding TabControl.SelectedContent}"
 ContentTemplate="{TemplateBinding TabControl.SelectedContentTemplate}"
 ContentStringFormat="{TemplateBinding TabControl.SelectedContentStringFormat}"
 ContentSource="SelectedContent"
 Name="PART_SelectedContentHost"
 Margin="{TemplateBinding Control.Padding}"
 SnapsToDevicePixels="{TemplateBinding UIElement.SnapsToDevicePixels}" />

Du bräuchtest also einen cachenden ContentPresenter... schon komisch, dass das anscheinend sonst noch niemandem gefehlt hat :gruebel: ... Mir fällt jedenfalls wirklich kein guter Workaround ein :( .
Das einfachste wäre es, dem TabControl direkt die getemplateten UIElements zu übergeben. Aber womit diese Transformation bewerkstelligen? ContentPresenter sieht im Reflector jedenfalls nicht so aus, als ob man ihm mal schnell die passendes-Template-Suche klauen könnte.

_________________
>λ=
UGrohne Threadstarter
ontopic starontopic starontopic starontopic starontopic starontopic starofftopic starofftopic star
Veteran
Beiträge: 5502
Erhaltene Danke: 220

Windows 8 , Server 2012
D7 Pro, VS.NET 2012 (C#)
BeitragVerfasst: Sa 04.04.09 08:26 
Das scheint nicht ganz des Rätsels Lösung zu sein: Wenn ich ein TabControl mit mehreren Tabs aufbaue und darin z.B. ein einem ein UserControl wieder mit einem TabControl mit mehreren Tabs einbaue, dann bekomme ich dieses Verhalten nicht, obwohl ich auch hier einen ContentPresenter als darstellendes Element habe.

Ich vermute irgendwie, dass es an der Collection liegt, von der diese Elemente kommen, aber ich kann das Phänomen im Moment nicht mal in einer nachgebauten Anwendung reproduzieren.
Kha
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic star
Beiträge: 3803
Erhaltene Danke: 176

Arch Linux
Python, C, C++ (vim)
BeitragVerfasst: Sa 04.04.09 12:02 
user profile iconUGrohne hat folgendes geschrieben Zum zitierten Posting springen:
Das scheint nicht ganz des Rätsels Lösung zu sein: Wenn ich ein TabControl mit mehreren Tabs aufbaue und darin z.B. ein einem ein UserControl wieder mit einem TabControl mit mehreren Tabs einbaue, [...]
...dann hast du genau das gemacht:
user profile iconKha hat folgendes geschrieben Zum zitierten Posting springen:
Das einfachste wäre es, dem TabControl direkt die getemplateten UIElements zu übergeben.


Das Problem tritt nur auf, wenn der ContentPresenter ad hoc aus den POCOs mithilfe des DataTemplates UIElements erzeugt und danach wieder verwirft. Würde dein ViewModel direkt die UIElements zurückgeben (*würg* :mrgreen:), würde es funktionieren.
Die sauberste Lösung wäre eine TabControl-Subklasse (mit attached Behaviour würde es wahrscheinlich auch funktionieren), die eine neue DP "SelectedElement" hinzufügt, welche SelectedContent mit SelectedTemplate kombiniert - aber dabei eben die Ergebnisse zwischenspeichert und wiederverwendet. Dann nur noch das ControlTemplate überschreiben, damit der ContentPresenter die DP benutzt. Aber, öhm... mir fällt gerade kein Aber ein, das sollte ja so wirklich funktionieren :shock: .

_________________
>λ=
UGrohne Threadstarter
ontopic starontopic starontopic starontopic starontopic starontopic starofftopic starofftopic star
Veteran
Beiträge: 5502
Erhaltene Danke: 220

Windows 8 , Server 2012
D7 Pro, VS.NET 2012 (C#)
BeitragVerfasst: Sa 04.04.09 13:08 
:gruebel: Das muss ich mir jetzt noch 1 bis 20 mal durchlesen, dann hab ichs auch verstanden *g*. Das muss ich mir nächste Woche mal genauer anschauen.
Kha
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic star
Beiträge: 3803
Erhaltene Danke: 176

Arch Linux
Python, C, C++ (vim)
BeitragVerfasst: Sa 04.04.09 16:26 
Hmpf, so leicht machen sie es uns dann wohl doch nicht... wenn das DataTemplate in den Ressourcen steckt, ist SelectedContentTemplate natürlich null... damit wären wir wieder bei dem Problem "wie baut man die Logik eines ContentPresenters nach"?

Nun, ich habe mich mal für einen leichteren Weg entschieden: Für jeden Tab-Inhalt erstelle ich einen eigenen ContentPresenter im Code, sodass der ContentPresenter des TabControls am Schluss einen weiteren ContentPresenter enthält XD.

Ähm, oder irgendwie so. Alles weitere im Anhang ;) .


PS: Ein Problem gab es noch - ein attached Behaviour hat nicht hingehauen, da zu dem Zeitpunkt tabControl.Template noch null war. Deswegen steckt der Aufruf jetzt hinterm InitializeComponent.
Einloggen, um Attachments anzusehen!
_________________
>λ=
UGrohne Threadstarter
ontopic starontopic starontopic starontopic starontopic starontopic starofftopic starofftopic star
Veteran
Beiträge: 5502
Erhaltene Danke: 220

Windows 8 , Server 2012
D7 Pro, VS.NET 2012 (C#)
BeitragVerfasst: Di 07.04.09 19:03 
Das funktioniert einwandfrei :)

Vielen Dank
Kha
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic star
Beiträge: 3803
Erhaltene Danke: 176

Arch Linux
Python, C, C++ (vim)
BeitragVerfasst: Mo 27.04.09 12:10 
Scheint so, als wären wir in prominenter Gesellschaft :D :
groups.google.com/gr...ead/6572f7781764f937
und eric.burke.name/dotn.../2009/04/26/22.09.28

Mein Ansatz gefällt mir trotzdem besser ;) .

_________________
>λ=
UGrohne Threadstarter
ontopic starontopic starontopic starontopic starontopic starontopic starofftopic starofftopic star
Veteran
Beiträge: 5502
Erhaltene Danke: 220

Windows 8 , Server 2012
D7 Pro, VS.NET 2012 (C#)
BeitragVerfasst: Mo 27.04.09 12:37 
Ja, mir auch. Poste doch mal nen Blog-Beitrag dazu *g*
Kha
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic star
Beiträge: 3803
Erhaltene Danke: 176

Arch Linux
Python, C, C++ (vim)
BeitragVerfasst: Mo 27.04.09 13:09 
Das wäre fast Grund genug, einen einzurichten - wäre das Schreiben auf Englisch nicht so anstrengend :mrgreen: .

_________________
>λ=