# Appendix


## Model–view–viewmodel (MVVM)

:::{warning}
MVVM adds unnecessary complexity for the goals of this course. The tutorial in {ref}`presenting-data-on-a-grid` builds on the basic template we used in section {ref}`creating-a-gui-application`.

Some reasons: MVVM requires an additional class (viewmodel) for each class of the model that should be shown on the GUI, which adds additional complexity. Moreover, the model classes should send a signal to the viewmodel whenever data in the model change, which can be hard to implement for beginners.
:::


We introduce MVVM mainly because the the framework we utilize also uses MVVM.

:::{wpd} Model–view–viewmodel
an architectural pattern in computer software that facilitates the separation of the development of a GUI (the *view*) from the development of the business logic or back-end logic (the *model*).

Also referred as to:
- *MVVM* in short.
- model–view–*binder*
:::

:::{commons-figure} https://commons.wikimedia.org/wiki/File:MVVMPattern.svg
:name: mvvm-pattern
Three components of MVVM. The return line from model to viewmodel is dashed because usually the viewmodel calls the model.
:::

:::{wpd} model
:id: Model–view–viewmodel#Components_of_MVVM_pattern
business logic and data
:::
:::{wpd} view
:id: Model–view–viewmodel#Components_of_MVVM_pattern
what the user sees and interacts with (structure, layout, controls etc)
:::
:::{wpd} viewmodel
:id: Model–view–viewmodel#Components_of_MVVM_pattern
abstraction (e.g., OOP code) of the view. It uses the *binder* to synchronize GUI elements on the view with the model.
:::
:::{wpd} binder
:id: Model–view–viewmodel#Components_of_MVVM_pattern
the data binding system in XAML (`Binding ...`{l=xml}) which connects the view and the viewmodel.
:::

[Remember](<project:#XAML>) that XAML defines both user interface elements and data-binding.

## Creating an MVVM-based project

1. `New Solution`
1. Select `Avalonia .NET MVVM App` from the list with the name, e.g., `MVVMExample`.

   After the project is opened you should see more directories compared to previous projects you created before, e.g., `Models`, `ViewModels`, `Views` which correspond to the MVVM components we introduced before.
   
1. Run the project.

   It should show you the message `Welcome to Avalonia!`.
   
Let us analyze how this message is presented to the user.

1. Open `MainWindow.axaml` and look at the `TextBlock`.

   You should see that `Text` uses a `Binding` to the path `Greeting`, which is an object in our code. But where?
   
   According to {numref}`mvvm-pattern`, data binding happens between the view and the viewmodel. The XAML describes the view, so `Greeting` must be in the viewmodel.

1. Open `MainWindowViewModel.cs`.

   You should see the property `Greeting` initialized with the welcome message.

## Integrating a `DataGrid` into an MVVM-based template

1. Make sure you have [installed the `DataGrid` control](project:#datagrid-control-installation).

1. :::{include} presenting-data-on-a-grid.md
   :start-after: <!-- application-styles-begin -->
   :end-before: <!-- application-styles-end -->
   :::

1. Under the directory `Models`, create a new file called `Models.cs` that will contain our model classes using right-click on `Models` and then `Add` -> `File`.

   In C# projects, usually we create a new file for each class, but to see all related classes at once, we will put them in a single file. It will be possible to  separate them later.

1. You will be asked whether you want to add the file to Git. `Add` it.
1. Paste the following into `Models.cs`:

   :::{include} presenting-data-on-a-grid.md
   :start-after: <!-- class-person-get-set-begin -->
   :end-before: <!-- class-person-get-set-end -->
   :::
   
1. After the last step, you should see that `Person` is gray underlined. Select the line with `Person` and click {{AllIcons_expui_codeinsight_intentionBulb}} to choose context actions.

1. Click `Move to ... namespace`.

   You will see that a namespace line is added.
   
   Namespaces avoid naming clashes between models, viewmodels and views. Even the probability for naming clashes is very low in a small project, let us follow the structure of other classes in our MVVM template – also the classes in `ViewModels` and `Views` have namespaces.

1. Open `MainWindow.axaml`.

   Replace the `TextBlock` with the following:
   
   :::{include} presenting-data-on-a-grid.md
   :start-after: <!-- mainwindow-include-datagrid-begin -->
   :end-before: <!-- mainwindow-include-datagrid-end -->
   :::

   In the XAML, we see that the data is provided by the binding `People`, which must be an object in the viewmodel.
   
1. Open `MainWindowViewModel.cs`.

   :::{include} presenting-data-on-a-grid.md
   :start-after: <!-- mainwindow.axaml.cs-objectmodel-begin -->
   :end-before: <!-- mainwindow.axaml.cs-objectmodel-end -->
   :::

2.  Delete the definition of the string `Greeting` and replace it with the following:
   
   ```cs
    public ObservableCollection<Person> People { get; }

    public MainWindowViewModel()
    {
        var people = new List<Person> 
        {
            new()
            {
                FirstName = "Melitta",
                LastName = "Lipp"
            },
            new()
            {
                FirstName = "Heilos",
                LastName = "König"
            },
            new()
            {
                FirstName = "Onur",
                LastName = "Kuştepe"
            }
        };
        People = new ObservableCollection<Person>(people);
    }
   ```
   This method creates an example dataset to show on the grid.
   
1. Run your project.
1. Try:

   - modifying data
   - changing sort order
   
This control is useful for editing data structured in the instances of a class. 


:::{include} presenting-data-on-a-grid.md
:start-after: <!-- used-resources-begin -->
:end-before: <!-- used-resources-end -->
:::