Laden...

ViewModelCollection an ItemSource übergeben

Erstellt von wettmasta vor 14 Jahren Letzter Beitrag vor 14 Jahren 4.682 Views
W
wettmasta Themenstarter:in
103 Beiträge seit 2007
vor 14 Jahren
ViewModelCollection an ItemSource übergeben

Moin moin,

ich habe ein kleines Problem und ich hoffe das ihr mir helfen könnt.

Ich habe in meiner Silverlight Anwendung ein TabControl und an dessen ItemSource möchte ich eine ViewModelCollection übergeben, zu jedem ViewModel in dieser Collection gibt es ein View, welches ich in dem jeweiligen Tab angezeigt haben möchte.
In WPF kann man das mit DataTemplates erreichen, in Silverlight ist diese Möglichtkeit ja aber leider nicht vorhanden.

Jemand Vorschläge?

Gruß
wettmasta

821 Beiträge seit 2009
vor 14 Jahren

Wie ich deiner PN entnehmen kann bist du ja schon auf meine hier genannte Lösung gestoßen:

http://www.mycsharp.de/wbb2/thread.php?threadid=77377&hilight=TemplateSelector

von daher kann der Topic geschlossen werden.

W
wettmasta Themenstarter:in
103 Beiträge seit 2007
vor 14 Jahren

Ähm nein, nicht ganz...
Du hast ja quasi ein eigenes Usercontrol geschrieben, ich muss aber das TabControl verwenden und dem ItemSource eine Collection von verschiedene ViewModels übergeben. Oder Habe ich etwas übersehen?

Gruß
wettmasta

821 Beiträge seit 2009
vor 14 Jahren

Mach doch einfach in jedes Tab dieses UserControl rein. Wenn du die DataType Property an den DataContext bindest (mit DataType={Binding}) dürfte es funktionieren

1.433 Beiträge seit 2006
vor 14 Jahren

Noch ein Vorschlag: Gib die Views als Collection an die ItemsSource des Tabpanels, die Views selber sollten in ihrem Context ja schon bereits ihr viewModel mitbringen.

Grüsse
Daniel
Space Profile
Wer nicht fragt, der nicht gewinnt

821 Beiträge seit 2009
vor 14 Jahren

Noch ein Vorschlag: Gib die Views als Collection an die ItemsSource des Tabpanels, die Views selber sollten in ihrem Context ja schon bereits ihr viewModel mitbringen.

Ist aber sehr unschön, damit müsste der ItemsSource, welcher im ViewModel sitzt ja über die View-Schicht bescheid wissen 😦

W
wettmasta Themenstarter:in
103 Beiträge seit 2007
vor 14 Jahren

Das Problem ist aber auch das die Itemsource vom Tabcontrol nur Tabitems akzeptiert...

821 Beiträge seit 2009
vor 14 Jahren

Das Problem ist aber auch das die Itemsource vom Tabcontrol nur Tabitems akzeptiert...

Eigentlich nicht, wie kommst du dadrauf ?

W
wettmasta Themenstarter:in
103 Beiträge seit 2007
vor 14 Jahren

Weil das so ist:)
Du kannst höchstes dem Content eines Tabitems ein UserControl zuweisen..

821 Beiträge seit 2009
vor 14 Jahren

Bist du sicher , dass du WPF / SL meinst und nicht WinForms:

Also wenn ich folgendes an IEnumerable<string> binde klappt das:

<Window x:Class="TestWPF.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        Title="MainWindow" Height="350" Width="525">
    <Grid>
        <TabControl ItemsSource="{Binding ItemsSource}">
            <TabControl.ContentTemplate>
                <DataTemplate>
                    <StackPanel Orientation="Vertical">
                        <TextBox Text="ich bin im Content" />
                        <TextBox Text="{Binding Mode=OneWay}" />
                    </StackPanel>
                </DataTemplate>
            </TabControl.ContentTemplate>
        </TabControl>
    </Grid>
</Window>
W
wettmasta Themenstarter:in
103 Beiträge seit 2007
vor 14 Jahren

<TabControl.ContentTemplate> Das gibts in WPF aber leider nicht in Silverlight...

P.S. Würde ich das ganze in WPF machen, hätte ich die ganzen Probleme nicht:(

1.433 Beiträge seit 2006
vor 14 Jahren

Noch ein Vorschlag: Gib die Views als Collection an die ItemsSource des Tabpanels, die Views selber sollten in ihrem Context ja schon bereits ihr viewModel mitbringen.

Ist aber sehr unschön, damit müsste der ItemsSource, welcher im ViewModel sitzt ja über die View-Schicht bescheid wissen 😦

eigentlich meine ich das so

TabControl
--> DataContext UserControl
--> Usercontrol hat den DataContext des ViewModels

Also eigentlich nicht's was auf meinen ersten Blick unschön wäre, denn die View in diesem Fall bekäme vom Model ja gar nicht's mit

Grüsse
Daniel
Space Profile
Wer nicht fragt, der nicht gewinnt

W
wettmasta Themenstarter:in
103 Beiträge seit 2007
vor 14 Jahren

Naja aber es soll eigentlich anders rum laufen, ich habe meine ViewModels und es ist egal mit welchem View man sie anzeigt.
Außerdem ändert es nichts daran, dass ein Tabcontrol nur Tabitems erwartet und keine anderen Usercontrols (in Silverlight).

821 Beiträge seit 2009
vor 14 Jahren

Naja aber es soll eigentlich anders rum laufen, ich habe meine ViewModels und es ist egal mit welchem View man sie anzeigt.
Außerdem ändert es nichts daran, dass ein Tabcontrol nur Tabitems erwartet und keine anderen Usercontrols (in Silverlight).

hmm sorry, hab mir grad nochmal zum Sichergehen das TabControl von SL angesehen, es leitet von ItemsControl ab und hat daher auch seine ItemsSource. Diese steht hier eindeutig als IEnumerabe und nicht als TabItems (geht ja auch nicht, da sie ja von ItemsSource definiert ist).

Verstehe nicht, wie du darauf kommst, bitte beleg es irgendwie anstatt zu erzählen, dass es so ist!

821 Beiträge seit 2009
vor 14 Jahren

Hi,

C#-Code:
List<UserControl> _NeueListe = new List<UserControl>();
_NeueListe.Add(new HerstellerCollView());
_NeueListe.Add(new KostenArtCollView());
TabTest.ItemsSource = _NeueListe;

Das bekomme ich als Fehler:
System.ArgumentException: Ein Objekt des Typs 'SilverlightApplication3.Views.HerstellerCollView' kann nicht in den Typ 'System.Windows.Controls.TabItem' umgewandelt werden.
bei System.Windows.Controls.TabControl.OnItemsChanged(NotifyCollectionChangedEventArgs e)

P.S. Oder sehe ich den Wald vor lauter Bäumen nicht mehr?!

Gruß
wettmasta

Du vermischt hier zwei Sachen!
wenn du es so machen willst, könnte höchstens TabTest.Items.Add(new KostenArtColView()); funktionieren
Damit würdest du jedoch auf die ganzen Vorteile von DataBinding / MVVM verwerfen.

P.S: Bitte hier im Forum weiterschreiben, nicht per PN, könnte ja auch andere interressieren, bzw. andere könnten eine Lösung wissen

W
wettmasta Themenstarter:in
103 Beiträge seit 2007
vor 14 Jahren

Nein, so will ich es nicht machen.
Ich will einfach nur der Itemsource des TabControls eine Collection von ViewModels übergeben und dann soll jedes Tabitem ein View(usercontrol) mit seinem dazugehörigen ViewModel anzeigen.

1.433 Beiträge seit 2006
vor 14 Jahren

Ich will einfach nur der Itemsource des TabControls eine Collection von ViewModels übergeben und dann soll jedes Tabitem ein View(usercontrol) mit seinem dazugehörigen ViewModel anzeigen.

Meiner Meinung nach wäre dass dann so aufgebaut:

View ==> TabItem
SubView im TabItem ==> Eine Page, die durch ein Frame bereitgestellt wird
ViewModel zur SubView ==> Diese wird ans Frame gebunden


Hi,

C#-Code:
List<UserControl> _NeueListe = new List<UserControl>();
_NeueListe.Add(new HerstellerCollView());
_NeueListe.Add(new KostenArtCollView());
TabTest.ItemsSource = _NeueListe;

Kann ja nicht sein, zu einer View gehört genau eine ModelView also müsste man in der Liste der UserControls den jeweiligen UserControls als DataContext, das jeweilige ModelView übergeben.

Grüsse
Daniel
Space Profile
Wer nicht fragt, der nicht gewinnt

821 Beiträge seit 2009
vor 14 Jahren

puh, falls ich heute abend noch zeit habe, implementier ich dir mal ne saubere lösung.

821 Beiträge seit 2009
vor 14 Jahren

Du hattest tatsächlich recht, das verkackte Control überprüft doch tatsächlich ob es nen TabItem bekommt. Hab da wohl voreilig reagiert und mir grad nochmal im Reflektor angeschaut was passiert. Er mappt sich da wohl das Event und flippt aus, wenn er nicht das bekommt was er will!

Hier die Codestelle:

       foreach (object obj2 in e.NewItems)
            {
                item = obj2 as TabItem;
                if (item == null)
                {
                    throw new ArgumentException(string.Format(CultureInfo.InvariantCulture, Resources.TabControl_InvalidChild, new object[] { obj2.GetType().ToString() }));
                }

Hab mich da schonmal sehr drüber aufgeregt, dass es bei Silverlight nicht so schöne DateTemplateSelectoren gibt, wie unter WPF. Ich finde das sollte ganz oben auf der ToDo - Liste stehen, dass sich WPF und Silverlight einheitlich und akorat programmieren lassen!

So, hab dementsprechen länger für die Lösung deines Problems gebraucht.
Hier meine Lösung, wie es noch einigermaßen schön hinzubekommen war:

  • ItemsSource des TabControls wird an IEnumerable gebunden
  • Damit TabControl nicht ausflippt bekommt die Bindung nen Converter mit, welcher die entsprechende ViewModel - Basisklasse in TabItem Convertiert und TabItem.Content mit einem UserControl bestückt (in der solution TabContentContainer), welches als Datenkontex die ViewModel - Basisklasse mitbekommt.
  • TabContentContainer übernimmt dann mit dem (ebefalls auch schon gewurschteltem) TemplateSelector-Workarround die Auswahl des eigentlichen Views

Gruß
MA

W
wettmasta Themenstarter:in
103 Beiträge seit 2007
vor 14 Jahren

Moin moin,
erstmal vielen Dank für deine Mühe, dein Ansatz sieht schon sehr gut aus!
Ich werde versuchen Ihn mal in meine Anwendung zu integrieren. Melde mich wieder wenn ich weiter gekommen bin.

Hab mich da schonmal sehr drüber aufgeregt, dass es bei Silverlight nicht so schöne DateTemplateSelectoren gibt, wie unter WPF. Ich finde das sollte ganz oben auf der ToDo - Liste stehen, dass sich WPF und Silverlight einheitlich und akorat programmieren lassen!

Das kann ich nur unterschreiben. Aber so wie ich das bis jetzt mitbekommen habe, wurde es auch noch nicht in SL4 integriert.

Gruß
wettmasta

W
wettmasta Themenstarter:in
103 Beiträge seit 2007
vor 14 Jahren

Moin moin,

erstmal ein ganz dickes Lob an meisteralex!
Habe deinen Ansatz in mein Projekt integriert und nach leichter Anpassung läuft es genau so wie ich es mir vorgestellt habe.