1

I'm new to WPF + MVVM and have been having trouble getting around viewmodels.

I have a object called FSystem which contains a alot of lists which are populated from a XML.

public class FSystem : ObservableObject
{
    public List<FUser> _userList;
    public List<FZone> _zoneList;
    public List<FSource> _sourceList;

    public string _projectName { get; set; }
    private string _projectVersion { get; set; }
    private string _processorIp { get; set; }

    private bool _isMultiLingualModeOn { get; set; }

    private int _systemIncludeLighting { get; set; }
    private int _systemIncludeWindowsTreatments { get; set; }
    private int _systemIncludeSip { get; set; }
    private int _systemIncludeCamaras { get; set; }

    public FSystem()
    {
        UserList = new List<FUser>();
    }
}

This is the XMLParser which is called when the user loads the XML to the application.

public static class XMLParsers
{
    public static FSystem ParseByXDocument(string xmlPath)
    {
        var fSystem = new FSystem();

        XDocument doc = XDocument.Load(xmlPath);

        XElement fSystemElement = doc.Element("FSystem");

        if (fSystemElement != null)
        {
            fSystem.ProjectName = fSystemElement.Element("ProjectName").Value;
            fSystem.ProjectVersion = fSystemElement.Element("ProjectVersion").Value;
            fSystem.ProcessorIp = fSystemElement.Element("ProcessorIP").Value;
            fSystem.ProcessorFilePath = fSystemElement.Element("ProcessorFilePath").Value;
            fSystem.SystemIncludeLighting = Convert.ToInt16(fSystemElement.Element("SystemIncludeLighting").Value);
            fSystem.SystemIncludeSip = Convert.ToInt16(fSystemElement.Element("SystemIncludeLighting").Value);
            fSystem.SystemIncludeCamaras = Convert.ToInt16(fSystemElement.Element("SystemIncludeCameras").Value);
        }

        fSystem.UserList = (from user in doc.Descendants("FUser")
                                 select new FUser()
                                 {
                                     Id = user.Element("Id").Value,
                                     Name = user.Element("Name").Value,
                                     Icon = user.Element("IconColour").Value,
                                     Pin = user.Element("UserPin").Value,
                                     IsPinEnabled = Convert.ToBoolean(Convert.ToInt16(user.Element("UserPinEnabled").Value)),
                                     ListIndex = user.Element("ListIndex").Value
                                 }).ToList();

        return fSystem;
    }
}

And this is the MainViewModel below is what contains the Commands which Load the XML and the property FSystem I wish to use in other view models.

public class MainViewModel : ViewModel 
{
    private Fystem fSystem;
    public FSystem FSystem
    {
        get { return fSystem; }
        private set
        {
            fSystem = value;
            NotifyPropertyChanged("FSystem");
        }
    }

    public MainViewModel()
    {
        InitiateState();
        WireCommands();
    }

    private void InitiateState()
    {
        FSystem = new FSystem();
    }

    private void WireCommands()
    {
        XDocumentLoadCommand = new RelayCommand(XDocumentLoad) {IsEnabled = true};

        ClearDataCommand = new RelayCommand(ClearData) {IsEnabled = true};
    }
public RelayCommand XDocumentLoadCommand { get; private set; }
    private void XDocumentLoad()
    {
        var openDlg = new OpenFileDialog
        {
            Title = "Open .FAS",
            DefaultExt = ".fas",
            Filter = "F System Files (*.fas)|*.fas",
            Multiselect = false
        };

        bool? result = openDlg.ShowDialog() == DialogResult.OK;
        if (result != true) return;

        FSystem = XMLParsers.ParseByXDocument(openDlg.FileName);
    }

The application basically lets the user change the different objects (FUser,FZone,FSource, ect). The idea I had was the user would load the XML then be able to edit the different list objects on different views.

What would the correct way be to go about this in MVVM?

I plan to (hopefully) get the User, Zone and Source views to display Datagrids which are populated with their respective data from the Model.

1 Answers1

0

Create you specific view models, and use dependency injection to pass the relevant data into them (this list or that list).

This way, the view models don't need to know about other stuff, and you can easily mock it for testing and for dummy data to see on the designer.

Copy paste into Linqpad for the simplest example. Both mock viewmodels take a dependency (i in our case). You can just pass your lists:

void Main()
{
    int someInt = 5;
    int anotherInt = 7;

    VM vm1 = new VM(someInt);
    VM vm2 = new VM(anotherInt);

    vm1.RevealI();
    vm2.RevealI();
}

public class VM{
    private int _i;

    public VM(int i)
    {
        _i = i; 
    }

    public void RevealI() { Console.WriteLine("value of i is: " + _i); }
}

Othen than that, here's more items:

Community
  • 1
  • 1
Noctis
  • 11,507
  • 3
  • 43
  • 82
  • Hey Noctis, thanks for the response. Sorry to be that guy but would you be able to point me in the right direction by linking a guide or a mock snippet? I've not used dependency injection before so don't really know what is relevant to what I am doing or not. – Andy Pillay Sep 07 '16 at 10:25
  • Yes I have :). I've just been doing reading up on dependency injection items you left. From what I gather, I should be passing the FSystem into my ViewModels/UserControls so they can be used. I'm just thinking ahead on how I can allow the user to be able to open the other views if FSystem is null (if they are building/creating a XML from scratch). – Andy Pillay Sep 07 '16 at 13:31
  • if it's null, either don't open the view, or let them know they have no data. better yet, pass a freshly minted object, which they can manually populate... – Noctis Sep 07 '16 at 23:11