RiSi95
RiSi95

Reputation: 3

How to maintain data binding between multiple Frames and multiple corresponding objects?

I'm working on a UWP application that is essentially a control panel for several of the same objects - let's call them Plate objects.

Functionally, a user needs to be able to create & remove Plate objects with specific properties, and all of the currently available Plate objects are shown on the Main Page, with their corresponding unique properties as well as controls to modify them.

They way I've implemented this is to create a Grid on the Main Page, and for each available Plate, add a Frame into a grid column, and each Frame navigates to a custom PlateView page to show what's basically a horizontal list of PlateView columns.

My problem is that I want to be able to two-way bind data for each control/property from each Plate to its corresponding PlateView.

Right now I store the List of all Plates as a public variable in App.cs, as I need to be able to get and modify this master list from multiple parts of the application through its complete lifecycle.

The way I understood the data binding description in the UWP documentation, either my Plate object can implement INotifyPropertyChanged or I can create a separate PlateViewModel class that implements it.

With Plate implementing it, the PlateView will set its ViewModel to the correct index of Plate in the List (this.ViewModel = App.plateList[1]), but I assume that makes a copy...? So if I modify a variable in PlateView, it won't actually change the Plate object in App.cs.

With a new PlateViewModel class, I don't understand how I wouldn't have the same problem, but inside the PlateViewModel class. For example, MS's documentation shows:

    public class RecordingViewModel
{
    private Recording defaultRecording = new Recording();
    public Recording DefaultRecording { get { return this.defaultRecording; } }
}

Even if I set an internal Plate object inside PlateViewModel, don't I have to call a variable from the XAML {x:bind ...} syntax? So I'd have to make a copy of every variable from the correct Plate into PlateViewModel, and they wouldn't necessarily link to the original Plate object in App.cs?

Thanks!

Upvotes: 0

Views: 218

Answers (1)

Sean O'Neil
Sean O'Neil

Reputation: 1241

To simply answer your question without getting into a whole discussion about MVVM, having the additional ViewModel property to bind to does not create a new instance of the List. What I would do is create a View Model property that presents your model with a getter and setter (in this case the App.cs property is your model):

ViewModel:

public List<Plate> MyPlates
{
    get
    {
        return ((App)Application.Current).MyGlobalListofPlates;
    }
    set
    {
        ((App)Application.Current).MyGlobalListofPlates = value;
        OnPropertyChanged("MyPlates");
    }
}

That code makes it obvious that it's not a new object being made and it gives you some control over what changes to the data are allowed. Another option is to assign the property in the constructor. This does not create a new object either. It is a reference to the original and any changes you make to it will be reflected everywhere.

public List<Plate> MyPlates { get; set; }

public MyViewModel() //Constructor
{
    MyPlates = ((App)Application.Current).MyGlobalListofPlates;
}

This second code block has problems because there's no INotify (which might not matter if it's 2-way binding? Not sure...). Anyway I'm just showing you that assigning the object to another object just creates a reference. You definitely want to read on up on value types versus reference types in C#. Almost any time you do "ThisObject = ThatObject" in C# you're just creating a pointer to the same object in memory.

Upvotes: 0

Related Questions