2 verbundene ComboBoxen DataBinding Fehler

  • WPF

Es gibt 5 Antworten in diesem Thema. Der letzte Beitrag () ist von SKeks.

    2 verbundene ComboBoxen DataBinding Fehler

    Hallo zusammen folgende Problemstellung:

    Ich habe 2 Comboboxen. Auf der ersten Combobox wird etwas ausgewählt und abhängig von dem SelectedItem soll die 2. Combobox gefüllt werden. Funktioniert. Wenn ich jetzt aber die Auswahl in der ersten Combobox ändere also das Binding der 2. Combobox auf eine andere ItemsSource setze tritt folgender Bindingfehler auf und zwar in der Anzahl wie die zweite Combobox Items hatte:

    System.Windows.Data Error: 4 : Cannot find source for binding with reference 'RelativeSource FindAncestor, AncestorType='System.Windows.Controls.ItemsControl', AncestorLevel='1''. BindingExpression:Path=VerticalContentAlignment; DataItem=null; target element is 'ComboBoxItem' (Name=''); target property is 'VerticalContentAlignment' (type 'VerticalAlignment')

    Ich interpretiere, dass die gebundene ObservableCollection der 2. Combobox verändert wird, ohne dass die ComboBoxItems darüber informiert werden und jetzt versucht WPF verzweifelt die Items anzuordnen. Ist eigentlich kein Problem, es funktioniert immer noch alles wie es soll, außer dass mein Ausgabefenster zugespammt wird :) . Kann trotzdem jemand bei diesem BindingFehler helfen?

    Ein weiteres Problem besteht nun, wenn die ObservableCollection für die 2. Combobox viele Items enthält, gibt's es auch im Release Built massive Verzögerungen. Bei 2500 Items knapp ca. 2 Sekunden, was ich schon als Einschränkung empfinde.

    Ein kurzes abgespecktes, wahrscheinlich nicht lauffähiges Beispiel zur Veranschaulichung:

    XML-Quellcode

    1. <Grid>
    2. <ComboBox Margin="2" ItemsSource="{Binding Länder}" SelectedItem="{Binding SelectedLand}" >
    3. <ComboBox.ItemTemplate>
    4. <DataTemplate DataType="Land">
    5. <TextBlock Margin="2, 1" Text="{Binding Name}"/>
    6. </DataTemplate>
    7. </ComboBox.ItemTemplate>
    8. </ComboBox>
    9. <ComboBox ItemsSource="{Binding SelectedLand.Städte}" SelectedItem="{Binding SelectedStadt}">
    10. <ComboBox.ItemTemplate>
    11. <DataTemplate DataType="Stadt">
    12. <TextBlock Margin="2, 1" Text="{Binding Name}"/>
    13. </DataTemplate>
    14. </ComboBox.ItemTemplate>
    15. </ComboBox>
    16. </Grid>


    VB.NET-Quellcode

    1. Public Class LänderViewModel
    2. Private _Länder As New ObservableCollection(Of Land)
    3. Public Property Länder As ObservableCollection(Of Land)
    4. Get
    5. Return _Länder
    6. End Get
    7. Set(value As ObservableCollection(Of Land))
    8. _Länder = value
    9. RaisePropertyChanged("Länder")
    10. End Set
    11. End Property
    12. Private _selectedLand As Land
    13. Public Property SelectedLand As Land
    14. Get
    15. Return _selectedLand
    16. End Get
    17. Set(value As Land)
    18. _selectedLand = value
    19. RaisePropertyChanged("SelectedLand")
    20. End Set
    21. End Property
    22. End Class
    23. Public Class Land
    24. Public Property Name As String
    25. Private _Städte As New ObservableCollection(Of Stadt)
    26. Public Property Städte As ObservableCollection(Of Stadt)
    27. Get
    28. Return _Städte
    29. End Get
    30. Set(value As ObservableCollection(Of Stadt))
    31. _Städte = value
    32. RaisePropertyChanged("Städte")
    33. End Set
    34. End Property
    35. Private _selectedStadt As Stadt
    36. Public Property SelectedStadt As Stadt
    37. Get
    38. Return _selectedStadt
    39. End Get
    40. Set(value As Stadt)
    41. _selectedStadt = value
    42. RaisePropertyChanged("SelectedStadt")
    43. End Set
    44. End Property
    45. End Class
    46. Public Class Stadt
    47. Public Property Name
    48. End Class


    Besitzt nun ein gewisses SelectedLand.Städte viele Einträge dauert es die angesprochene Zeit bis die 2. Combobox ansprechbar ist. Wechsele ich nun das Land tritt der og. Bindingfehler auf und es dauert wieder seine Zeit.

    Edit: Das Problem ist im Netz bekannt und es wird geraten mit einem VirtualizingPanel für die Combobox zu arbeiten. Das ist NICHT die Lösung. Im Debugmodus sieht man, dass ein Haufen neuer Arbeitsspeicher benötigt wird sobald man die ItemsSource ändert. Es werden also ALLE Combobox-Items neu generiert und nicht nur die sichtbaren

    Edit 2: Ich sehe gerade, dass jemand exakt das Beispiel in c# erklärt hat social.technet.microsoft.com/w…es-in-wpf-using-mvvm.aspx. Auch dort tritt das Problem auf.

    Edit 3: Wenn man explizit das Alignment setzt tritt der Fehler nicht mehr auf!!!

    XML-Quellcode

    1. <ComboBox.ItemContainerStyle>
    2. <Style TargetType="{x:Type ComboBoxItem}" BasedOn="{StaticResource {x:Type ComboBoxItem}}">
    3. <Setter Property="HorizontalContentAlignment" Value="Left"/>
    4. <Setter Property="VerticalContentAlignment" Value="Center"/>
    5. </Style>
    6. </ComboBox.ItemContainerStyle>

    ​Allerdings ist die Geschwindigkeit immer noch nicht überzeugend bzw. hat sich nicht geändert

    Dieser Beitrag wurde bereits 4 mal editiert, zuletzt von „SKeks“ ()

    Hallo

    Erstmal ist die Sache die, das ich denke das den Bindingfehler welcher von dir gezeigt wir nicht aus dem Binding in deinem obigen XAML stammt.

    Setze mal bei der Combobox welche auf Länder gebunden ist das IsSyncronisizedWithCurrentItem auf True und das SelectedItem PRoperty zur Sicherheit explizit auf TwoWay.

    Dein Einwand mit dem Virtualizing Stackpanel ist nicht korrekt. Diese Option bringt einen enormen(!!!) Performanceschub, nur muss man aufpassen das es überhaupt greift, was nicht immer der Fall ist. Besonders wenn man ein DataTemplate verwendet. Hier muss auf einiges geachtet werden.

    Grüße
    Sascha
    If _work = worktype.hard Then Me.Drink(Coffee)
    Seht euch auch meine Tutorialreihe <WPF Lernen/> an oder abonniert meinen YouTube Kanal.

    ## Bitte markiere einen Thread als "Erledigt" wenn deine Frage beantwortet wurde. ##

    Hi,
    danke für die Antwort. Das DataTemplate habe ich benutzt um mit dem Margin den angezeigten Text ein wenig nach rechts zu schieben. Benutze ich DisplayMemberPath dann bekomme ich das gleich Ergebnis.
    ​Das Problem mit dem Binding Fehler habe ich lösen können sie erster Post Edit 3.

    ​Mir scheint einfach, dass eine Combobox jedes mal neue ItemContainer erstellt, sobald man die Source wechselt
    Und hast du jetzt noch probleme mit der Performance oder etwas anderen?
    Das Poste am besten den aktuellen(!!) Code.

    Grüße
    Sascha
    If _work = worktype.hard Then Me.Drink(Coffee)
    Seht euch auch meine Tutorialreihe <WPF Lernen/> an oder abonniert meinen YouTube Kanal.

    ## Bitte markiere einen Thread als "Erledigt" wenn deine Frage beantwortet wurde. ##

    Hallo,

    ich möchte auflösen:

    Ich habe den Style der Combobox als Template komplett verändert und XAML hat immer dieses Style her genommen, auch wenn ich explizit als ItemsPanel ein VirtualizingStackpanel verwendet habe im XAML-Designer. Habe jetzt das VirtulazingStackpanel direkt in den Style geschrieben und alles funktioniert.

    Ein weiteres Problem, was ich identifizieren konnte, was nicht oben im Beispiel steht: Ich hatte auf dem Fenster noch eine ListBox, welche die gleiche Anzahl an Items hatte wie die Combobox. Hier habe ich den Template Style direkt von MSDN kopiert und verändert. Jedoch wurde in dem Originaltemplate nur ein StackPanel verwendet statt einem VirtualizingStackPanel wie es eigentlich überall steht. Deswegen bin ich da nicht auf den Fehler gekommen.

    Kurz: Keinerlei Performanceprobleme mehr und alles tut wie es soll. Hattest Recht @Nofear23m mit dem VirtualazingPanel

    Dieser Beitrag wurde bereits 1 mal editiert, zuletzt von „SKeks“ ()