1

I am building a Windows desktop application using WPF and C#. I am trying to use the MVVM model but am not able to get my head around with the model and the INotifyPropertyChanged and INotifyCollectionChanged interfaces.

I am detailing below structure of my model, have simplified it to put my question across. One class model. I am getting trades from an external system and inserting them in the database. Once I inserted them in the database, I would like the page showing the trades getting updated with the new trades.

Where and how should I implement the INotifyPropertyChanged and INotifyCollectionChanged interfaces? My model looks something like Page-->View-->ViewModel<--Model.

If this is not clear then I can provide more information.

// ---Model--
public class Trade
{
  private decimal tradeid;
  private decimal securityid;

  public Trade () {}

  // <<public get-set properties for the above 2 items>>
}

// ---ViewModel--

public class TradeVM
{       
  private ObservableCollection<Trade> _tradeList;

  public ObservableCollection<Trades> TradeList
  {
     get
     {
         //getting all rows from database
        _tradeList = new ObservableCollection<TradesDB>(GetAllRows<Trades>(typeof(Trades)).ToList());
     }
     set
     {
         _tradeList = value;
     }
  }

  public TradesVM() {}    
}

// ---View---

public class TradeView
{
  private TradeVM _tradeVM;

  public TradeView()
  {
    _tradeVM = new TradeVM;
  }    

  public void GetTradesFromExternalSystem()
  {
    //call the webservice of externsal system and get the trades and insert them in the database.

  }

  public Ilist<Trade> GetTradesFromDatabase()
  {
     return _tradeVM.TradeList.ToList();    
  }    
}

// ---Page Class displaying Trades to user---

public partial class TradeData : Page
{
    private TradeView _tradeView;

    public TradeData()
    {
        InitializeComponent();
        _tradeView = new TradeView();
        //datagrid datacontext assignment
        this.dgTrades.Datacontext = _tradeView.GetTradesFromDatabase().ToList();    
  }

  private void cmdGetTrades_Click(object sender, RoutedEventArgs e)
  {
      _tradeView.GetTradesFromExternalSystem();
  }   
}

// ---Page---
// --just putting the datagrid population line. rest all is default
<igDP:XamDataGrid Name="dgTrades" ScrollViewer.HorizontalScrollBarVisibility="Auto" ScrollViewer.VerticalScrollBarVisibility="Auto" DataSource="{Binding}" MaxHeight="800"></igDP>
dymanoid
  • 13,597
  • 3
  • 34
  • 59
pat
  • 11
  • 3
  • You don't need to imlement INotifyCollectionChanged. That is already done by the ObservableCollection class. You should however not return a new ObservableCollection instance from a property getter. Return the existing instance, and add some method that fills it with items, outside the getter. If you really want to return a new collection from each call of the getter, don't use ObservableCollection. It's useless then. – Clemens Nov 30 '18 at 15:06
  • Additional to @Clemens comment you will need to bind to your `OberservableCollection` - you are currently calling `.ToList()` on your `OberservableCollection` which kills the `Observable` ability since a simple `List` which your are getting by calling `.ToList()` doesn't have that ability. Also you shouldn't set the `DataContext` of your `DataGrid` but instead set the `DataContext` of your `View` to your `ViewModel` and have a property in your `ViewModel` which gets bound to your `DataGrid` – Rand Random Nov 30 '18 at 15:09
  • @pat, if you're seeing any errors from your code, kindly post those as well. – MAbraham1 Nov 30 '18 at 15:15
  • Thank you for quick responses @Clements - When I was looking at help online this was the method used to create an observable collection form List. I guess there was one more where you loop through and add each item from the list to the observable collection. Is that the one you are referring to? – pat Nov 30 '18 at 15:24
  • @Rand - Can you help with some code snippet? If I should not use ToList() then how would I set the DataContect. using a property in Page Class? I am not sure I understood your point setting the datacontext of the view to viewmodel. But both are class objects? not sure how to implement your suggestion. Thanks again – pat Nov 30 '18 at 15:24
  • @MAbraham1 - no error. The update to the trades is not getting reflected on the datagrid automatically. – pat Nov 30 '18 at 15:26
  • It's good that you are learning the foundation of MVVM, but you'd probably want to look into one of the popular MVVM frameworks out there as there is a lot more to doing MVVM the right way then just INPC and INCC. There's other moving parts like dependency injection, event to command mapping, etc. – SledgeHammer Nov 30 '18 at 19:59
  • @SledgeHammer - Thank you for your response. wow those sound great but I am not a good technical person so not sure whether I could grasp the concepts. I will look at it though. Currently I am waiting for someone to provide me small code snippets or point me in the right direction of how to set the viewmodel as the datacontext for the view. also am I using too many layers than required. my layers are Page-->View-->ViewModel-->Model – pat Nov 30 '18 at 20:22
  • 1
    @pat Not to scare you off, but there is definitely a VERY steep learning curve to MVVM & WPF. You can write WPF apps without using it, but you're going down a rabbit hole that way. Especially for larger apps. If you use a good MVVM framework, all the stuff you are trying to figure out is done for you "magically" :). Without a framework you're going to be scratching your head about a lot of things once you get into it, like how VMs talk to each other, etc. – SledgeHammer Nov 30 '18 at 20:35
  • 1
    @pat - one of the more popular ones that's still maintained is MvvmLight http://www.mvvmlight.net/#documentation... they've got Visual Studio templates to get you up and running in no time. – SledgeHammer Nov 30 '18 at 20:37
  • @SledgeHammer - Thanks. I will download and look at it. – pat Nov 30 '18 at 21:23

0 Answers0