d--b
d--b

Reputation: 5779

CustomControl in MVVM

I am building a complex UI application and one of the windows contains a control that's a Canvas that draws a directed acyclic graph (DAG) of nodes. Because that window was fairly complex (and because I don't know anything about WPF in the first place), I thought I would use a CustomControl (and not a user control, since I thought user control were used to group things together). The application I am trying to build should be following MVVM.

Now I am creating that GraphControl as a subclass of the Selector control.

Question #1: Is that class the ViewModel? I don't understand the role of the GraphControl class in the grand MVVM story.

Question #2: When I add it to my main application, I have to do something like:

<GraphControl DataContext="{Binding RelativeSource={RelativeSource Self}}" ...

which looks to me like I really haven't understood how that stuff is supposed to work.

Help?

Edit: Apparently that person had the same problem as I had (https://mutelight.org/datacontext-in-a-custom-control). The solution given in the article is to do this:

<GraphControl><Grid DataContext="{Binding RelativeSource={RelativeSource Self}}" ...

That sounds just as hackish to me though...

Upvotes: 0

Views: 1175

Answers (2)

MikeT
MikeT

Reputation: 5500

The best way to answer your question is to explain MVVM

The M is the Data Model, this controls access to data, ie links to Web Services, Databases, Files, Etc

The V is the View, its controls how data is gathered from the users and displayed to the user

The VM is the interface between the 2, it collects the data from the model that needs to be displayed to the user and processes input from the users, validating and performing business checks on data before it is saved to the model

so to answer your first question controls are view elements they collect and display data to the user, if they are doing anything else then you have broken MVVM

to answer your Second questions, if you have correctly built your control you add it in the same way as you add any other control such as a ListView or Button, how you get data into your control depends on how you built it, if that means you designed it to be bound on the datacontext then thats what you do if not then bind to the correct dependency property you set up in the controls code file

Upvotes: 1

mm8
mm8

Reputation: 169150

Question #1: Is that class the ViewModel? I don't understand the role of the GraphControl class in the grand MVVM story.

No. The GraphControl is just another control that belongs to the view. Examples of built-in controls include the TextBox, the Button and the ListBox among several others. Your GraphControl is just another type of control.

The view model is what the control binds to. Please refer to MSDN for a basic introduction to the MVVM design pattern and the roles of each of the components: https://msdn.microsoft.com/en-us/library/hh848246.aspx.

Question #2: When I add it to my main application, I have to do something like:

You can set the DataContext of a control one way or another. The most common approach is to set the DataContext of the parent window to an instance of a view model, e.g.:

public MainWindow()
{
    InitializeComponent();
    DataContext = new ViewModel();
}

A child element inherits the DataContext of its parent element in the element tree unless the DataContext property is explicitly set to something else.

This means that your control will inherit the DataContext of its parent panel which will in turn inherit the DataContext from its parent element and so on.

The following sets the DataContext of the control to itself which means that you can bind to any properties of the GraphControl class without specifying an explicit source:

<GraphControl DataContext="{Binding RelativeSource={RelativeSource Self}}" ...>

Whether you want to do this depends on your requirements.

Upvotes: 2

Related Questions