DEV Community

Nguyễn Tiến Dũng
Nguyễn Tiến Dũng

Posted on

MVVM In C# .NET

MVVM (Model-View-ViewModel) is a design pattern used in the development of user interfaces, particularly in the context of WPF (Windows Presentation Foundation) and Silverlight applications in C# .NET. It helps separate concerns between the user interface (View), the data (Model), and the application logic (ViewModel).

Here's a brief overview of the MVVM components:

Model: This represents the data and business logic of the application. It provides data to the ViewModel.

View: This represents the user interface (UI) of the application. It binds to the ViewModel to display data and to trigger events.

ViewModel: This acts as a mediator between the View and the Model. It provides data to the View by interacting with the Model and exposes methods and commands for the View to interact with the Model.

Here are some key concepts to understand in MVVM:

Data Binding: This is the mechanism by which data is automatically synchronized between the View and the ViewModel. It is accomplished using data binding expressions in XAML.

Commands: Commands allow the View to trigger actions in the ViewModel, without requiring knowledge of how the ViewModel performs those actions.

Dependency Injection: This is a technique used to inject dependencies (such as data services) into the ViewModel, allowing it to be more modular and testable.

Unit Testing: By separating the concerns of the application, MVVM makes it easier to write unit tests for the ViewModel and Model components.

Overall, MVVM is a powerful pattern that helps make C# .NET applications more modular, testable, and maintainable.

Model:

public class CustomerModel
{
    public string Name { get; set; }
    public string Address { get; set; }
}
Enter fullscreen mode Exit fullscreen mode

ViewModel:

public class CustomerViewModel : INotifyPropertyChanged
{
    private CustomerModel _customer;

    public CustomerViewModel()
    {
        _customer = new CustomerModel();
    }

    public string Name
    {
        get { return _customer.Name; }
        set
        {
            _customer.Name = value;
            OnPropertyChanged(nameof(Name));
        }
    }

    public string Address
    {
        get { return _customer.Address; }
        set
        {
            _customer.Address = value;
            OnPropertyChanged(nameof(Address));
        }
    }

    public event PropertyChangedEventHandler PropertyChanged;

    protected void OnPropertyChanged(string propertyName)
    {
        PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
    }
}
Enter fullscreen mode Exit fullscreen mode

View (XAML):

<Window x:Class="MyApp.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:vm="clr-namespace:MyApp.ViewModels"
        Title="MainWindow" Height="450" Width="800">
    <Window.DataContext>
        <vm:CustomerViewModel />
    </Window.DataContext>
    <Grid>
        <Grid.RowDefinitions>
            <RowDefinition Height="Auto" />
            <RowDefinition Height="Auto" />
            <RowDefinition Height="Auto" />
        </Grid.RowDefinitions>
        <Grid.ColumnDefinitions>
            <ColumnDefinition Width="Auto" />
            <ColumnDefinition Width="*" />
        </Grid.ColumnDefinitions>
        <Label Grid.Row="0" Grid.Column="0" Content="Name:" />
        <TextBox Grid.Row="0" Grid.Column="1" Text="{Binding Name}" />
        <Label Grid.Row="1" Grid.Column="0" Content="Address:" />
        <TextBox Grid.Row="1" Grid.Column="1" Text="{Binding Address}" />
        <Button Grid.Row="2" Grid.Column="1" Content="Save" Command="{Binding SaveCommand}" />
    </Grid>
</Window>

Enter fullscreen mode Exit fullscreen mode

In this example, the CustomerModel class represents the data, the CustomerViewModel class represents the logic, and the XAML View represents the UI. The DataContext property of the Window is set to an instance of the CustomerViewModel class, which provides the data and behavior for the View. Data binding expressions are used to synchronize data between the ViewModel and the View, and the SaveCommand property on the ViewModel exposes a command that the View can use to trigger an action.

Top comments (0)