F# and MVVM Light Toolkit Sample Application

MVVM Light Toolkitを使ってViewModelとModelをF#で記述した足し算を行うだけのシンプルなアプリケーションの実装例です。サンプルアプリケーションは以下のような形のものになります。以下に、サンプルに含まれるプロジェクトの概要を示します。 Okazuki.Fsharp.Mvvmプロジェクト(C#)F#でのViewModelの定義を楽にするためのヘルパークラスを定義したViewModelの基本クラスを定義しています。 Okazuki.Fsharp.Mvvm.Sample(C#)MVVM Light Toolkitをベースにしたプ

 
 
 
 
 
(0)
250 times
Add to favorites
6/21/2011
E-mail Twitter del.icio.us Digg Facebook

Solution explorer

C#, F#
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html>
    <head><link rel="stylesheet" type="text/css" href="description/Combined.css,1:ImageSprite;/Areas/Epx/Themes/Msdn/Content:0,/Areas/Epx/Content/Css:1&amp;amp;hashKey=E7560C71640616C5057FAEACB58DCB00" xmlns="http://www.w3.org/1999/xhtml" />
<link rel="stylesheet" type="text/css" href="description/2f95808e-ca34-4249-88ff-44fabe33cdc0Combined.css,1:LinkList,2:ImageSprite,2:SiteFeedbackLink;/Areas/Epx/Themes/Msdn/Content:0,/Areas/Epx/Themes/Base/Content:1,/Areas/Epx/Content/Css:2&amp;amp;hashKey=EEE39C2D6B93379FDAF50337BE99AF8C" xmlns="http://www.w3.org/1999/xhtml" />

        <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
        <title>F# and MVVM Light Toolkit Sample Application</title>
        <link href="description/Galleries.css" type="text/css" rel="Stylesheet" /><link href="description/Layout.css" type="text/css" rel="Stylesheet" /><link href="description/Brand.css" type="text/css" rel="Stylesheet" />
        <link href="description/iframedescription.css" rel="Stylesheet" type="text/css" />
        <script src="description/offline.js" type="text/javascript"></script>
        <style type="text/css">
            #projectInfo {
                overflow: auto;
            }
            #longDesc {
                clear:both;
                margin: 25px 0 10px 0;
            }

            #SampleIndexList{
                margin-left: 15px;
            }
        </style>
    </head>
<body>
    <div id="offlineDescription">
        <h1>F# and MVVM Light Toolkit Sample Application</h1>
        <br/>
        <div id="projectInfo">
            <div class="section">
                    <div class="itemBarLong tagsContainer">
                        <label for="テクノロジ">テクノロジ</label>
                        <div id="テクノロジ">
                            ViewModel pattern (MVVM)
                        </div>
                    </div>
                    <div class="itemBarLong tagsContainer">
                        <label for="トピック">トピック</label>
                        <div id="トピック">
                            Fsharp
                        </div>
                    </div>
                <div class="itemBarLong">
                    <label for="Platforms">Platforms</label>
                    <div id="Platforms">
                        Desktop
                    </div>
                </div>
                <div class="itemBarLong">
                    <label for="Requirements">Requirements</label>
                    <div id="Requirements">
                        
                    </div>
                </div>
                <div class="itemBar">
                    <label for="LastUpdated">Primary Language</label>
                    <div id="LastUpdated">ja-JP</div>
                </div>
                <div class="itemBar">
                    <label for="LastUpdated">最終更新日</label>
                    <div id="LastUpdated">2011/06/21</div>
                </div>
                <div class="itemBarLong">
                    <label for="License">ライセンス</label>
                    <div id="License">
                        <a href="license.rtf">Apache License Version 2.0</a></div>
                </div>
                <div class="itemBar">
                    <div class="viewonlinecont">
                        <a data-link="online" href="http://code.msdn.microsoft.com/F-and-MVVM-Light-Toolkit-5217f8fc">このサンプルをオンラインで表示する</a>
                    </div>
                </div>
            </div>
        </div>
        
                   
<script type="text/javascript">
    function initializePage() {
        var otherTabClass = 'otherTab';
        var hiddenPreClass = 'hidden';

        var htmlDecode = function(encodedData) {
            var decodedData = "";
            if (encodedData) {
                var div = document.createElement('div');
                div.innerHTML = encodedData;
                decodedData = div.firstChild.nodeValue.replace( /\\r\\n/ig , '\r\n');
            }
            return decodedData;
        };
                
        Galleries.iterateElem(Galleries.findElem(null, 'div', 'scriptcode'), function (index, scriptBlock) {
            var titleElem = Galleries.findElem(scriptBlock, 'div', 'title')[0];
            var labelElems = Galleries.findElem(titleElem, 'span');
            if (labelElems.length == 0) {
                labelElems = titleElem;
            }
            var languageSpans = Galleries.findElem(scriptBlock, 'span', 'hidden');
            var pres = Galleries.findElem(scriptBlock, 'pre');
            if (languageSpans.length > 0 && pres.length > 1) {
                Galleries.iterateElem(labelElems, function(index, elem) {
                    var codePre = pres[index];
                    var labelSpan = elem;
                    var languageSpan = languageSpans[index];
                            
                    elem.code = codePre.innerHTML.replace( /(\r(\n)?)|((\r)?\n)/ig , '\\r\\n');
                            
                    codePre.className = codePre.className.replace(hiddenPreClass, '');
                            
                    languageSpan.parentNode.removeChild(languageSpan);
                });

                pres = Galleries.findElem(scriptBlock, 'pre');
                Galleries.iterateElem(labelElems, function(index, elem) {
                    var codePre = pres[index];
                    var labelSpan = elem;
                    if (index == 0) {
                        scriptBlock.activeTab = 0;
                    }
                    else {
                        labelSpan.className += otherTabClass;
                        codePre.className += hiddenPreClass;
                    }
                    Galleries.attachEventHandler(labelSpan, 'click', function(e) {
                        var activeTab = scriptBlock.activeTab;
                        labelElems[activeTab].className += otherTabClass;
                        pres[activeTab].className += hiddenPreClass;

                        codePre.className = codePre.className.replace(hiddenPreClass, '');
                        labelSpan.className = labelSpan.className.replace(otherTabClass, '');
                        scriptBlock.activeTab = index;
                    });
                });

                var preview = Galleries.findElem(scriptBlock, 'div', 'preview');
                if (preview.length == 0) {
                    preview.push(pres[pres.length - 1]);
                }
                Galleries.iterateElem(preview, function(index, elem) {
                    elem.parentNode.removeChild(elem);
                });

                if (window.clipboardData && clipboardData.setData) {
                    var copyLink = document.createElement('a');
                    copyLink.href = 'javascript:void(0);';
                    copyLink.className = 'copyCode';
                    copyLink.innerHTML = 'コードをコピー';
                    Galleries.attachEventHandler(copyLink, 'click', function (e) {
                        clipboardData.setData("Text", htmlDecode(labelElems[scriptBlock.activeTab].code));
                        return false;
                    });
                    scriptBlock.insertBefore(copyLink, scriptBlock.childNodes[0]);
                }
            }
        });
    }

    Galleries.onWindowLoad(function(){
        initializePage();
    });

</script>
<div id="longDesc">
    
<h1>概要</h1>
<p>MVVM Light Toolkitを使ってViewModelとModelをF#で記述した足し算を行うだけのシンプルなアプリケーションの実装例です。サンプルアプリケーションは以下のような形のものになります。</p>
<p><img src="description/WS000000.JPG" alt="" width="265" height="78"></p>
<p>以下に、サンプルに含まれるプロジェクトの概要を示します。</p>
<ul>
<li>Okazuki.Fsharp.Mvvmプロジェクト(C#)<br>
F#でのViewModelの定義を楽にするためのヘルパークラスを定義したViewModelの基本クラスを定義しています。 </li><li>Okazuki.Fsharp.Mvvm.Sample(C#)<br>
MVVM Light Toolkitをベースにしたプロジェクトです。Viewを担当します。&nbsp; </li><li>Okazuki.Fsharp.Mvvm.ViewModel(F#)&nbsp;<br>
F#で記述したViewModelとModelを定義しています。&nbsp; </li></ul>
<h1>ポイント</h1>
<p>F#でのプロパティやコマンドの記述を簡略化するために、MVVM Light Toolkitで提供されているViewModelBaseを継承して、以下のようなヘルパーメソッドを追加したFsViewModelBaseクラスを定義しています。</p>
<p>&nbsp;</p>
<div class="scriptcode">
<div class="pluginEditHolder" pluginCommand="mceScriptCode">
<div class="title"><span>C#</span></div>
<div class="pluginEditHolderLink">スクリプトの編集</div>
<span class="hidden">csharp</span>
<pre class="hidden">namespace Okazuki.Fsharp.Mvvm
{
    using System;
    using GalaSoft.MvvmLight;
    using GalaSoft.MvvmLight.Command;

    /// &lt;summary&gt;
    /// F#でのViewModelの定義の簡略化のためのメソッドを追加したViewModelの基本クラス。
    /// &lt;/summary&gt;
    public class FsViewModelBase : ViewModelBase
    {
        /// &lt;summary&gt;
        /// プロパティの値の設定と変更通知を行います。
        /// &lt;/summary&gt;
        /// &lt;typeparam name=&quot;T&quot;&gt;プロパティの型&lt;/typeparam&gt;
        /// &lt;param name=&quot;field&quot;&gt;フィールド&lt;/param&gt;
        /// &lt;param name=&quot;value&quot;&gt;プロパティにセットする値&lt;/param&gt;
        /// &lt;param name=&quot;propertyName&quot;&gt;プロパティ名&lt;/param&gt;
        protected void SetAndNotify&lt;T&gt;(ref T field, T value, string propertyName)
        {
            if (Equals(field, value))
            {
                return;
            }

            field = value;
            base.RaisePropertyChanged(propertyName);
        }

        /// &lt;summary&gt;
        /// RelayCommandを作成、または取得します。
        /// &lt;/summary&gt;
        /// &lt;param name=&quot;field&quot;&gt;フィールド&lt;/param&gt;
        /// &lt;param name=&quot;execute&quot;&gt;コマンドの実行メソッド&lt;/param&gt;
        /// &lt;param name=&quot;canExecute&quot;&gt;コマンドの実行可否判定メソッド&lt;/param&gt;
        /// &lt;returns&gt;作成または取得されたコマンド&lt;/returns&gt;
        protected RelayCommand GetOrCreateCommand(
            ref RelayCommand field,
            Action execute,
            Func&lt;bool&gt; canExecute)
        {
            if (field != null)
            {
                return field;
            }

            return field = new RelayCommand(execute, canExecute);
        }

        /// &lt;summary&gt;
        /// RelayCommandを作成、または取得します。
        /// &lt;/summary&gt;
        /// &lt;param name=&quot;field&quot;&gt;フィールド&lt;/param&gt;
        /// &lt;param name=&quot;execute&quot;&gt;コマンドの実行メソッド&lt;/param&gt;
        /// &lt;returns&gt;作成または取得されたコマンド&lt;/returns&gt;
        protected RelayCommand GetOrCreateCommand(
            ref RelayCommand field,
            Action execute)
        {
            return GetOrCreateCommand(ref field, execute, () =&gt; true);
        }

        /// &lt;summary&gt;
        /// RelayCommandを作成、または取得します。
        /// &lt;/summary&gt;
        /// &lt;typeparam name=&quot;T&quot;&gt;コマンドの引数の型&lt;/typeparam&gt;
        /// &lt;param name=&quot;field&quot;&gt;フィールド&lt;/param&gt;
        /// &lt;param name=&quot;execute&quot;&gt;コマンドの実行メソッド&lt;/param&gt;
        /// &lt;param name=&quot;canExecute&quot;&gt;コマンドの実行可否判定メソッド&lt;/param&gt;
        /// &lt;returns&gt;作成または取得されたコマンド&lt;/returns&gt;
        protected RelayCommand&lt;T&gt; GetOrCreateCommand&lt;T&gt;(
            ref RelayCommand&lt;T&gt; field,
            Action&lt;T&gt; execute,
            Predicate&lt;T&gt; canExecute)
        {
            if (field != null)
            {
                return field;
            }

            return field = new RelayCommand&lt;T&gt;(execute, canExecute);
        }

        /// &lt;summary&gt;
        /// RelayCommandを作成、または取得します。
        /// &lt;/summary&gt;
        /// &lt;typeparam name=&quot;T&quot;&gt;コマンドの引数の型&lt;/typeparam&gt;
        /// &lt;param name=&quot;field&quot;&gt;フィールド&lt;/param&gt;
        /// &lt;param name=&quot;execute&quot;&gt;コマンドの実行メソッド&lt;/param&gt;
        /// &lt;returns&gt;作成または取得されたコマンド&lt;/returns&gt;
        protected RelayCommand&lt;T&gt; GetOrCreateCommand&lt;T&gt;(
            ref RelayCommand&lt;T&gt; field,
            Action&lt;T&gt; execute)
        {
            return GetOrCreateCommand&lt;T&gt;(ref field, execute, v =&gt; true);
        }
    }
}
</pre>
<div class="preview">
<pre class="csharp"><span class="cs__keyword">namespace</span>&nbsp;Okazuki.Fsharp.Mvvm&nbsp;
{&nbsp;
&nbsp;&nbsp;&nbsp;&nbsp;<span class="cs__keyword">using</span>&nbsp;System;&nbsp;
&nbsp;&nbsp;&nbsp;&nbsp;<span class="cs__keyword">using</span>&nbsp;GalaSoft.MvvmLight;&nbsp;
&nbsp;&nbsp;&nbsp;&nbsp;<span class="cs__keyword">using</span>&nbsp;GalaSoft.MvvmLight.Command;&nbsp;
&nbsp;
&nbsp;&nbsp;&nbsp;&nbsp;<span class="cs__com">///&nbsp;&lt;summary&gt;</span>&nbsp;
&nbsp;&nbsp;&nbsp;&nbsp;<span class="cs__com">///&nbsp;F#でのViewModelの定義の簡略化のためのメソッドを追加したViewModelの基本クラス。</span>&nbsp;
&nbsp;&nbsp;&nbsp;&nbsp;<span class="cs__com">///&nbsp;&lt;/summary&gt;</span>&nbsp;
&nbsp;&nbsp;&nbsp;&nbsp;<span class="cs__keyword">public</span>&nbsp;<span class="cs__keyword">class</span>&nbsp;FsViewModelBase&nbsp;:&nbsp;ViewModelBase&nbsp;
&nbsp;&nbsp;&nbsp;&nbsp;{&nbsp;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="cs__com">///&nbsp;&lt;summary&gt;</span>&nbsp;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="cs__com">///&nbsp;プロパティの値の設定と変更通知を行います。</span>&nbsp;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="cs__com">///&nbsp;&lt;/summary&gt;</span>&nbsp;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="cs__com">///&nbsp;&lt;typeparam&nbsp;name=&quot;T&quot;&gt;プロパティの型&lt;/typeparam&gt;</span>&nbsp;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="cs__com">///&nbsp;&lt;param&nbsp;name=&quot;field&quot;&gt;フィールド&lt;/param&gt;</span>&nbsp;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="cs__com">///&nbsp;&lt;param&nbsp;name=&quot;value&quot;&gt;プロパティにセットする値&lt;/param&gt;</span>&nbsp;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="cs__com">///&nbsp;&lt;param&nbsp;name=&quot;propertyName&quot;&gt;プロパティ名&lt;/param&gt;</span>&nbsp;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="cs__keyword">protected</span>&nbsp;<span class="cs__keyword">void</span>&nbsp;SetAndNotify&lt;T&gt;(<span class="cs__keyword">ref</span>&nbsp;T&nbsp;field,&nbsp;T&nbsp;<span class="cs__keyword">value</span>,&nbsp;<span class="cs__keyword">string</span>&nbsp;propertyName)&nbsp;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{&nbsp;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="cs__keyword">if</span>&nbsp;(Equals(field,&nbsp;<span class="cs__keyword">value</span>))&nbsp;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{&nbsp;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="cs__keyword">return</span>;&nbsp;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}&nbsp;
&nbsp;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;field&nbsp;=&nbsp;<span class="cs__keyword">value</span>;&nbsp;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="cs__keyword">base</span>.RaisePropertyChanged(propertyName);&nbsp;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}&nbsp;
&nbsp;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="cs__com">///&nbsp;&lt;summary&gt;</span>&nbsp;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="cs__com">///&nbsp;RelayCommandを作成、または取得します。</span>&nbsp;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="cs__com">///&nbsp;&lt;/summary&gt;</span>&nbsp;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="cs__com">///&nbsp;&lt;param&nbsp;name=&quot;field&quot;&gt;フィールド&lt;/param&gt;</span>&nbsp;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="cs__com">///&nbsp;&lt;param&nbsp;name=&quot;execute&quot;&gt;コマンドの実行メソッド&lt;/param&gt;</span>&nbsp;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="cs__com">///&nbsp;&lt;param&nbsp;name=&quot;canExecute&quot;&gt;コマンドの実行可否判定メソッド&lt;/param&gt;</span>&nbsp;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="cs__com">///&nbsp;&lt;returns&gt;作成または取得されたコマンド&lt;/returns&gt;</span>&nbsp;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="cs__keyword">protected</span>&nbsp;RelayCommand&nbsp;GetOrCreateCommand(&nbsp;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="cs__keyword">ref</span>&nbsp;RelayCommand&nbsp;field,&nbsp;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Action&nbsp;execute,&nbsp;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Func&lt;<span class="cs__keyword">bool</span>&gt;&nbsp;canExecute)&nbsp;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{&nbsp;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="cs__keyword">if</span>&nbsp;(field&nbsp;!=&nbsp;<span class="cs__keyword">null</span>)&nbsp;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{&nbsp;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="cs__keyword">return</span>&nbsp;field;&nbsp;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}&nbsp;
&nbsp;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="cs__keyword">return</span>&nbsp;field&nbsp;=&nbsp;<span class="cs__keyword">new</span>&nbsp;RelayCommand(execute,&nbsp;canExecute);&nbsp;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}&nbsp;
&nbsp;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="cs__com">///&nbsp;&lt;summary&gt;</span>&nbsp;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="cs__com">///&nbsp;RelayCommandを作成、または取得します。</span>&nbsp;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="cs__com">///&nbsp;&lt;/summary&gt;</span>&nbsp;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="cs__com">///&nbsp;&lt;param&nbsp;name=&quot;field&quot;&gt;フィールド&lt;/param&gt;</span>&nbsp;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="cs__com">///&nbsp;&lt;param&nbsp;name=&quot;execute&quot;&gt;コマンドの実行メソッド&lt;/param&gt;</span>&nbsp;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="cs__com">///&nbsp;&lt;returns&gt;作成または取得されたコマンド&lt;/returns&gt;</span>&nbsp;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="cs__keyword">protected</span>&nbsp;RelayCommand&nbsp;GetOrCreateCommand(&nbsp;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="cs__keyword">ref</span>&nbsp;RelayCommand&nbsp;field,&nbsp;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Action&nbsp;execute)&nbsp;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{&nbsp;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="cs__keyword">return</span>&nbsp;GetOrCreateCommand(<span class="cs__keyword">ref</span>&nbsp;field,&nbsp;execute,&nbsp;()&nbsp;=&gt;&nbsp;<span class="cs__keyword">true</span>);&nbsp;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}&nbsp;
&nbsp;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="cs__com">///&nbsp;&lt;summary&gt;</span>&nbsp;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="cs__com">///&nbsp;RelayCommandを作成、または取得します。</span>&nbsp;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="cs__com">///&nbsp;&lt;/summary&gt;</span>&nbsp;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="cs__com">///&nbsp;&lt;typeparam&nbsp;name=&quot;T&quot;&gt;コマンドの引数の型&lt;/typeparam&gt;</span>&nbsp;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="cs__com">///&nbsp;&lt;param&nbsp;name=&quot;field&quot;&gt;フィールド&lt;/param&gt;</span>&nbsp;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="cs__com">///&nbsp;&lt;param&nbsp;name=&quot;execute&quot;&gt;コマンドの実行メソッド&lt;/param&gt;</span>&nbsp;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="cs__com">///&nbsp;&lt;param&nbsp;name=&quot;canExecute&quot;&gt;コマンドの実行可否判定メソッド&lt;/param&gt;</span>&nbsp;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="cs__com">///&nbsp;&lt;returns&gt;作成または取得されたコマンド&lt;/returns&gt;</span>&nbsp;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="cs__keyword">protected</span>&nbsp;RelayCommand&lt;T&gt;&nbsp;GetOrCreateCommand&lt;T&gt;(&nbsp;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="cs__keyword">ref</span>&nbsp;RelayCommand&lt;T&gt;&nbsp;field,&nbsp;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Action&lt;T&gt;&nbsp;execute,&nbsp;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Predicate&lt;T&gt;&nbsp;canExecute)&nbsp;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{&nbsp;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="cs__keyword">if</span>&nbsp;(field&nbsp;!=&nbsp;<span class="cs__keyword">null</span>)&nbsp;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{&nbsp;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="cs__keyword">return</span>&nbsp;field;&nbsp;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}&nbsp;
&nbsp;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="cs__keyword">return</span>&nbsp;field&nbsp;=&nbsp;<span class="cs__keyword">new</span>&nbsp;RelayCommand&lt;T&gt;(execute,&nbsp;canExecute);&nbsp;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}&nbsp;
&nbsp;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="cs__com">///&nbsp;&lt;summary&gt;</span>&nbsp;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="cs__com">///&nbsp;RelayCommandを作成、または取得します。</span>&nbsp;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="cs__com">///&nbsp;&lt;/summary&gt;</span>&nbsp;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="cs__com">///&nbsp;&lt;typeparam&nbsp;name=&quot;T&quot;&gt;コマンドの引数の型&lt;/typeparam&gt;</span>&nbsp;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="cs__com">///&nbsp;&lt;param&nbsp;name=&quot;field&quot;&gt;フィールド&lt;/param&gt;</span>&nbsp;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="cs__com">///&nbsp;&lt;param&nbsp;name=&quot;execute&quot;&gt;コマンドの実行メソッド&lt;/param&gt;</span>&nbsp;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="cs__com">///&nbsp;&lt;returns&gt;作成または取得されたコマンド&lt;/returns&gt;</span>&nbsp;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="cs__keyword">protected</span>&nbsp;RelayCommand&lt;T&gt;&nbsp;GetOrCreateCommand&lt;T&gt;(&nbsp;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="cs__keyword">ref</span>&nbsp;RelayCommand&lt;T&gt;&nbsp;field,&nbsp;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Action&lt;T&gt;&nbsp;execute)&nbsp;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{&nbsp;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="cs__keyword">return</span>&nbsp;GetOrCreateCommand&lt;T&gt;(<span class="cs__keyword">ref</span>&nbsp;field,&nbsp;execute,&nbsp;v&nbsp;=&gt;&nbsp;<span class="cs__keyword">true</span>);&nbsp;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}&nbsp;
&nbsp;&nbsp;&nbsp;&nbsp;}&nbsp;
}&nbsp;
&nbsp;
&nbsp;
</pre>
</div>
</div>
</div>
<div class="endscriptcode">&nbsp;</div>
<p>&nbsp;</p>
<p>いくつか、メソッドが定義されていますが、ポイントとなるメソッドは2つになります。1つはプロパティのsetterで使用するメソッド。もう1つはRelayCommand型のプロパティで使用するメソッドです。setterで使用するメソッドはSetAndNotifyメソッドで、プロパティのsetterに書くプロパティの変更通知などの冗長な処理を肩代わりしてくれます。RelayCommand型のプロパティで使用するメソッドは、初回のみコマンドの生成を行い、二回目以降の呼び出しでは生成したコマンドを返すメソッドです。</p>
<p>上記のクラスを使用することでF#で記述するViewModelのプロパティの定義のコードは以下のようになります。</p>
<p>&nbsp;</p>
<div class="scriptcode">
<div class="pluginEditHolder" pluginCommand="mceScriptCode">
<div class="title"><span>C#</span></div>
<div class="pluginEditHolderLink">スクリプトの編集</div>
<span class="hidden">csharp</span>
<pre class="hidden">let mutable lhs = 0

/// 左辺値を取得または設定します
member x.Lhs 
    with get() = lhs
    and set v = x.SetAndNotify(&amp;lhs, v, &quot;Lhs&quot;)
</pre>
<div class="preview">
<pre class="csharp">let&nbsp;mutable&nbsp;lhs&nbsp;=&nbsp;<span class="cs__number">0</span>&nbsp;
&nbsp;
<span class="cs__com">///&nbsp;左辺値を取得または設定します</span>&nbsp;
member&nbsp;x.Lhs&nbsp;&nbsp;
&nbsp;&nbsp;&nbsp;&nbsp;with&nbsp;<span class="cs__keyword">get</span>()&nbsp;=&nbsp;lhs&nbsp;
&nbsp;&nbsp;&nbsp;&nbsp;and&nbsp;<span class="cs__keyword">set</span>&nbsp;v&nbsp;=&nbsp;x.SetAndNotify(&amp;lhs,&nbsp;v,&nbsp;<span class="cs__string">&quot;Lhs&quot;</span>)&nbsp;
&nbsp;
&nbsp;
</pre>
</div>
</div>
</div>
<div class="endscriptcode">SetAndNotifyの記述だけでいい点とF#の文法の簡潔さによって非常にすっきりした定義になります。コマンドの定義も以下のようになります。</div>
<div class="endscriptcode">
<div class="scriptcode">
<div class="pluginEditHolder" pluginCommand="mceScriptCode">
<div class="title"><span>C#</span></div>
<div class="pluginEditHolderLink">スクリプトの編集</div>
<span class="hidden">csharp</span>
<pre class="hidden">let mutable addCommand = null

/// 足し算コマンドを取得します
member x.AddCommand
    with get() = x.GetOrCreateCommand(
                    &amp;addCommand, 
                    x.AddExecute)

/// 足し算ロジックを呼び出します。
member private x.AddExecute() =
    // Modelのメソッドへ委譲
    x.Answer &lt;- Calc.add lhs rhs
</pre>
<div class="preview">
<pre class="csharp">let&nbsp;mutable&nbsp;addCommand&nbsp;=&nbsp;<span class="cs__keyword">null</span>&nbsp;
&nbsp;
<span class="cs__com">///&nbsp;足し算コマンドを取得します</span>&nbsp;
member&nbsp;x.AddCommand&nbsp;
&nbsp;&nbsp;&nbsp;&nbsp;with&nbsp;<span class="cs__keyword">get</span>()&nbsp;=&nbsp;x.GetOrCreateCommand(&nbsp;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&amp;addCommand,&nbsp;&nbsp;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;x.AddExecute)&nbsp;
&nbsp;
<span class="cs__com">///&nbsp;足し算ロジックを呼び出します。</span>&nbsp;
member&nbsp;<span class="cs__keyword">private</span>&nbsp;x.AddExecute()&nbsp;=&nbsp;
&nbsp;&nbsp;&nbsp;&nbsp;<span class="cs__com">//&nbsp;Modelのメソッドへ委譲</span>&nbsp;
&nbsp;&nbsp;&nbsp;&nbsp;x.Answer&nbsp;&lt;-&nbsp;Calc.add&nbsp;lhs&nbsp;rhs&nbsp;
&nbsp;
&nbsp;
</pre>
</div>
</div>
</div>
<div class="endscriptcode">実際には、フィールドの定義とメソッドやプロパティの定義の並びの関係で上記のようにプロパティ関連の定義やコマンドの定義をまとまった位置に書くことは出来ませんが実際のコードイメージは上記のようになります。</div>
<div class="endscriptcode"></div>
<h1 class="endscriptcode">MVVM Light Toolkitらしく仕上げる</h1>
<p>最後に、ViewModelLocatorを定義してF#で作成したViewModelを返すプロパティを定義します。そしてWindowを以下のように左辺値と右辺値の入力TextBoxと計算を行うボタンと答えを表示するTextBlockを置いて完成です。</p>
<p>&nbsp;</p>
<div class="scriptcode">
<div class="pluginEditHolder" pluginCommand="mceScriptCode">
<div class="title"><span>XAML</span></div>
<div class="pluginEditHolderLink">スクリプトの編集</div>
<span class="hidden">xaml</span>
<pre class="hidden">&lt;Window x:Class=&quot;Okazuki.Fsharp.Mvvm.Sample.MainWindow&quot;
        xmlns=&quot;http://schemas.microsoft.com/winfx/2006/xaml/presentation&quot;
        xmlns:x=&quot;http://schemas.microsoft.com/winfx/2006/xaml&quot;
        Title=&quot;MainWindow&quot; Height=&quot;350&quot; Width=&quot;525&quot; 
        DataContext=&quot;{Binding Source={StaticResource Locator}, Path=Main}&quot; SizeToContent=&quot;WidthAndHeight&quot;&gt;
    &lt;Grid&gt;
        &lt;Grid.ColumnDefinitions&gt;
            &lt;ColumnDefinition Width=&quot;Auto&quot; /&gt;
            &lt;ColumnDefinition Width=&quot;Auto&quot; /&gt;
            &lt;ColumnDefinition Width=&quot;Auto&quot; /&gt;
            &lt;ColumnDefinition Width=&quot;Auto&quot; /&gt;
            &lt;ColumnDefinition Width=&quot;Auto&quot; /&gt;
        &lt;/Grid.ColumnDefinitions&gt;
        &lt;Button Content=&quot;=&quot; Name=&quot;button1&quot; Command=&quot;{Binding Path=AddCommand}&quot; Grid.Column=&quot;3&quot; Margin=&quot;5&quot; /&gt;
        &lt;TextBox Name=&quot;textBox1&quot; Text=&quot;{Binding Path=Lhs}&quot; MinWidth=&quot;75&quot; Margin=&quot;5&quot; /&gt;
        &lt;TextBlock Name=&quot;textBlock1&quot; Text=&quot;{Binding Path=Answer}&quot; Grid.Column=&quot;4&quot; Margin=&quot;5&quot; VerticalAlignment=&quot;Center&quot; /&gt;
        &lt;TextBox Name=&quot;textBox2&quot; Text=&quot;{Binding Path=Rhs}&quot; Grid.Column=&quot;2&quot; MinWidth=&quot;75&quot; Margin=&quot;5&quot; /&gt;
        &lt;TextBlock Grid.Column=&quot;1&quot; Name=&quot;textBlock2&quot; Text=&quot;&#43;&quot; Margin=&quot;5&quot; VerticalAlignment=&quot;Center&quot; /&gt;
    &lt;/Grid&gt;
&lt;/Window&gt;
</pre>
<div class="preview">
<pre class="xaml"><span class="xaml__tag_start">&lt;Window</span>&nbsp;x:<span class="xaml__attr_name">Class</span>=<span class="xaml__attr_value">&quot;Okazuki.Fsharp.Mvvm.Sample.MainWindow&quot;</span>&nbsp;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="xaml__attr_name">xmlns</span>=<span class="xaml__attr_value">&quot;http://schemas.microsoft.com/winfx/2006/xaml/presentation&quot;</span>&nbsp;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="xaml__keyword">xmlns</span>:<span class="xaml__attr_name">x</span>=<span class="xaml__attr_value">&quot;http://schemas.microsoft.com/winfx/2006/xaml&quot;</span>&nbsp;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="xaml__attr_name">Title</span>=<span class="xaml__attr_value">&quot;MainWindow&quot;</span>&nbsp;<span class="xaml__attr_name">Height</span>=<span class="xaml__attr_value">&quot;350&quot;</span>&nbsp;<span class="xaml__attr_name">Width</span>=<span class="xaml__attr_value">&quot;525&quot;</span>&nbsp;&nbsp;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="xaml__attr_name">DataContext</span>=<span class="xaml__attr_value">&quot;{Binding&nbsp;Source={StaticResource&nbsp;Locator},&nbsp;Path=Main}&quot;</span>&nbsp;<span class="xaml__attr_name">SizeToContent</span>=<span class="xaml__attr_value">&quot;WidthAndHeight&quot;</span><span class="xaml__tag_start">&gt;&nbsp;
</span>&nbsp;&nbsp;&nbsp;&nbsp;<span class="xaml__tag_start">&lt;Grid</span><span class="xaml__tag_start">&gt;&nbsp;
</span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="xaml__tag_start">&lt;Grid</span>.ColumnDefinitions<span class="xaml__tag_start">&gt;&nbsp;
</span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="xaml__tag_start">&lt;ColumnDefinition</span>&nbsp;<span class="xaml__attr_name">Width</span>=<span class="xaml__attr_value">&quot;Auto&quot;</span>&nbsp;<span class="xaml__tag_start">/&gt;</span>&nbsp;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="xaml__tag_start">&lt;ColumnDefinition</span>&nbsp;<span class="xaml__attr_name">Width</span>=<span class="xaml__attr_value">&quot;Auto&quot;</span>&nbsp;<span class="xaml__tag_start">/&gt;</span>&nbsp;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="xaml__tag_start">&lt;ColumnDefinition</span>&nbsp;<span class="xaml__attr_name">Width</span>=<span class="xaml__attr_value">&quot;Auto&quot;</span>&nbsp;<span class="xaml__tag_start">/&gt;</span>&nbsp;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="xaml__tag_start">&lt;ColumnDefinition</span>&nbsp;<span class="xaml__attr_name">Width</span>=<span class="xaml__attr_value">&quot;Auto&quot;</span>&nbsp;<span class="xaml__tag_start">/&gt;</span>&nbsp;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="xaml__tag_start">&lt;ColumnDefinition</span>&nbsp;<span class="xaml__attr_name">Width</span>=<span class="xaml__attr_value">&quot;Auto&quot;</span>&nbsp;<span class="xaml__tag_start">/&gt;</span>&nbsp;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&lt;/Grid.ColumnDefinitions&gt;&nbsp;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="xaml__tag_start">&lt;Button</span>&nbsp;<span class="xaml__attr_name">Content</span>=<span class="xaml__attr_value">&quot;=&quot;</span>&nbsp;<span class="xaml__attr_name">Name</span>=<span class="xaml__attr_value">&quot;button1&quot;</span>&nbsp;<span class="xaml__attr_name">Command</span>=<span class="xaml__attr_value">&quot;{Binding&nbsp;Path=AddCommand}&quot;</span>&nbsp;Grid.<span class="xaml__attr_name">Column</span>=<span class="xaml__attr_value">&quot;3&quot;</span>&nbsp;<span class="xaml__attr_name">Margin</span>=<span class="xaml__attr_value">&quot;5&quot;</span>&nbsp;<span class="xaml__tag_start">/&gt;</span>&nbsp;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="xaml__tag_start">&lt;TextBox</span>&nbsp;<span class="xaml__attr_name">Name</span>=<span class="xaml__attr_value">&quot;textBox1&quot;</span>&nbsp;<span class="xaml__attr_name">Text</span>=<span class="xaml__attr_value">&quot;{Binding&nbsp;Path=Lhs}&quot;</span>&nbsp;<span class="xaml__attr_name">MinWidth</span>=<span class="xaml__attr_value">&quot;75&quot;</span>&nbsp;<span class="xaml__attr_name">Margin</span>=<span class="xaml__attr_value">&quot;5&quot;</span>&nbsp;<span class="xaml__tag_start">/&gt;</span>&nbsp;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="xaml__tag_start">&lt;TextBlock</span>&nbsp;<span class="xaml__attr_name">Name</span>=<span class="xaml__attr_value">&quot;textBlock1&quot;</span>&nbsp;<span class="xaml__attr_name">Text</span>=<span class="xaml__attr_value">&quot;{Binding&nbsp;Path=Answer}&quot;</span>&nbsp;Grid.<span class="xaml__attr_name">Column</span>=<span class="xaml__attr_value">&quot;4&quot;</span>&nbsp;<span class="xaml__attr_name">Margin</span>=<span class="xaml__attr_value">&quot;5&quot;</span>&nbsp;<span class="xaml__attr_name">VerticalAlignment</span>=<span class="xaml__attr_value">&quot;Center&quot;</span>&nbsp;<span class="xaml__tag_start">/&gt;</span>&nbsp;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="xaml__tag_start">&lt;TextBox</span>&nbsp;<span class="xaml__attr_name">Name</span>=<span class="xaml__attr_value">&quot;textBox2&quot;</span>&nbsp;<span class="xaml__attr_name">Text</span>=<span class="xaml__attr_value">&quot;{Binding&nbsp;Path=Rhs}&quot;</span>&nbsp;Grid.<span class="xaml__attr_name">Column</span>=<span class="xaml__attr_value">&quot;2&quot;</span>&nbsp;<span class="xaml__attr_name">MinWidth</span>=<span class="xaml__attr_value">&quot;75&quot;</span>&nbsp;<span class="xaml__attr_name">Margin</span>=<span class="xaml__attr_value">&quot;5&quot;</span>&nbsp;<span class="xaml__tag_start">/&gt;</span>&nbsp;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="xaml__tag_start">&lt;TextBlock</span>&nbsp;Grid.<span class="xaml__attr_name">Column</span>=<span class="xaml__attr_value">&quot;1&quot;</span>&nbsp;<span class="xaml__attr_name">Name</span>=<span class="xaml__attr_value">&quot;textBlock2&quot;</span>&nbsp;<span class="xaml__attr_name">Text</span>=<span class="xaml__attr_value">&quot;&#43;&quot;</span>&nbsp;<span class="xaml__attr_name">Margin</span>=<span class="xaml__attr_value">&quot;5&quot;</span>&nbsp;<span class="xaml__attr_name">VerticalAlignment</span>=<span class="xaml__attr_value">&quot;Center&quot;</span>&nbsp;<span class="xaml__tag_start">/&gt;</span>&nbsp;
&nbsp;&nbsp;&nbsp;&nbsp;<span class="xaml__tag_end">&lt;/Grid&gt;</span>&nbsp;
<span class="xaml__tag_end">&lt;/Window&gt;</span>&nbsp;
&nbsp;
&nbsp;
</pre>
</div>
</div>
</div>
<p>&nbsp;</p>
<h1>まとめ</h1>
<p>F#は、C#やVBに比べて非常に簡潔な記述で多くの事を表現することが出来る言語です。この言語は画面の定義などにも使おうと思えば使えますが、現状ツールのサポートが追い付いていないためMVVMパターンのViewはC#などの既存の言語をベースにしたプロジェクトで作成し、残りのViewModelやModelをF#で記述するという選択肢も作成するアプリケーションの形態によってはありだと思います。</p>
<p>その際に、ちょっとした工夫を行うことで、この記事で示したように簡潔なコードでViewModelを定義することが出来るようになります。&nbsp;</p>
<div class="endscriptcode">&nbsp;</div>
&nbsp;</div>
<p>&nbsp;</p>

</div>


    </div>
</body>
</html>