0

I am extending an application I have developed so that it is more broadly useful for multiple jobs, rather than the single job I created it for. There are a number of tables that I get from SQL Server with LINQ to SQL. Instead of having all records from the database populate the application, I want to filter first by job. Currently my viewmodels all have the same construction: a set of private ObservableCollections that get the data through the LINQ to SQL classes, a constructor that sets up binding commands (trying to practice good MVVM), and then the logic. So what I do now is something like this:

partial class MainViewModel : InotifyPropertyChanged
{
    ObservableJobs _oJob = new ObservableJobs(_dataDc);
    public MainViewModel()
    {
        NumRecords.Value = oJob.View.Count;
    }

    public ViewableCollection<Job> oJob
    {
        get { return _oJob; }
    }
    // and then the stuff that the viewmodel takes care of follows
}

public class ViewableCollection<T> : ObservableCollection<T>
{
    private ListCollectionView _View;
    public ListCollectionView View
    {
        get
        {
            if (_View == null)
            {
                _View = new ListCollectionView(this);
            }
            return _View;
        }
    }
}

It strikes me that _oJob is populated before the constructor is run, as the NumRecords.Value is assigned the actual records from the database. Is it better practice to declare outside the constructor and assign inside the constructor, or is it only a matter of timing/ sequencing when things happen? In my next phase I think I need to control the timing of when things get loaded better, so that I minimize the number of records transferred from the SQL Server.

If I try to declare it this way I get an exception, inner exception says "Value cannot be null. Parameter name source".

    ObservableJobs _oJob;// = new ObservableJobs(_dataDc);
    public MainViewModel()
    {
        _oJob = new ObservableJobs(_dataDc);
        NumRecords.Value = oJob.View.Count;
    }

How do I go about controlling how I instantiate the observable collections so that I can set a jobID (or pass one to the constructor along with the datacontext) and filter the querys?

Here is the ObservableJobs class:

class ObservableJobs: ViewableCollection<Job>
{
    public ObservableJobs(DocControlDC dataDc)
    {
        foreach (Job j in dataDc.Jobs)
        {
            this.Add(j);
        }
    }
}
  • 2
    Please don't use "EDIT" monikers in your posts. This isn't a forum. A comprehensive edit history is already available for anyone to view by clicking the "edited n minutes ago" link above this comment. – Robert Harvey Apr 7 '15 at 19:00
1

Why not do DI instead of newing up the object right in that class? That way you don't have to bother about the original problem because it will be initialized for you and then be passed in.

Also it would make it much easier to test your view model.

But to answer your original question. In case you have to initialize inside of your class then I would say:

It is a matter of efficiency.

Here is the rule of thumb that I go by:

If the property being instantiated is going to be repeating in multiple constructors the same way then I just take it out and initialize it on the top. It is easier to see on the top when you are trying to understand the class as well (Or have a private constructor that rest of the overloads call as a part of initialization - this however creates unnecessary amount of duplicated code - having it on the top is just one liner).

If it is going to be initialized differently per constructor then I keep it inside of the constructor, which is self-explanatory.

  • Please see my edits . . . I get an error if I do the assignment in the constructor. Does this problem happen because my ObservableJobs constructor requires a DataContext? ie, does the lone ObservableJobs _oJob; cause the problem? – Paul Gibson Apr 7 '15 at 18:23
  • 2
    I think looking into the DI option has led me to some important realizations. I need to take control of the application startup with an event rather than using the startupUri. Then I can create my viewmodel with the right filters and pass it to the window constructor. I realize that my question is very poorly worded, but only now can I grasp what was actually happening. So thanks for the answer, it definitely helped me to change my perspective. – Paul Gibson Apr 7 '15 at 20:21
  • @PaulGibson sounds a lot more modularized than before. Glad it works properly now! – AvetisG Apr 7 '15 at 20:23

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.