none
WPF MVVM Salvare in diverse taballe in base a un combobox RRS feed

  • Domanda

  • ciao a tutti,

    non sono riuscito a trovare una soluzione idonea al mio obbiettivo finale.

    sono in una scenario mvvm.

    Ho una finestra(quella per inserimento di fatture per capirci)  in questa finestra c'è un combobox, dove posso scegliere i tipi di fattura(fattura immediata, fattura differita,documento di trasporto,preventivo,buono di consegna etc...) 

    e avro nel db le rispettive tabelle(testata e corpo).

    Ora io in base alla scelta devo poter salvare i dati nelle relative tabelle. Non sono riuscito ad implementarlo nella mia soluzione wpf mvvm entity framework code first.

    =( e da qualche mese ma senza nessun risultato. Io per adesso per ovviare a questo problema ho utilizzato automapper cioè prima del salvtaggio mi mappavo la tabella.

    Ho messo il link di un video di quello che vorrei replicare su wpf.

    video

    spero in qualche aiuto.

    venerdì 20 giugno 2014 00:06

Tutte le risposte

  • Ciao,

    senza vedere il codice in questo caso non credo si riesca ad aiutarti.

    venerdì 20 giugno 2014 13:17
    Postatore
  • Se ho 3 soggetti Documenta -> DetailDocumentA, DocumentB -> DetailDocumentB, DocumentC -> DetailDocumentC, relazione uno a molti. (Hanno tutti le stesse proprietà, tutti ereditano da DocumentGeneric-> DetailDocumentGeneric). 
    Nella mia view ho dei textbox (DocumentGeneric) e un datagrid (DetailDocumentGeneric), e un combobox (da qui se scelgo DocumentA, DocumentB, DocumentC). 

    Io a seconda della scelta del mio combobox vorrei può salvare ciò che scrivo nella view (DocumentGeneric-> DocumentDetailGeneric) nella tabella corrispondente.

    My Window:

    Window x:Class="Invoice_Example_Brux.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:invoiceExampleBrux="clr-namespace:Invoice_Example_Brux"
        Title="MainWindow" Height="350" Width="525">
    <Window.DataContext>
        <invoiceExampleBrux:MainWindowViewModel/>
    </Window.DataContext>
    <Grid>
        <TextBox HorizontalAlignment="Left" Height="23" Margin="174,78,0,0" TextWrapping="Wrap" Text="{Binding MyModel.Name}" VerticalAlignment="Top" Width="120"/>
        <Label Content="Id" HorizontalAlignment="Left" Margin="10,53,0,0" VerticalAlignment="Top"/>
        <TextBox HorizontalAlignment="Left" Height="23" Margin="10,78,0,0" TextWrapping="Wrap" Text="{Binding MyModel.Id}" VerticalAlignment="Top" Width="120"  IsReadOnly="True"/>
        <Label Content="Number" HorizontalAlignment="Left" Margin="322,52,0,0" VerticalAlignment="Top"/>
        <TextBox HorizontalAlignment="Left" Height="23" Margin="322,78,0,0" TextWrapping="Wrap" Text="{Binding MyModel.Number}" VerticalAlignment="Top" Width="120"/>
        <Label Content="Name" HorizontalAlignment="Left" Margin="174,53,0,0" VerticalAlignment="Top"/>
        <Button Content="Save" HorizontalAlignment="Left" Margin="211,288,0,0" VerticalAlignment="Top" Width="75" Command="{Binding SaveCommand}"/>
        <ComboBox
            SelectionChanged="Selector_OnSelectionChanged"
                  HorizontalAlignment="Left" Margin="180,38,0,0" VerticalAlignment="Top" Width="120"                  
                  DisplayMemberPath="Name"
                  ItemsSource="{Binding DocumentType,UpdateSourceTrigger=PropertyChanged}"/>
        <Label Content="Type Document" HorizontalAlignment="Left" Margin="192,12,0,0" VerticalAlignment="Top"/>
    </Grid>

    myWindows codebheind:

     namespace Invoice_Example_Brux
    {
    
        public partial class MainWindow
        {
            public MainWindow()
            {
                InitializeComponent();
            }
    
            private void Selector_OnSelectionChanged(object sender, SelectionChangedEventArgs e)
            {
                var cmb  = sender as ComboBox;
                var selectedItem = cmb.SelectedValue as DocumentType;
                if (selectedItem == null) return;
                var code = selectedItem.Code;
                switch (code)
                {
                    case "A":
                        DataContext = new ViewModelGeneric<DocumentA>();
                        break;
                    case "B":
                        DataContext = new ViewModelGeneric<DocumentB>();
               break;
                    case "C":
                        break;
                }
            }
        }
    }


    My Entity DocumentA and DocumentB:

    public class DocumentA : DocumentGeneral
        {
            public ObservableCollection<DetailDocumentA> DetailDocumentA { get; set; }
    
        }
       public class DetailDocumentA : DetailDocumentGeneral
        {
        }
    
      public class DocumentB : DocumentGeneral
        {
            public ObservableCollection<DetailDocumentB> DetailDocumentB { get; set; }
    
        }
       public class DetailDocumentB : DetailDocumentGeneral
        {
        }
    
        public class DocumentGeneral 
        {
            public Guid Id { get; set; }
            public string Name { get; set; }
            public string Number { get; set; }
            public string TypeDocument { get; set; }
    
        }
       public class DetailDocumentGeneral
        {
            public Guid Id { get; set; }
            public string Quantity { get; set; }
            public string Price { get; set; }
            public string Total { get; set; }
        }


    My ViewModelGeneric:

    public class ViewModelGeneric<T> : ViewModelBase
            where T : DocumentGeneral, new()
        {
            public T MyModel { get; set; }
            public RelayCommand SaveCommand { get; set; }
            public ViewModelGeneric()
            {
                MyModel = new T();
                SaveCommand = new RelayCommand(Save);
            }
    
            private void Save(object obj)
            {
                if (MyModel.Id == Guid.Empty)
                {
                    MyModel.Id = Guid.NewGuid();
                }
    //the problme is here. how can I do to fill in the detail of my entity
              /*  MyModel.Detail.Add(new DetailDocumentGeneral
               {
                   Price = "50",Quantity = "100",Total = "5000"
               });*/
    
                using (var ctx = new DocumentContext())
                {
                    var document = ctx.Set<T>();
                    document.Add(MyModel);
                    ctx.SaveChanges();
                }
            }
        }

    Questo è l'esempio:
    InvoiceExample

    IO ho bypassato questo ostacolo utilizzando automapper:

     if (comboboxValue == "A")
                {
                    var newTestata = Mapper.Map<DocumentGeneric, DocumentA>(MyModel);
                    documentARepository.Aggiungi(newTestata);
                }else 
       if (comboboxValue == "B")
                {
                    var newTestata = Mapper.Map<DocumentGeneric, DocumentB>(MyModel);
                    documentBRepository.Aggiungi(newTestata);
                }

    Però nn è la solzione adatta. C'è qualcosa che mi sfugge. 

    Dovrei semplicemente aver la possibilita in base a quello che scelgo da un combobox  di salvare in diverse tabelle del db, quello che scrivo nella view.


    venerdì 20 giugno 2014 13:27
  • Da quello che mi pare di capire a primo impatto (non ho letto il codice del link), sembrerebbe che tu tenti di aggiungere una classe base alla derivata, invece dovresti fare un cast al tipo di dettaglio specifico. Come potrai notare con l'ultimo tuo spezzone di codice, il tipo di dettaglio sottostante è ben specificato :

    Mapper.Map<DocumentGeneric, DocumentA>

    Dovresti fare altrettanto, oppure usare switch o reflection. 

    Per capirci non puoi usare :

    new DetailDocumentGeneral
    ma potrà essere new T2() o comunque del tipo corretto costruito con reflection.

    venerdì 20 giugno 2014 14:29
    Postatore