# Interop with C++ View Model

It is recommended to use the [MVVM](https://en.wikipedia.org/wiki/Model%E2%80%93view%E2%80%93viewmodel) pattern with GacUI:
- `empty list item`
  **Model**: It refers to a domain model. Code in **Model** solves real problem that users need. It could be an object-oriented design of a domain, it could also be a data access layer to the data in database, from the internet, or any possible way.
- `empty list item`
  **ViewModel**: It refers to a set of interface exposing the **Model** in a convient way for **Views**. Data organization in **Model** doesn't have to be UI friendly. It is the **ViewModel** who exposes a right set of operations, to make **Views** access **Model** convenient.
  For example, there are many applications offer list sorting to users. Data in **Model** is not sorted, it could be indexed, because there is so many way to sort the data, it is a waste of storage to cache all sorting result. When a user sort the data in a specific way, it is the **ViewModel** who handels the sorting. the **ViewModel** accesses the data, return the data organization in a sorted way.
- `empty list item`
  **View**: A **View** could be the actual UI of an application, it could also be a set of unit tests. **Views** access **ViewModel**, typically it doesn't access **Model**.

In GacUI, **ViewModels** are defined as a set of interfaces in [Workflow script files](../.././gacui/xmlres/tag_script.md). **Views** are defined as a set of [windows and controls](../.././gacui/xmlres/instance/root_instance.md).

All **ViewModels** that are needed in a **View** are defined as [<ref.Parameter/>](../.././gacui/xmlres/tag_instance.md), which represents constructor arguments to that **View**. The **Class** attributes of such **\<ref.Parameter/\>** will be interfaces for **ViewModels**.

In the GacUI entry point (the **GuiMain** function), a main window will be created. If the main window needs **ViewModels**, the main window **\<Instance/\>** will have one or more **\<ref.Parameter/\>**, then the constructor of the main window will have one or more constructor arguments.

Now, **GuiMain** just needs to create classes that implement these interfaces, and gives all of them to the constructor of the main window, then **ViewModels** and the **View** is connected together.

## Sample

[This](https://github.com/vczh-libraries/Release/tree/master/Tutorial/GacUI_HelloWorlds/MVVM) is a very simple example for using MVVM in GacUI.

![](https://gaclib.net/doc/gacui/adv_mvvm.gif)

The **ViewModel** is an interface:
```
interface IViewModel
{
    func GetUserName() : string;
    func SetUserName(value : string) : void;
    prop UserName : string {GetUserName, SetUserName}

    func GetPassword() : string;
    func SetPassword(value : string) : void;
    prop Password : string {GetPassword, SetPassword}

    func GetUserNameError() : string;
    event UserNameErrorChanged();
    prop UserNameError : string {GetUserNameError : UserNameErrorChanged}

    func GetPasswordError() : string;
    event PasswordErrorChanged();
    prop PasswordError : string {GetPasswordError : PasswordErrorChanged}

    func SignUp() : bool;
}
```
 It defines all **View** needs to know:
- Accessing the user name and the password.
- Retriving validation results for the user name and the password.

When the content of a text box is changed, the data is stored to the view model. This is implemented using data bindings to the view model object:
```
<ref.Parameter Name="ViewModel" Class="vm::IViewModel"/>
<Window ref.Name="self" Text="Let's Sign Up!" ClientSize="x:320 y:320">
    <att.ViewModel-set UserName-bind="textBoxUserName.Text" Password-bind="textBoxPassword.Text"/>
    ...
```

When the validation result is changed, errors are displayed to the UI immediately. This is implemented using data bindings to UI objects:
```
<SolidLabel Text-bind="ViewModel.UserNameError"/>
```

When the user name or the password is stored to the view model, validation results are updated automatically. This is implemented in a C++ class which inherits the interface:
```
class ViewModel : public Object, public virtual vm::IViewModel
{
private:
    WString userName;
    WString password;
    Regex regexLcLetters;
    Regex regexUcLetters;
    Regex regexNumbers;

public:
    ViewModel()
        :regexLcLetters(L"[a-z]")
        , regexUcLetters(L"[A-Z]")
        , regexNumbers(L"[0-9]")
    {
    }

    ...

    WString GetPassword()override
    {
        return password;
    }

    void SetPassword(const WString& value)override
    {
        password = value;
        PasswordErrorChanged();
    }

    WString GetPasswordError()override
    {
        if (password == L"")
        {
            return L"Password should not be empty.";
        }
        bool containsLowerCases = regexLcLetters.Match(password);
        bool containsUpperCases = regexUcLetters.Match(password);
        bool containsNumbers = regexNumbers.Match(password);
        if (!containsLowerCases || !containsUpperCases || !containsNumbers)
        {
            return L"Password should contains at least one lower case letter, one upper case letter and one digit.";
        }
        return L"";
    }
};
```

It is very easy to connect the **ViewModel** to the **View**:
```
void GuiMain()
{
    ...
    auto viewModel = Ptr(new ViewModel);
    auto window = new helloworld::MainWindow(viewModel);
    ...
}
```

Collection objects or tree-like objects can be binded to [list controls](../.././gacui/components/controls/list/home.md) directly. Data bindings accept any [workflow expressions](../.././workflow/lang/bind.md) that compiles. MVVM in GacUI is very powerful, you are free to choose any way to define **ViewModel** interfaces, and it is always possible to bind it to the UI.

