DataGrid mit Combobox Items von fremder Tabelle

  • WPF

Es gibt 2 Antworten in diesem Thema. Der letzte Beitrag () ist von shadow01.

    DataGrid mit Combobox Items von fremder Tabelle

    Hallo Zusammen

    Ich habe ein neues Problem:
    Ich habe ein DataGrid in dem ich Angaben zu einer Wohnung, Haus speichern möchte. Nun will ich noch eine Combobox im DataGrid das von der tb_contact geladen werden soll und die ID des Contacts soll in die tb_subobject gespeichert werden. Wie muss ich die Combobox laden / einbinden um die Werte der tb_contact auswählen zu können?
    Ein zweites Problem habe ich nun wenn ich eine neue Zeile ausfüllen will, dann erscheint die Fehlermeldung: "Dynamic SQL generation is not supported against multiple base tables." Mir ist klar was die Bedeutung der Meldung heisst, jedoch die Lösung nicht. Muss ich die Tabellen mit Join verbinden? Eigentlich möchte ich ja nur in die tb_subObject speichern, die anderen Tabellen sind nur für die Detailanzeige (RowDetailsTemplate) vorhanden. Leider finde ich keinen Lösungsansatz, ausser von ausserhalb des GataGrids via TextBoxen zu füllen dann bäuchte ich den Speicherbefehl nicht mehr. Das soll aber nicht die Lösung sein.


    XML-Quellcode

    1. <DataGrid Grid.Row="1" ItemsSource="{Binding}" Name="dgvSubObject" BeginningEdit="dgvSubObject_BeginningEdit" RowEditEnding="dgvSubObject_RowEditEnding" AutoGenerateColumns="False" AutoGeneratingColumn="dgvSubObject_AutoGeneratingColumn" HeadersVisibility="Column" >
    2. <DataGrid.ContextMenu>
    3. <ContextMenu>
    4. <MenuItem Header="click me" />
    5. </ContextMenu>
    6. </DataGrid.ContextMenu>
    7. <DataGrid.RowDetailsTemplate>
    8. <DataTemplate>
    9. <DockPanel Background="GhostWhite">
    10. <Grid Margin="0,10">
    11. <Grid.ColumnDefinitions>
    12. <ColumnDefinition Width="Auto" />
    13. <ColumnDefinition Width="*" />
    14. </Grid.ColumnDefinitions>
    15. <Grid.RowDefinitions>
    16. <RowDefinition Height="Auto" />
    17. <RowDefinition Height="Auto" />
    18. <RowDefinition Height="Auto" />
    19. </Grid.RowDefinitions>
    20. <TextBlock Text="Mieter: " FontWeight="Bold" />
    21. <TextBlock Text="{Binding Mieter}" Grid.Column="1" />
    22. <TextBlock Text="Telefon: " FontWeight="Bold" Grid.Row="1" />
    23. <TextBlock Text="{Binding tel}" Grid.Column="1" Grid.Row="1" />
    24. <TextBlock Text="E-Mail: " FontWeight="Bold" Grid.Row="2" />
    25. <TextBlock Text="{Binding email}" Grid.Column="1" Grid.Row="2" />
    26. </Grid>
    27. </DockPanel>
    28. </DataTemplate>
    29. </DataGrid.RowDetailsTemplate>
    30. <DataGrid.AlternatingRowBackground>
    31. <LinearGradientBrush EndPoint="0.5,1" StartPoint="0.5,0">
    32. <GradientStop Color="Black" Offset="0"/>
    33. <GradientStop Color="White" Offset="1"/>
    34. <GradientStop Color="#FFD2D2D2" Offset="0.267"/>
    35. </LinearGradientBrush>
    36. </DataGrid.AlternatingRowBackground>
    37. <DataGrid.ColumnHeaderStyle>
    38. <Style/>
    39. </DataGrid.ColumnHeaderStyle>
    40. <DataGrid.Columns>
    41. <DataGridTextColumn Header="AuftragsNr" Binding="{Binding OrderNr}"/>
    42. <DataGridTextColumn Header="Stockwerk" Binding="{Binding Floor}"/>
    43. <DataGridTextColumn Header="WhgNr" Binding="{Binding WhgNr}"/>
    44. <DataGridTextColumn Header="Bez" Binding="{Binding Bez}"/>
    45. <DataGridTextColumn Header="Raum" Binding="{Binding Raum}"/>
    46. <DataGridTextColumn Header="Beschreibung" Binding="{Binding Beschreibung}"/>
    47. <DataGridComboBoxColumn DisplayMemberPath="Street" Header="Strasse" SelectedItemBinding="{Binding Mieter}">
    48. <DataGridComboBoxColumn.ElementStyle>
    49. <Style TargetType="{x:Type ComboBox}">
    50. <Setter Property="ItemsSource" Value="{Binding Mieter}"/>
    51. </Style>
    52. </DataGridComboBoxColumn.ElementStyle>
    53. <DataGridComboBoxColumn.EditingElementStyle>
    54. <Style TargetType="{x:Type ComboBox}">
    55. <Setter Property="ItemsSource" Value="{Binding Mieter}" />
    56. </Style>
    57. </DataGridComboBoxColumn.EditingElementStyle>
    58. </DataGridComboBoxColumn>
    59. </DataGrid.Columns>
    60. </DataGrid>


    C#-Quellcode

    1. private void fillDgvSubObject()
    2. {
    3. myConn.Open();
    4. myDataAdapter = new MySqlDataAdapter { SelectCommand = new MySqlCommand() { Connection = myConn, CommandText = "SELECT tb_subObject.ID, OrderNr, Floor, WhgNr, Bez, Raum, CONCAT(PreName, ' ', Name)as Mieter, Beschreibung, tel, email FROM tb_subobject, tb_prename, tb_name, tb_contact WHERE OrderNr=" + AuftragID + " AND " +
    5. "tb_subobject.ID_ContactMieter=tb_contact.ID AND tb_contact.ID_PreName=tb_prename.ID AND tb_contact.ID_Name=tb_name.ID"
    6. } };
    7. myDataSet = new DataSet();
    8. myDataAdapter.Fill(myDataSet, "subobject");
    9. dgvSubObject.DataContext = myDataSet.Tables["subobject"].DefaultView;
    10. }
    11. private void dgvSubObject_BeginningEdit(object sender, DataGridBeginningEditEventArgs e)
    12. {
    13. myBuilder = new MySqlCommandBuilder(myDataAdapter);
    14. DataRowView myDRV = (DataRowView)dgvSubObject.SelectedItem;
    15. myDRV.BeginEdit();
    16. }
    17. private void dgvSubObject_RowEditEnding(object sender, DataGridRowEditEndingEventArgs e)
    18. {
    19. DataRowView myDRV = (DataRowView)dgvSubObject.SelectedItem;
    20. myDRV.EndEdit();
    21. myDataAdapter.UpdateCommand = myBuilder.GetUpdateCommand();
    22. myDataAdapter.Update(myDataSet, "subobject");
    23. }
    24. private void dgvSubObject_AutoGeneratingColumn(object sender, DataGridAutoGeneratingColumnEventArgs e)
    25. {
    26. var tc = e.Column as System.Windows.Controls.DataGridTextColumn;
    27. var b = tc.Binding as System.Windows.Data.Binding;
    28. b.UpdateSourceTrigger = UpdateSourceTrigger.PropertyChanged;
    29. b.ValidatesOnDataErrors = true;
    30. b.NotifyOnValidationError = true;
    31. }


    Gruss und Danke

    shadow01 schrieb:

    Wie muss ich die Combobox laden / einbinden um die Werte der tb_contact auswählen zu können?
    Du bindest da nicht an einen EF-Context, sondern an ein (un)good old DataView.
    Da darfst du glaub nicht mit SelectedItemBinding herumfummeln, sondern musst iwas mit SelectedValueBinding oder SelectedValueMemberPath oder sowas bemühen.
    Genau kann ichs nicht sagen, nur dass eine Dataview-gebundene DG-ComboColumn in Wpf zum Kotzen ist, wegen der 2^10 verschiedenen Möglichkeiten, die Bindingerei zu vermurksen, und Intellisense bietet nix an.

    Zur anderen Frage müsstest du mal die Methode zeigen, und die Fehlerzeile.

    Ah - glaub ich sehs.
    probierma so:

    C#-Quellcode

    1. private MySqlCommandBuilder myBuilder;
    2. private void fillDgvSubObject() {
    3. myConn.Open();
    4. myDataAdapter = new MySqlDataAdapter {
    5. SelectCommand = new MySqlCommand() {
    6. Connection = myConn, CommandText = "SELECT tb_subObject.ID, OrderNr, Floor, WhgNr, Bez, Raum, CONCAT(PreName, ' ', Name)as Mieter, Beschreibung, tel, email FROM tb_subobject, tb_prename, tb_name, tb_contact WHERE OrderNr=" + AuftragID + " AND " +
    7. "tb_subobject.ID_ContactMieter=tb_contact.ID AND tb_contact.ID_PreName=tb_prename.ID AND tb_contact.ID_Name=tb_name.ID"
    8. }
    9. };
    10. myBuilder = new MySqlCommandBuilder(myDataAdapter);
    11. myDataSet = new DataSet();
    12. myDataAdapter.Fill(myDataSet, "subobject");
    13. dgvSubObject.DataContext = myDataSet.Tables["subobject"].DefaultView;
    14. }
    15. private void dgvSubObject_BeginningEdit(object sender, DataGridBeginningEditEventArgs e) {
    16. DataRowView myDRV = (DataRowView)dgvSubObject.SelectedItem;
    17. myDRV.BeginEdit();
    18. }
    19. private void dgvSubObject_RowEditEnding(object sender, DataGridRowEditEndingEventArgs e) {
    20. DataRowView myDRV = (DataRowView)dgvSubObject.SelectedItem;
    21. myDRV.EndEdit();
    22. myDataAdapter.Update(myDataSet, "subobject");
    23. }
    Also der CommandBuilder wird nur einmal, initial erstellt, und damit ist der Adapter automatisch auch mit geeeigneten UpdateCommands initialiseirt.
    Im weiteren Builder und Adapter nicht mehr manipulieren!!

    Nein, das geht garnet.
    Dein Sql-Statement ist zu komplex, als dass ein CommadnBuilder da Insert-/Delete-/Update-Command draus ableiten könnte.
    Derlei Ableitungen sind nur möglich, wenn nur eine Tabelle selectiert wird - aber bei dir werden ja Werte aus mehreren Tabellen zu einer View zusammengemischt - dass kann ein CommandBuilder nicht mehr auseinanderklamüsern - welche spalte da in welche Db-Tabelle geschrieben werden soll.

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