Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

What should be the ViewModel members visibility?

Tags:

c#

mvvm

wpf

I've came across an interesting issue for which I've found no explanation yet...

Given the very simple MVVM WPF application below, why is the list bound to the combo box only if its visibility in the ViewModel is set to public ?

Changing the TestList visibility to internal raises no error or warning at compile time but leaves the combo box empty at run time.

Quoting the official documentation: internal types or members are accessible only within files in the same assembly.

And this issue is happening despite the fact that the View and the ViewModel are defined in the same assembly.

Here is how the code looks like:

Model:

class TestModel
{
    internal List<string> Musketeers { get; private set; }

    public TestModel()
    {
        Musketeers = new List<string> { "Athos", "Porthos", "Aramis" };
    }
}

View:

<Window x:Class="TestWpfApplication.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml">
    <Grid>
        <ComboBox Width="250" Height="25" ItemsSource="{Binding TestList}" />
    </Grid>
</Window>

ViewModel:

class TestViewModel : INotifyPropertyChanged
{
    TestModel myModel = new TestModel();

    public List<string> TestList
    {
        get
        {
            return myModel.Musketeers;
        }
    }

    // INotifyPropertyChanged members are below ...
}
like image 865
Yannick Blondeau Avatar asked Mar 13 '13 21:03

Yannick Blondeau


People also ask

Can ViewModel have reference view?

Apart from using the name ViewModel (which itself is confusing if the class is full of logic), the one iron-clad rule of MVVM architecture is that you may never reference a View, from ViewModel.

What is the ViewModel in MVVM?

The ViewModel is a model for the View of the app: an abstraction of the View. The ViewModel retrieves the necessary data from the DataModel, applies the UI logic and then exposes relevant data for the View to consume.

When to use ViewModels?

The ViewModel is essential when you want a separation of concerns between your DomainModel (DataModel) and the rest of your code.

Where do I put ViewModels?

Just create a new folder called ViewModels inside your project. So that along with the Views, Controllers and Models folders, you'll also have ViewModels. Like you already said, you talk to your DAL using your models and you talk to your views using your view models.


2 Answers

ViewModel with internal access is visible for View, but is not visible to Binding class, which really makes the binding work.

{Binding TestList} is transformed into Binding class instance, which has no knowledge about internal members of your ViewModel class.

like image 123
MarcinJuraszek Avatar answered Oct 24 '22 17:10

MarcinJuraszek


This is because Data Binding uses reflection and that in turn adhers to the visibility of items. Since data binding is implemented outside of your assembly - inside the WPF libraries - it cannot see non-public members.

Binding to a non-existing member will not issue a runtime error but rather a debug output with a message containing details about the missing member.

like image 41
Roman Gruber Avatar answered Oct 24 '22 19:10

Roman Gruber