2011年12月29日

WPF – MVVM (一)

小弟本來是專注於網頁設計,最近被公司抓去寫WPF,所以就開始了新的生涯XDD,而既然講到WPF,就不可能不需要知道MVVM,翻了一些國外文章,寫的還不錯,小弟我就邊看邊把他記錄一下,並分享給大家吧,不過因為MVVM的東西比較多,所以小弟我也會分成好幾篇慢慢地來講解。

What’s MVVM

MVVM當然也是縮寫,也就是Model-View-ViewModel,簡稱MVVM,他也算是一種設計樣式,目的是為了讓各自的相依性降低,這樣以後也比較好維護與測試,而MVVM的意思如下。

  • Model是一個來自服務或資料庫數據的類別。
  • View就是一個顯示的介面,預計是要將資料展現出來。
  • ViewModel就如同膠水般,它把Model和View黏合起來。它將Model包裝起來,而且 ViewModel還會控制View的應用部分,例如在View那邊按下按鈕後,要處理的動作,實際上會放在ViewModel。

而它們之間的關係如下圖般,View也就是XAML,透過Data Binding技術與View Model繫結,但實際上ViewModel是不會知道哪個View繫結了它( ViewModel );而ViewModel與Model的關係也是如此,Model永遠不知道他被哪個ViewModel所參考到,而ViewModel則會參考到Model;換言之,就是View會知道ViewModel,ViewModel會知道Model,這種單向的關係。

image

View與ViewModel

其實如上圖所說,其實View與ViewModel溝通是利用了Binding的技術;我們可以利用下圖更明確的理解,

image

逐步進行(一)

不過我想講了那麼多,還不如實際的一步一步來走走看,我想感覺是比較明顯的,首先,我們先實作一個簡單的MVVM架構試試看,而這個畫面是這次預計的目標,其實滿簡單的,就是會顯示一個文章Title ( 我稱取為PostsTitle ),然後按下按鈕後,會改變Title,雖然這畫面看起來沒啥成就感,但至少我們可以從很簡單的例子看到MVVM。

image

Model

提到MVVM,當然第一步我們要先把Model建立起來,假設這套系統是要處理文章資料的管理 ( 實際上我並不會把它完成,這裡只是假設要建立文章管理系統 ),既然如此,最重要的Model,顧名思義就是文章了,假設我們此類別取名為Posts,並開始撰寫此類別。

以下是Posts Class的程式碼,超級簡單,就兩行,裡面兩個屬性。

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace WPFMVVM
{
    public class Posts
    {
        public string postsText { get; set; }
        public string postsTitle { get; set; }

    }
}

到這邊我們的Model就建置好了,接下來我們要做的是黏合View和Model的ViewModel!

ViewModel

其實也不長,但比較特別的是,ViewModel裡面的屬性會參考到Model,換言之,Model不會知道有那些ViewModel用到他 ( 因為Model裡面並沒有參考到ViewModel. ),然後我們會定義一些方法,讓Model的屬性可以被存取到 ( 例如這邊的PostsTitle方法 )。

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace WPFMVVM
{
    public class PostsViewModel
    {
        public Posts posts{ get; set;}
      
        public PostsViewModel()
        {
            posts = new Posts { postsText = "", postsTitle = "Unknown" };
        }

        public string PostsTitle
        {
            get { return posts.postsTitle; }
            set { posts.postsTitle  = value; }
        } 
    }
}

接下來,我們再來處理View的部分。

View

這個地方比較要注意的是Window標籤裡面,我們必須要定義一個local這個NameSpace,當然這個local你也可以取名其他的名稱,而後面接的就是我們剛剛定義ViewModel的NameSpace,其次就是DataContext標籤裡面,我們直接實例化PostsViewModel出來;最後利用Binding將Label的Content細節至PostsViewModel的PostsTitle。

<Window x:Class="WPFMVVM.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:local="clr-namespace:WPFMVVM"
        Title="MainWindow" Height="350" Width="525">
    <Window.DataContext>
        <!-- 實例化PostViewModel -->
        <local:PostsViewModel />
    </Window.DataContext>
    <Grid>
        <Label  Content="{Binding PostsTitle}"    Height="28" HorizontalAlignment="Left" Margin="12,12,0,0" Name="label1" VerticalAlignment="Top" />
        <Button Content="Button" Height="23" HorizontalAlignment="Left" Margin="145,13,0,0" Name="button1" VerticalAlignment="Top" Width="75" Click="button1_Click" />
    </Grid>
</Window>

這樣就是MVVM!那麼簡單!?,當然不是,這只是簡單的一個Binding而已,但不管怎樣,我們已經看到了Model和ViewModel是如何處理的,也可以清楚的了解了Model、ViewModel與View之間的關係,雖然目前只有利用Binding來將PostsTitle顯示於Label,按下Button也沒啥反應 ( 因為我還沒實作阿XDD ),我們下一篇繼續看下去。

參考資料

8 則留言:

  1. 有所範例檔案下載嗎!?@@

    回覆刪除
  2. 您好,目前我沒有放上範例耶>"<,因為找不到比較適合的地方來放,這部份,未來我會改進,並慢慢補上,也請您多見諒喔。

    回覆刪除
  3. To Industrialist
    謝謝您的讚美,小弟會更加努力的,謝謝!

    回覆刪除
  4. 淺顯易懂 幫助很大 謝謝

    回覆刪除
  5. 我很喜歡你的解說 相當清楚
    但我找不到第二篇 可以請問它的標題嗎?

    回覆刪除
  6. Hi..
    第二篇和第三篇在這邊..
    http://blog.sanc.idv.tw/2011/12/wpf-mvvm_29.html
    http://blog.sanc.idv.tw/2011/12/wpf-mvvm_31.html
    希望對您有幫助~謝謝喔~^^~

    回覆刪除
  7. 您好: 感謝您分享的文章,很有幫助,是否可以引用您的例子,讓我分享在我的部落格

    回覆刪除