[Windows Phone] MVVM Framework: Caliburn.Micro

SONY DSC

在微軟推出 XAML 後,就一直在推行 MVVM,它跟 MVC 的不同除了 Controller 外,就是在 Model 與 View 之間多了一個 View Model。而最近因為工作的關係,接觸到 Caliburn.Micro 這套 Framework。

本篇文章將會介紹如何利用 Caliburn.Micro 建立簡單的 Windows Phone App。首先建立 Windows Phone 8.1 專案後,在 NuGet 上搜尋 Caliburn.Micro 然後安裝它。

專案預設會建立 MainPage.xaml,修改如下:

<Page
    x:Class="CaliburnDemoApp2.MainPage"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    xmlns:local="using:CaliburnDemoApp2"
    xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
    xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
    xmlns:caliburn="using:Caliburn.Micro"
    mc:Ignorable="d"
    Background="{ThemeResource ApplicationPageBackgroundThemeBrush}">

    <Grid>
        <Button x:Name="MyButton" Content="My Button" Margin="140,288,0,295" />
        <TextBlock x:Name="MyTextBlock" HorizontalAlignment="Left" Margin="140,365,0,0" TextWrapping="Wrap" Text="TextBlock" VerticalAlignment="Top" Width="78"/>
    </Grid>
</Page>

除了兩個控制項外,最上面加了一行 Caliburn.Micro 的 namespace,其餘並沒有什麼不同,特別注意的是,兩個控制項一定要有 ID,方便讓之後建立的 View Model 來對應。

接下來建立 MainPageViewModel,在 Caliburn.Micro 的慣例下,View Model 跟 View 的命名只差 “ViewModel”。MainPageViewModel.cs 的程式碼如下:

    public class MainPageViewModel : Screen
    {
        private INavigationService navigationService;
        public MainPageViewModel(INavigationService navigationService)
        {
            this.navigationService = navigationService;

            this.MyTextBlock = DateTime.Now.ToString();
        }

        public string MyTextBlock { get; set; }

        public async void MyButton()
        {
            MessageDialog message = new MessageDialog("My Message");
            await message.ShowAsync();
        }
    }

之前建立的 View中,有兩個控制項分別命名為 MyButton 以及 MyTextBlock,所以在 View Model 中建立 MyTextBlock 這個屬性,以及名稱為 MyButton 的 method,Caliburn.Micro 會自動去對應。

之後打開 App.cs 檔案,做以下的修改,好讓 Caliburn.Micro 能順利運作:

首先修改 OnLaunched:

protected override void OnLaunched(LaunchActivatedEventArgs e)
{
    Initialize();

    var resumed = false;

    if (e.PreviousExecutionState == ApplicationExecutionState.Terminated)
    {
        resumed = _navigationService.ResumeState();
    }

    if (resumed)
    {
        Window.Current.Activate();
        return;
    }

    if (e.PreviousExecutionState != ApplicationExecutionState.Running)
    {
        DisplayRootViewFor<MainPageViewModel>();
    }
}

程式碼的目的在於程式一開始執行時,所要做的狀態判斷,接下來新增 Configure 這個 method:

 protected override void Configure()
 {
     LogManager.GetLog = t => new DebugLog(t);

     _container = new WinRTContainer();
     _container.RegisterWinRTServices();

     // Register your view models at the container
     _container.PerRequest<MainPageViewModel>();

     // We want to use the Frame in OnLaunched so set it up here
     PrepareViewFirst();
 }

這邊是做一些必要的註冊,其中最重要的是 View Model 的註冊及一開始要顯示的頁面,之後呼叫 PrepareViewFirst。

後面是 GetInstance 及 GetAllInstances,程式要取得 View Model,會呼叫 GetInstance。

 protected override object GetInstance(Type service, string key)
 {
     var instance = _container.GetInstance(service, key);
     if (instance != null)
         return instance;

     throw new Exception("Could not locate any instances.");
 }

 protected override IEnumerable<object> GetAllInstances(Type service)
 {
     return _container.GetAllInstances(service);
 }

最後執行程式,結果如下:

2014-12-03_225303

下一篇文章,將會講解 Event 的建立及如何切換頁面。

廣告

發表迴響

在下方填入你的資料或按右方圖示以社群網站登入:

WordPress.com 標誌

您的留言將使用 WordPress.com 帳號。 登出 /  變更 )

Google+ photo

您的留言將使用 Google+ 帳號。 登出 /  變更 )

Twitter picture

您的留言將使用 Twitter 帳號。 登出 /  變更 )

Facebook照片

您的留言將使用 Facebook 帳號。 登出 /  變更 )

連結到 %s