在微軟推出 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); }
最後執行程式,結果如下:
下一篇文章,將會講解 Event 的建立及如何切換頁面。