DEV Community

Cover image for Hands-on project comparation MVVM and MVC in C#
Taki
Taki

Posted on

2

Hands-on project comparation MVVM and MVC in C#

Let's walk through two mini projects side-by-side in C# — one using MVC for a web app (ASP.NET Core), and another using MVVM for a desktop app (WPF). Both will manage a simple Product with properties like Name and Price.


🔷 PROJECT 1: ASP.NET Core MVC Web App

✅ Goal:

A web interface to view and create products using the MVC pattern.

🔧 Tech Stack:

  • ASP.NET Core MVC (.NET 8+)
  • Razor Views

📁 Folder Structure:

MvcProductApp/
│
├── Controllers/
│   └── ProductController.cs
├── Models/
│   └── Product.cs
├── Views/
│   └── Product/
│       ├── Index.cshtml
│       └── Create.cshtml
├── Startup.cs or Program.cs (depending on template)
Enter fullscreen mode Exit fullscreen mode

📄 Models/Product.cs

public class Product
{
    public int Id { get; set; }
    public string Name { get; set; }
    public decimal Price { get; set; }
}
Enter fullscreen mode Exit fullscreen mode

📄 Controllers/ProductController.cs

public class ProductController : Controller
{
    private static List<Product> products = new();

    public IActionResult Index()
    {
        return View(products);
    }

    [HttpGet]
    public IActionResult Create()
    {
        return View();
    }

    [HttpPost]
    public IActionResult Create(Product product)
    {
        products.Add(product);
        return RedirectToAction("Index");
    }
}
Enter fullscreen mode Exit fullscreen mode

📄 Views/Product/Index.cshtml

@model List<Product>

<h2>Product List</h2>
<a href="/Product/Create">Create Product</a>

<ul>
@foreach (var product in Model)
{
    <li>@product.Name - $@product.Price</li>
}
</ul>
Enter fullscreen mode Exit fullscreen mode

📄 Views/Product/Create.cshtml

@model Product

<h2>Create Product</h2>
<form asp-action="Create" method="post">
    <input asp-for="Name" placeholder="Name" />
    <input asp-for="Price" placeholder="Price" />
    <button type="submit">Save</button>
</form>
Enter fullscreen mode Exit fullscreen mode

Run this in your browser. It uses classic MVC:

  • Controller mediates between View and Model.
  • No live data-binding or client-side state.

🔷 PROJECT 2: WPF MVVM Desktop App

✅ Goal:

A WPF desktop app where you can bind textboxes to a ProductViewModel using MVVM.

🔧 Tech Stack:

  • WPF App (.NET 8+)
  • MVVM with INotifyPropertyChanged and ICommand

📁 Folder Structure:

MvvmProductApp/
│
├── Models/
│   └── Product.cs
├── ViewModels/
│   └── ProductViewModel.cs
├── Views/
│   └── MainWindow.xaml
├── RelayCommand.cs
└── App.xaml.cs / MainWindow.xaml.cs
Enter fullscreen mode Exit fullscreen mode

📄 Models/Product.cs

public class Product
{
    public string Name { get; set; }
    public decimal Price { get; set; }
}
Enter fullscreen mode Exit fullscreen mode

📄 RelayCommand.cs

public class RelayCommand : ICommand
{
    private readonly Action _execute;
    public RelayCommand(Action execute) => _execute = execute;

    public event EventHandler CanExecuteChanged;
    public bool CanExecute(object parameter) => true;
    public void Execute(object parameter) => _execute();
}
Enter fullscreen mode Exit fullscreen mode

📄 ViewModels/ProductViewModel.cs

public class ProductViewModel : INotifyPropertyChanged
{
    private string _name;
    private decimal _price;

    public string Name
    {
        get => _name;
        set { _name = value; OnPropertyChanged(nameof(Name)); }
    }

    public decimal Price
    {
        get => _price;
        set { _price = value; OnPropertyChanged(nameof(Price)); }
    }

    public ICommand SaveCommand { get; }

    public ProductViewModel()
    {
        SaveCommand = new RelayCommand(SaveProduct);
    }

    private void SaveProduct()
    {
        MessageBox.Show($"Product saved: {Name}, ${Price}");
    }

    public event PropertyChangedEventHandler PropertyChanged;
    protected void OnPropertyChanged(string propertyName) =>
        PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
}
Enter fullscreen mode Exit fullscreen mode

📄 Views/MainWindow.xaml

<Window x:Class="MvvmProductApp.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:local="clr-namespace:MvvmProductApp"
        Title="MVVM Product App" Height="200" Width="300">
    <Window.DataContext>
        <local:ProductViewModel />
    </Window.DataContext>

    <StackPanel Margin="20">
        <TextBox Text="{Binding Name, Mode=TwoWay}" PlaceholderText="Product Name" />
        <TextBox Text="{Binding Price, Mode=TwoWay}" PlaceholderText="Price" />
        <Button Content="Save" Command="{Binding SaveCommand}" />
    </StackPanel>
</Window>
Enter fullscreen mode Exit fullscreen mode

This is classic MVVM:

  • ViewModel handles logic and exposes data.
  • View binds to ViewModel (no event handlers in code-behind).
  • Supports real-time UI updates and data validation.

🧠 Final Thoughts

Feature ASP.NET MVC WPF MVVM
UI Update Method Server-driven (postbacks) Data binding (live updates)
Logic Separation Controller-centric ViewModel-centric
Platform Web Desktop/mobile
Testability Controller unit test ViewModel unit test

Top comments (0)