WPF Development, MVVM

Windows Presentation Foundation (WPF) is a platform for creating graphical user interface (GUI) applications in Microsoft’s .NET framework. WPF provides powerful data binding, excellent graphic capabilities, and a variety of flexible UI components that enable developers to easily create attractive UI applications.

1. Features of WPF

WPF has the following features:

  • XAML (Extensible Application Markup Language): WPF uses a markup language called XAML to build the UI. This allows for declarative definition of layouts and UI elements.
  • Data Binding: WPF provides powerful data binding capabilities, making it easy to connect UI elements with data models.
  • Styles and Templates: You can define the styles of UI elements and modify the visual aspects of the UI through templates.
  • 3D Graphics: WPF supports 3D graphics, providing a richer user experience.

2. What is the MVVM Pattern?

The MVVM (Model-View-ViewModel) pattern is an architectural pattern that separates the UI and business logic in WPF applications. The MVVM pattern consists of the following three main components:

  • Model: Contains the data and business logic of the application.
  • View: Composes the user interface, primarily defined in XAML files.
  • ViewModel: Acts as a mediator between the model and the view, preparing data for the UI and handling commands.

2.1 Advantages of MVVM

  • Increases code reusability.
  • Improves testability.
  • Enhances maintainability.
  • Separates UI and business logic to minimize interference.

3. WPF Example Using the MVVM Pattern

Now, let’s look at a simple example of a WPF application that applies the MVVM pattern. This example will create an application that takes user input and performs a simple calculation.

3.1 Creating the Project

Create a new WPF application project in Visual Studio. Name the project “MVVMExample”.

3.2 Model

First, create a model class. This class will have properties for the two numbers to be calculated.


public class CalculatorModel
{
    public double Number1 { get; set; }
    public double Number2 { get; set; }
    public double Result { get; set; }
    
    public void Add()
    {
        Result = Number1 + Number2;
    }
}

3.3 ViewModel

Next, create the ViewModel class. The ViewModel manages access to the model and implements commands using the ICommand interface to interact with the UI.


using System.ComponentModel;
using System.Runtime.CompilerServices;
using System.Windows.Input;

public class CalculatorViewModel : INotifyPropertyChanged
{
    private CalculatorModel _model;

    public CalculatorViewModel()
    {
        _model = new CalculatorModel();
        CalculateCommand = new RelayCommand(Calculate);
    }

    public double Number1
    {
        get => _model.Number1;
        set
        {
            _model.Number1 = value;
            OnPropertyChanged();
        }
    }

    public double Number2
    {
        get => _model.Number2;
        set
        {
            _model.Number2 = value;
            OnPropertyChanged();
        }
    }

    public double Result
    {
        get => _model.Result;
        set
        {
            _model.Result = value;
            OnPropertyChanged();
        }
    }

    public ICommand CalculateCommand { get; private set; }

    private void Calculate()
    {
        _model.Add();
        Result = _model.Result;
    }

    public event PropertyChangedEventHandler PropertyChanged;

    protected void OnPropertyChanged([CallerMemberName] string propertyName = null)
    {
        PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
    }
}

3.4 Command Class (RelayCommand)

Add a RelayCommand class that implements ICommand. This class defines the command and includes logic to determine whether it can be executed.


using System;
using System.Windows.Input;

public class RelayCommand : ICommand
{
    private readonly Action<object> _execute;
    private readonly Predicate<object> _canExecute;

    public RelayCommand(Action<object> execute, Predicate<object> canExecute = null)
    {
        _execute = execute ?? throw new ArgumentNullException(nameof(execute));
        _canExecute = canExecute;
    }

    public event EventHandler CanExecuteChanged
    {
        add { CommandManager.RequerySuggested += value; }
        remove { CommandManager.RequerySuggested -= value; }
    }

    public bool CanExecute(object parameter) =&gt; _canExecute == null || _canExecute(parameter);

    public void Execute(object parameter) =&gt; _execute(parameter);
}

<h3>3.5 View</h3>
<p>
    Finally, modify the XAML file to compose the UI. Create a UI to accept two numbers from the user and display the result.
</p>
<pre><code class="language-xaml">
<window height="200" title="MVVM Example" width="300" x:class="MVVMExample.MainWindow" xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml">
    <grid>
        <stackpanel margin="10">
            <textbox height="30" margin="0,0,0,10" text="{Binding Number1, UpdateSourceTrigger=PropertyChanged}" width="200"></textbox>
            <textbox height="30" margin="0,0,0,10" text="{Binding Number2, UpdateSourceTrigger=PropertyChanged}" width="200"></textbox>
            <button command="{Binding CalculateCommand}" content="Calculate" height="30" width="200"></button>
            <textblock margin="0,10,0,0" text="{Binding Result}"></textblock>
        </stackpanel>
    </grid>
</window>
</code></pre>
<h2>4. Importance of Applying the MVVM Pattern</h2>
<p>
    Applying the MVVM pattern can significantly improve the maintainability, scalability, and testability of an application. By separating the UI and business logic, developers can enhance code reusability and modify business logic without the need to change the UI. Additionally, the ViewModel allows for intuitive code writing by binding data and commands to the UI.
</p>
<h2>5. Conclusion</h2>
<p>
    The combination of WPF and the MVVM pattern is a powerful tool in modern GUI application development. WPF’s rich UI components and the structured approach of MVVM make it an attractive choice for both experts and beginners. The simple example discussed above illustrates how to effectively apply the MVVM pattern to WPF applications.
</p>
<h2>6. References</h2>
<ul>
<li><a href="https://docs.microsoft.com/en-us/dotnet/desktop/wpf/?view=netdesktop-6.0">WPF Documentation</a></li>
<li><a href="https://docs.microsoft.com/en-us/dotnet/architecture/microservices/mvc-architecture/mvvm">MVVM Pattern Overview</a></li>
</ul>

<div id="jp-relatedposts" class="jp-relatedposts">
	<h3 class="jp-relatedposts-headline"><em>관련</em></h3>
</div>	<!-- .entry-content -->

	<footer class="entry-footer">
		<span class="byline"><span class="author vcard"><img alt="" src="https://secure.gravatar.com/avatar/5b7f47db621d1eab02540d35048be506?s=49&amp;d=mm&amp;r=g" srcset="https://secure.gravatar.com/avatar/5b7f47db621d1eab02540d35048be506?s=98&amp;d=mm&amp;r=g 2x" class="avatar avatar-49 photo" height="49" width="49" decoding="async"><span class="screen-reader-text">Author </span> <a class="url fn n" href="https://atmokpo.com/w/en/author/root/">root</a></span></span><span class="posted-on"><span class="screen-reader-text">Posted on </span><a href="https://atmokpo.com/w/37681/" rel="bookmark"><time class="entry-date published" datetime="2024-11-01T09:59:32+00:00">2024/11/01</time><time class="updated" datetime="2024-11-01T11:04:10+00:00">2024/11/01</time></a></span><span class="cat-links"><span class="screen-reader-text">Categories </span><a href="https://atmokpo.com/w/category/wpf-programming/" rel="category tag">WPF Programming</a></span>			</footer><!-- .entry-footer -->
<!-- #post-37681 -->

	<nav class="navigation post-navigation" aria-label="Posts">
		<h2 class="screen-reader-text">Post navigation</h2>
		<div class="nav-links"><div class="nav-previous"><a href="https://atmokpo.com/w/37679/" rel="prev"><span class="meta-nav" aria-hidden="true">Previous</span> <span class="screen-reader-text">Previous post:</span> <span class="post-title">WPF Development, MVC</span></a></div><div class="nav-next"><a href="https://atmokpo.com/w/37683/" rel="next"><span class="meta-nav" aria-hidden="true">Next</span> <span class="screen-reader-text">Next post:</span> <span class="post-title">WPF Development, MVVM Framework Summary</span></a></div></div>
	</nav>
	<!-- .site-main -->

	
<!-- .content-area -->


	<aside id="secondary" class="sidebar widget-area">
		<section id="block-2" class="widget widget_block widget_search"><form role="search" method="get" action="https://atmokpo.com/w/en/" class="wp-block-search__button-outside wp-block-search__text-button wp-block-search"><label class="wp-block-search__label" for="wp-block-search__input-1">Search</label><div class="wp-block-search__inside-wrapper "><input class="wp-block-search__input" id="wp-block-search__input-1" placeholder="" value="" type="search" name="s" required=""><button aria-label="Search" class="wp-block-search__button wp-element-button" type="submit">Search</button></div></form></section><section id="block-10" class="widget widget_block"><ul class="wp-block-page-list"><li class="wp-block-pages-list__item"><a class="wp-block-pages-list__item__link" href="https://atmokpo.com/w/c-coding-test-tutorials/">C++ Coding Test Tutorials</a></li><li class="wp-block-pages-list__item"><a class="wp-block-pages-list__item__link" href="https://atmokpo.com/w/collection-of-c-coding-test-tutorials/">Collection of C# Coding Test Tutorials</a></li><li class="wp-block-pages-list__item"><a class="wp-block-pages-list__item__link" href="https://atmokpo.com/w/deep-learning-automated-trading/">Deep learning Automated trading</a></li><li class="wp-block-pages-list__item"><a class="wp-block-pages-list__item__link" href="https://atmokpo.com/w/deep-learning-natural-language-processing/">Deep learning natural language processing</a></li><li class="wp-block-pages-list__item"><a class="wp-block-pages-list__item__link" href="https://atmokpo.com/w/english-sentence-study/">English sentence study</a></li><li class="wp-block-pages-list__item"><a class="wp-block-pages-list__item__link" href="https://atmokpo.com/w/flutter-course/">Flutter course</a></li><li class="wp-block-pages-list__item"><a class="wp-block-pages-list__item__link" href="https://atmokpo.com/w/gan-deep-learning-course/">GAN deep learning course</a></li><li class="wp-block-pages-list__item"><a class="wp-block-pages-list__item__link" href="https://atmokpo.com/w/java-android-app-development/">Java Android app development</a></li><li class="wp-block-pages-list__item"><a class="wp-block-pages-list__item__link" href="https://atmokpo.com/w/java-coding-test/">Java Coding Test</a></li><li class="wp-block-pages-list__item"><a class="wp-block-pages-list__item__link" href="https://atmokpo.com/w/javascript-coding-test/">Javascript Coding Test</a></li><li class="wp-block-pages-list__item"><a class="wp-block-pages-list__item__link" href="https://atmokpo.com/w/kotlin-android-app-development/">Kotlin Android app development</a></li><li class="wp-block-pages-list__item"><a class="wp-block-pages-list__item__link" href="https://atmokpo.com/w/kotlin-coding-test/">Kotlin coding test</a></li><li class="wp-block-pages-list__item"><a class="wp-block-pages-list__item__link" href="https://atmokpo.com/w/python-auto-trading/">Python Auto Trading</a></li><li class="wp-block-pages-list__item"><a class="wp-block-pages-list__item__link" href="https://atmokpo.com/w/python-coding-test/">Python Coding Test</a></li><li class="wp-block-pages-list__item"><a class="wp-block-pages-list__item__link" href="https://atmokpo.com/w/python-study/">Python Study</a></li><li class="wp-block-pages-list__item"><a class="wp-block-pages-list__item__link" href="https://atmokpo.com/w/pytorch-study/">PyTorch Study</a></li><li class="wp-block-pages-list__item"><a class="wp-block-pages-list__item__link" href="https://atmokpo.com/w/react-basics-course/">React basics course</a></li><li class="wp-block-pages-list__item"><a class="wp-block-pages-list__item__link" href="https://atmokpo.com/w/spring-boot-backend-development/">Spring Boot backend development</a></li><li class="wp-block-pages-list__item"><a class="wp-block-pages-list__item__link" href="https://atmokpo.com/w/swift-coding-test/">Swift Coding Test</a></li><li class="wp-block-pages-list__item"><a class="wp-block-pages-list__item__link" href="https://atmokpo.com/w/swift-iphone-app-development-swiftui/">Swift iPhone app development (SwiftUI)</a></li><li class="wp-block-pages-list__item"><a class="wp-block-pages-list__item__link" href="https://atmokpo.com/w/swift-iphone-app-development-uikit/">Swift iPhone app development (UIKit)</a></li><li class="wp-block-pages-list__item"><a class="wp-block-pages-list__item__link" href="https://atmokpo.com/w/unity-basic/">Unity Basic</a></li><li class="wp-block-pages-list__item"><a class="wp-block-pages-list__item__link" href="https://atmokpo.com/w/using-hugging-face/">Using Hugging Face</a></li><li class="wp-block-pages-list__item"><a class="wp-block-pages-list__item__link" href="https://atmokpo.com/w/uwp-programming/">UWP Programming</a></li><li class="wp-block-pages-list__item"><a class="wp-block-pages-list__item__link" href="https://atmokpo.com/w/wpf-programming/">WPF Programming</a></li></ul></section><section id="listcategorypostswidget-3" class="widget widget_listcategorypostswidget"><h2 class="widget-title">Category Post List</h2><ul class="lcp_catlist" id="lcp_instance_listcategorypostswidget-3"><li><a href="https://atmokpo.com/w/37715/">WPF Development, Practice displaying products and details using MVVM</a></li><li><a href="https://atmokpo.com/w/37713/">WPF Development, Animation</a></li><li><a href="https://atmokpo.com/w/37711/">WPF Development, Spaghetti Code</a></li><li><a href="https://atmokpo.com/w/37709/">WPF Development, Style</a></li><li><a href="https://atmokpo.com/w/37707/">WPF Development, Converter</a></li><li><a href="https://atmokpo.com/w/37705/">WPF Development, Transformation</a></li><li><a href="https://atmokpo.com/w/37703/">WPF Development, Displaying Collections Using List Controls</a></li><li><a href="https://atmokpo.com/w/37701/">WPF Development, Customizing List Controls</a></li><li><a href="https://atmokpo.com/w/37699/">WPF Development, List Control</a></li><li><a href="https://atmokpo.com/w/37697/">WPF Development, Commands and Methods</a></li></ul><ul class="lcp_paginator"><li><a href="https://atmokpo.com/w/37681/?lcp_pagelistcategorypostswidget-3=6#lcp_instance_listcategorypostswidget-3" title="6" class="lcp_prevlink">&lt;&lt;</a></li><li><a href="https://atmokpo.com/w/37681/?lcp_pagelistcategorypostswidget-3=1#lcp_instance_listcategorypostswidget-3" title="1">1</a></li><li><a href="https://atmokpo.com/w/37681/?lcp_pagelistcategorypostswidget-3=2#lcp_instance_listcategorypostswidget-3" title="2">2</a></li><li><a href="https://atmokpo.com/w/37681/?lcp_pagelistcategorypostswidget-3=3#lcp_instance_listcategorypostswidget-3" title="3">3</a></li><li><a href="https://atmokpo.com/w/37681/?lcp_pagelistcategorypostswidget-3=4#lcp_instance_listcategorypostswidget-3" title="4">4</a></li><li><a href="https://atmokpo.com/w/37681/?lcp_pagelistcategorypostswidget-3=5#lcp_instance_listcategorypostswidget-3" title="5">5</a></li><li><a href="https://atmokpo.com/w/37681/?lcp_pagelistcategorypostswidget-3=6#lcp_instance_listcategorypostswidget-3" title="6">6</a></li><li class="lcp_currentpage">7</li><li><a href="https://atmokpo.com/w/37681/?lcp_pagelistcategorypostswidget-3=8#lcp_instance_listcategorypostswidget-3" title="8">8</a></li><li><a href="https://atmokpo.com/w/37681/?lcp_pagelistcategorypostswidget-3=9#lcp_instance_listcategorypostswidget-3" title="9">9</a></li><li><a href="https://atmokpo.com/w/37681/?lcp_pagelistcategorypostswidget-3=8#lcp_instance_listcategorypostswidget-3" title="8" class="lcp_nextlink">&gt;&gt;</a></li></ul></section><section id="block-3" class="widget widget_block">
<div class="wp-block-group"><div class="wp-block-group__inner-container is-layout-flow wp-block-group-is-layout-flow">
<h3 class="wp-block-heading">최신 글</h3>


<ul class="wp-block-latest-posts__list wp-block-latest-posts"><li><a class="wp-block-latest-posts__post-title" href="https://atmokpo.com/w/37979/">Unity 2D Game Development, Create a Platform Game Including Jumps, Obstacles, and Enemies.</a></li>
<li><a class="wp-block-latest-posts__post-title" href="https://atmokpo.com/w/37977/">Unity 2D Game Development, Adding Effects Using Particle System Implementing visual effects such as explosions and flames using the particle system.</a></li>
<li><a class="wp-block-latest-posts__post-title" href="https://atmokpo.com/w/37973/">Unity 2D Game Development, Touch Input and Mobile Game Development  Creation of 2D games utilizing touch input on mobile devices.</a></li>
<li><a class="wp-block-latest-posts__post-title" href="https://atmokpo.com/w/37975/">Unity 2D Game Development, Power-Up and Buff System Creating a power-up system that temporarily enhances the player’s abilities.</a></li>
<li><a class="wp-block-latest-posts__post-title" href="https://atmokpo.com/w/37971/">Unity 2D Game Development, Quest and Mission System Creating a quest system where rewards are given for achieving specific goals.</a></li>
</ul></div></div>
</section>	</aside><!-- .sidebar .widget-area -->

		<!-- .site-content -->

		<footer id="colophon" class="site-footer">
			
			
			<div class="site-info">
								<span class="site-title"><a href="https://atmokpo.com/w/en/" rel="home">라이브스마트</a></span>
								<a href="https://wordpress.org/" class="imprint">
					Proudly powered by WordPress				</a>
			</div><!-- .site-info -->
		</footer><!-- .site-footer -->
	<!-- .site-inner -->
<!-- .site -->

<link rel="stylesheet" id="lcp_paginator-css" href="https://atmokpo.com/w/wp-content/plugins/list-category-posts//lcp_paginator.css?ver=6.7.2" media="all">
<script src="https://atmokpo.com/w/wp-content/plugins/collapse-magic/js/collapse-magic.js?x=203&amp;ver=1.0" id="claps-main-js"></script>
<script defer="" src="https://atmokpo.com/w/wp-content/plugins/koko-analytics/assets/dist/js/script.js?ver=1.6.4" id="koko-analytics-js"></script>
<script src="https://atmokpo.com/w/wp-content/plugins/responsive-accordion-and-collapse/js/accordion-custom.js?ver=6.7.2" id="call_ac-custom-js-front-js"></script>
<script src="https://atmokpo.com/w/wp-content/plugins/responsive-accordion-and-collapse/js/accordion.js?ver=6.7.2" id="call_ac-js-front-js"></script>
<script src="https://stats.wp.com/e-202515.js" id="jetpack-stats-js" data-wp-strategy="defer"></script>
<script id="jetpack-stats-js-after">
_stq = window._stq || [];
_stq.push([ "view", JSON.parse("{\"v\":\"ext\",\"blog\":\"238449126\",\"post\":\"37681\",\"tz\":\"0\",\"srv\":\"atmokpo.com\",\"j\":\"1:14.2.1\"}") ]);
_stq.push([ "clickTrackerInit", "238449126", "37681" ]);
</script>

<script>
  document.querySelectorAll("code").forEach(function(codeBlock) {
      // 내용에 '<'나 '>'가 포함된 경우에만 변환
      if (codeBlock.innerHTML.includes("<") && codeBlock.innerHTML.includes(">")) {
          codeBlock.textContent = codeBlock.innerHTML;
      }
  });
</script></object></object></object></object>