Entity Framework - Detail-View Problem

  • WPF

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

    Entity Framework - Detail-View Problem

    Nabend,

    Habe gerade ein Problem mit einer klassischen Detail-View Ansicht im Entity Framework und WPF ich habe mir das Tutorial von ErfinderdesRades angesehen: die vier Views (in Wpf) aber irgendwie funktioniert bei mir zwar das Tutorial aber die DBSets zicken rum

    zum Probieren habe ich mir eine einfache Form geholt Links mit einer Listview und rechts einem Border mit nur einem Textfeld zum testen.

    Hier das XAML:

    XML-Quellcode

    1. <Window x:Class="dia_test"
    2. xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    3. xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    4. xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
    5. xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
    6. xmlns:local="clr-namespace:HHHB"
    7. mc:Ignorable="d"
    8. Title="dia_test" Height="300" Width="300" d:DataContext="{d:DesignInstance {x:Type local:folder_v01}}">
    9. <Grid>
    10. <Grid.RowDefinitions>
    11. <RowDefinition Height="39*"/>
    12. <RowDefinition Height="230*"/>
    13. </Grid.RowDefinitions>
    14. <Grid.ColumnDefinitions>
    15. <ColumnDefinition/>
    16. <ColumnDefinition/>
    17. </Grid.ColumnDefinitions>
    18. <ListBox x:Name="listBox" Grid.Column="0" Grid.RowSpan="2">
    19. <ListBox.ItemTemplate>
    20. <DataTemplate>
    21. <WrapPanel>
    22. <TextBlock Text="{Binding bezeichnung}"/>
    23. </WrapPanel>
    24. </DataTemplate>
    25. </ListBox.ItemTemplate>
    26. </ListBox>
    27. <Border x:Name="test_border" DataContext="{Binding _folders}" BorderBrush="Black" BorderThickness="1" Grid.Column="1" HorizontalAlignment="Left" Height="100" Margin="36,25.898,0,0" VerticalAlignment="Top" Width="100" Grid.Row="1">
    28. <TextBox x:Name="textBox" TextWrapping="Wrap" Text="{Binding bezeichnung}"/>
    29. </Border>
    30. </Grid>
    31. </Window>


    hier der Code behind:

    VB.NET-Quellcode

    1. Imports System.Data.Entity
    2. Public Class dia_test
    3. Dim db As New template_dbEntities
    4. Public _folders As DbSet(Of folder_v01) = db.folder_v01
    5. Public Sub New()
    6. ' This call is required by the designer.
    7. InitializeComponent()
    8. ' Add any initialization after the InitializeComponent() call.
    9. _folders.Load
    10. Me.DataContext = _folders
    11. listBox.ItemsSource = _folders.ToList
    12. listBox.IsSynchronizedWithCurrentItem = True
    13. test_border.DataContext = _folders.ToList
    14. End Sub
    15. End Class


    Habe jetzt folgendes Problem die Elemente werden in der Listview angezeigt klicke ich auf ein Element ändert sich nichts.
    Ändere ich "test_border.DataContext = _folders" dann wird er mit einen Fehler auf:
    Data binding directly to a store query (DbSet, DbQuery, DbSqlQuery, DbRawSqlQuery) is not supported.


    Ich vermute das der Border einfach keine Info über die Klickänderung im Listview bekommt binde ich das Element an die .selecteditem Property der Listview klappt es....

    Kann mir hier jemand helfen?
    Danke!
    mfG.
    Stephan
    ist immer problematisch, wenn ohne MVVM geproggt wird.

    Eiglich kann man das komplett ohne CodeBehind machen, und dann funzt das auch.

    ah, jezt seh ich was: glaub #17 muss gelöscht wern.

    aber wie gesagt: wenn man systematisch nach MVVM aufbaut, hat man ein System, und funkti nicht ein anderes dazwischen.

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

    Ok gut ich hab mir jetzt nochmal das Beispiel PersonList vorgenommen und dein MainModel auf meine Zwecke hin angepasst:

    VB.NET-Quellcode

    1. Imports System.Collections.ObjectModel
    2. Imports System.Data.Entity
    3. Public Class all_trans_stati
    4. Private WithEvents _allstati As New ObservableCollection(Of trans_status_v01)()
    5. Public Property _allstati_list() As New ListCollectionView(_allstati)
    6. Dim db As New template_dbEntities
    7. Sub New()
    8. load()
    9. End Sub
    10. Sub load()
    11. ''_allstati.Clear()
    12. Dim v_temp As DbSet(Of trans_status_v01) = db.trans_status_v01
    13. v_temp.Load
    14. _allstati = v_temp.Local
    15. _allstati_list.MoveCurrentToFirst()
    16. End Sub
    17. Private Sub stati_col_changed(sender As Object, e As Specialized.NotifyCollectionChangedEventArgs) Handles _allstati.CollectionChanged
    18. If e.Action <> Specialized.NotifyCollectionChangedAction.Remove Then Return
    19. If Not _allstati_list.MoveCurrentToNext Then _allstati_list.MoveCurrentToPrevious()
    20. End Sub
    21. End Class


    Leider synchronisiert sich meine _allstati Collection nicht mit der _allstati_list so wie es in deinem Beispiel passiert damit bleibt der Item Count 0 und es wird nichts angezeig irgendwie ist es mir auch nicht ganz einleuchtend wo das MainModel in dem Beispiel aufgerufen wird ich muss derzeit meine Klasse im New Event der Form platzieren?
    mfG.
    Stephan
    ja, das ist das Lausige mittm EF, dass da immer neue ObservableCollections generiert werden. Wirkung davon ist, dass nach jedem Laden natürlich alle Bindings beim Deibel sind.
    Sie sind natürlich nicht beim Deibel, sondern sind bei der vorherigen ObservableCollection.

    also genau genommen sind sie bei der _allstati_list, der CollectionView.
    Und die weiß nun natürlich nix davon, dass die _allstati-ObservableCollection neu erstellt wurden. Die Datasource der _allstati_list ist nachwievor die _allstati, die's ganz am Anfang war, und deswegen wird auch keine Änderung angezeigt, denn für die _allstati_list hat sich ja nix geändert.

    evtl nochma EntityFramework-CodeFirst-Sample ganz genau gugge, wie ich da das Problem gelöst habe.
    Deine Erklärung verstehe ich, ich hab ein bisschen rumgesucht die C#ler haben da teilweise die Möglichkeit das PropertyChanged defacto von Hand zu feuern was aber ja irgendwie auch nicht Sinn der Sache sein kann.
    Ich hab das mir jetzt mal im Detail angeschaut mit deinem CodeFirst Sample aber offen gesagt ich checks nicht.

    In deinem Beispiel hast die die Klasse MainViewModel die eine Property z.b. Category() as ObservableCollection(of Category) beinhaltet. In der Klasse Category ist eine weitere OC _Article bzw. eine Property Article() damit wird die 1:n Verknüpfung abgebildet das leuchtet ein.

    Im Sub New holst du dir die Daten aus der Datenbank über die _context.Category.local die füllt damit deine Collections im Usercontrol ist die Binding so eingestellt das das Datagrid einmal die Category holt und einmal das Datagrid die Category/Article alles Logo bringt mich aber nur bedingt weiter weil es irgendwie noch immer nicht erklärt wie ich meine NotifyPropertyChanged hinbekomme...

    ------------------------------
    Aber ich habs hinbekommen ich habe jetzt nochmal den Code angesehen und bin darauf gekommen das ich ja eigentlich keine ListCollectionView benötige ich hab die ObservableCollection jetzt direkt an die Listview gebunden den Datacontext des Borders gesetzt und siehe da es funktioniert....

    Danke für eure Hilfe.
    mfG.
    Stephan