1
votes

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

1 Answers

0
votes

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: