justin peterson
justin peterson

Reputation: 377

Passing Database information from one ViewModel to another using Entity Framework and MVVM

I've got an MVVM application that uses Entity Framework 4.1, WPF and C#. I am trying to get it so that when I double click a row in from a datagrid (the grid binds to an EntitySet in my DataBase named LoanComparisons) in a view I've got called LoanListingView, it switches over to my other view (named LoanCalculatorView) passing the information in my database (EntitySet named Loans) by the information given in the row that was selected.

So far I've already wired the app so double clicking a row in LoanListingView DataGrid opens up LoanCalculatorView that has default values that have been entered into it's fields.

Now for some code. Here is my DataGrid that binds to my database entity set named LoanComparisons:

       <DataGrid MouseDoubleClick="OnDoubleClick"  ItemsSource="{Binding Path=LoanComparisons}" 
                  AutoGenerateColumns="False" SelectionChanged="DataGrid_SelectionChanged">

            <DataGrid.Columns>
                <DataGridTextColumn IsReadOnly="True" Header="Customer Name" Binding="{Binding Path=Name}" />
                <DataGridTextColumn IsReadOnly="True" Header="Home Value" Binding="{Binding Path=HomeValue}" />
                <DataGridTextColumn IsReadOnly="True" Header="Monthly Income" Binding="{Binding Path=MonthlyIncome}" />
                <DataGridTextColumn IsReadOnly="True" Header="First Payment" Binding="{Binding Path=FirstPaymentDate}" />
            </DataGrid.Columns>
        </DataGrid>

Double clicking any row opens up my LoanCalculatorView with pre-set values. Currently the DoubleClick event runs this code:

      /// Handles double-clicks on datagrid rows
    private void OnDoubleClick(object sender, MouseButtonEventArgs e)
    {
        if (sender != null)
        {
            DataGrid grid = sender as DataGrid;
            if (grid != null && grid.SelectedItems != null && grid.SelectedItems.Count == 1)
            {
                DataGridRow dgr = grid.ItemContainerGenerator.ContainerFromItem(grid.SelectedItem) as DataGridRow;
              _viewModel.Open(null);


              //The DataContext will be set to dgr but since "DataGridRow"
              //does not contain the Open method I cant do this:
              //  DataContext = dgr;
              //dgr.Open(dgr);
              //
              //I think this is where I am lost at

            }
        }
    }

Currently, the Open method passes a null value into it's method because I'm not sure how to pass the information from my other EntitySet named "Loans". The open method is as follows:

//Creates a new LoanCalculatorViewModel that calls the SetComparisonDataRecord method
//passing it an argument comparison and changes the DataContext to LoanCalculatorView.
  public void Open(LoanComparison comparison)
  {
     var loanCalculatorViewModel = new LoanCalculatorViewModel();

     loanCalculatorViewModel.SetComparisonDataRecord(comparison);

     var loanCalculatorView = new LoanCalculatorView {DataContext = loanCalculatorViewModel};

     loanCalculatorView.Show();
  }

Finally, the SetComparisonDataRecord right now simply is empty but I put a comment of what should be in there and how I want to set the values:

      public void SetComparisonDataRecord(LoanComparison comparison)
  {


     //SharedValues.HomeValue = comparison.HomeValue;

  }

One other thing to keep in mind, my two EntitySets have a one-to-many relationship. One loan and a collection of LoanComparisons. Is it possible to show me how to pass the information from the selected row (representing an Entity from my LoanComparisons EntitySet) to the LoanCalculatorView?

Upvotes: 2

Views: 579

Answers (2)

justin peterson
justin peterson

Reputation: 377

Changed my OnDoubleClick Method like so, where the DataContext gets set in the Open method:

 private void OnDoubleClick(object sender, MouseButtonEventArgs e)
    {
        if (sender != null)
        {
            DataGrid grid = sender as DataGrid;
            if (grid != null && grid.SelectedItems != null && grid.SelectedItems.Count == 1)
            {           
                var lc = grid.SelectedItem as LoanComparison;
                if (lc != null) _viewModel.Open(lc);

            }
        }
    }

simple open method:

public void Open(LoanComparison comparison)
  {
     var loanCalculatorViewModel = new LoanCalculatorViewModel();

     loanCalculatorViewModel.SetComparisonDataRecord(comparison);

     var loanCalculatorView = new LoanCalculatorView {DataContext = loanCalculatorViewModel};

     loanCalculatorView.Show();
  }

From there I wrote a basic query asking my database for the "loan" entity:

public void SetComparisonDataRecord(LoanComparison comparison)
           {

     var calcEntities = new LoanCalcEntities();

     var currentLoan = from loan in calcEntities.Loans
                       where loan.LoanId == comparison.CurrentLoanId
                       select loan;


     var proposedLoan = from loan in calcEntities.Loans
                       where loan.LoanId == comparison.ProposedLoanId
                       select loan;

     //SharedValues.HomeValue = comparison.HomeValue;

  }

Sorry for the trouble! Thanks for the help :)

Upvotes: 0

Xcalibur37
Xcalibur37

Reputation: 2323

One suggestion to avoid headaches, is to bind a property to the SelectedItem property of the datagrid so that you do not need to worry about the "current selection" when firing the Double-Click event.

For what you are doing, I would break down the calls as such:

  1. Perform the first call to EF for the initial grid-view so that the list can be populated.
  2. Assuming that each item has an Id because of primary keys, or some unique identifier, pass only that value as the parameter for your popup-window.
  3. During the loading of your viewmodel during the init of your popup window load, make the call to entity for the record with ID "passed id" using LINQ.
  4. Take the returned Entity POCO, store it in a property in your viewmodel and access it in your view.
  5. Note: Make sure you are using INotifyPropertyChanged on all your viewmodel properties so that the view refreshes properly.

Is that essentially what you are looking for?

Upvotes: 0

Related Questions