本文章是由機器翻譯。

MVVM

在 Windows 8 中使用 MVVM 模式

Laurent· Bugnion

下載代碼示例

與以往的經驗,在任何基於 XAML 的框架中的任何程式師可能已經至少聽到的模型-視圖-ViewModel (MVVM) 模式。一些一直使用它廣泛地在所有 Windows 演示文稿基金會 (WPF)、 Silverlight 或 Windows Phone 應用程式。他人避開它,是因為他們誤解模式做什麼,確切地說,或是因為他們不想添加他們視為對其應用程式的複雜性的一個新的水準。

您不必使用 MVVM 模式構建基於 XAML 的應用程式。它是絕對可以使用基於事件的交互等傳統模式來創建令人信服的應用程式。然而,解耦的模式,如 MVVM 帶來不少優勢。值得注意的是,MVVM 模式可以極大地提高表達混合中的經驗和便利設計器-­開發工作流程。

最近 — — 特別是與新的平臺,如 Windows Phone 和當然,Windows 8 的 XAML 的擴展 — — MVVM 的使用已經到全新的水準,從只有幾個愛好者程式師使用,鼓勵由 Microsoft 的主流做法利基模式。

前提條件

本文演示如何使用 MVVM 和 MVVM 光工具組,開放原始碼工具組,方便了基於 XAML 的應用程式中的常見操作模式。為了貫徹例子,Visual Studio 2012 需要,以及 MVVM 光工具組的最新版本。請注意您可以使用 Visual Studio 2012 年速成版,是為免費提供。當然,也可以使用任何其他版本。

可以從下載 visual Studio 2012 bit.ly/vs12rc (極限、 溢價或專業版)。可以從下載免費的速成版 bit.ly/vs12express

MVVM 光工具組安裝程式可以從下載部分下載 mvvmlight.codeplex.com。後安裝 MSI,打開讀我檔案的頁面,您可以選擇安裝專案和項範本為您正在使用的 Visual Studio 的版本。

在 Windows 8 的 MVVM 模式

Windows 8 依賴于一套新的名為 Windows 運行庫 (WinRT) 的 Api。編寫應用程式運行在 Windows 運行時有三種方式 (有時稱為"推算")。

第一種方法是最直觀的 WPF、 Silverlight 或 Windows Phone 等其他基於 XAML 的框架的技能的人。它使用 XAML 作為前端,和 C# 或 Visual Basic 為其邏輯。雖然有幾個差異 Silverlight 和 WinRT XAML / C# / Visual Basic 投影、 技能和大多數概念是相同的。事實上,MVVM 是該預測,選擇的模式為這些舊框架相同的原因。

第二,熟悉 HTML 和 JavaScript 開發人員還可以編寫代碼 Windows 存儲應用程式的基於 HTML 的投影。與 MVVM 在 XAML 中的日益普及,HTML 開發商想太在 HTML/JavaScript 中使用資料繫結。然而,由於缺乏資料繫結機制,是必須從頭開始,並重新創建此功能。這是什麼框架,如 knockout.js (knockoutjs.com) 在做。這種 MVVM 框架也可以用於發展中國家的 Windows 存儲應用程式。

也是可以使用 microsoft 稱為 WinJS 的專有技術框架。WinJS (如 GridView、 SemanticZoom 等) 中的控制項類似于在 XAML 中,並支援資料繫結太。有關 WinJS 的詳細資訊,請參閱 bit.ly/winjsbinding。詳述了 JavaScript 的更多資料繫結框架 bit.ly/jsbinding

專案希洛 (c + + 和 XAML)

第三 WinRT 投影使用 XAML 前端和非託管 c + + (未經 Microsoft.NET 框架) 作為其邏輯。希洛 (bit.ly/hilocode) 是從 Microsoft 模式的示例專案 & 旨在表明與 c + + 和 XAML 創建 Windows 應用程式商店的各個方面的做法。

由於 XAML 和資料繫結的可用性,可以使用非託管 c + + 使用 MVVM 模式。希洛演示如何使用 MVVM 在 c + +,如 c + + ; 非同步程式設計等議題 使用瓷磚 ; 頁面導航 ; 使用觸摸 ; 處理啟動、 掛起和恢復 ; 創建高級-­性能的經驗 ; 測試該應用程式 ; 和認證。

希洛附帶了完整的原始程式碼和完整的文檔。它是一個很好的案例研究,為傳統 c + + 開發人員想要在 Windows 8 中開始使用現代發展模式,以及 C# / 視覺的基本開發人員希望使用 c + + 堆疊的額外性能。

關於 MVVM 的提醒

MVVM 模式是命名的模型-視圖-控制器或 MVC 的另一個著名的分離模式的變體。微軟的情況下大量的框架,特別是廣泛使用 Ruby on Rails Web 應用程式框架,以及 ASP.NET MVC 中使用此模式。不只是在 Web 應用程式,但還廣泛使用它從桌面應用程式到手機應用程式 (在 iOS,例如)。

分離模式的主要優點是它分配給每個圖層的明確的責任。模型是資料來自何處 ; 視圖為使用者顯示的內容和他的驅動。如的控制器,它有點像樂團的主任和協調的行動和反應的應用程式。例如,控制器通常是負責協調的操作,如資料顯示在回應使用者輸入、 啟動和停止動畫和等等。

與這些明確的職責,開發團隊的成員可以專注的每一部分,沒有踏上彼此的腳趾。同樣,交互設計師不必擔心創造或持久性資料,等等。

關注點分離好後果是分離應用程式也是容易測試。例如,模型的類可以是單元測試而無需考慮的看法。因為模型和視圖之間的相互作用清楚地定義並由控制器協調,有可能以嘲笑,或類比,一些互動在需要創建一致的測試條件。這就是為什麼可測性經常提到作為 XAML 基於應用程式中使用的 MVVM 模式的優點之一。

從 MVVM 到 MVC

儘管 MVC 模式具有明顯的優勢,為許多框架,它不是最適合基於 XAML 的框架,由於 (或由於到) 資料繫結系統。這個強大的基礎架構可以不同的物件的屬性綁定,並使它們保持同步。雖然這聽起來像是一個簡單的功績,影響是巨大的:通過讓照顧此同步的資料繫結系統,開發人員可以集中精力計算資料物件屬性的值,而不必擔心更新使用者介面。

此外,綁定是鬆散耦合。綁定只計算需求,和應用程式不會打破如果綁定的結果是不正確。因為它很難找到為什麼某些綁定不計算正確這"鬆動"有時會給開發商帶來的麻煩。但是,它是一個可以更容易在使用者介面上沒有正在緊密耦合到一個資料結構的情況下工作的優勢。用鬆散綁定,卻很容易在視圖上移動使用者介面元素,甚至完全沒有觸及下層圖層更改應用程式的外觀和感覺。

為了方便的資料繫結,並避免非常大的物件,控制器在較小的、 精幹的物件稱為 ViewModels 或演示文稿模型細分。常見的用法是將 ViewModel 設置為該視圖的 DataCoNtext 配對模型的視圖。在實踐中,但是,這並不總是如此 ; 它並不少見,有與給定模型相關聯的多個視圖或有一個複雜的視圖拆分中多個 ViewModels。

由於要生成 UI XAML 用法,可以聲明性的方式,直接在 XAML 文檔正文中表示資料繫結。這允許分離的過程中,在開發人員擔心有關模型和模型,雖然是交互設計師接管 UX 建立在相同的時間,或甚至在稍後的時間。

最後,因為 XAML 是基於 XML 的它工作好用 Expression Blend 視覺化檢視。當配置正確,MVVM,使能夠直觀顯示在螢幕上,允許設計器工作 UX,而不必運行應用程式,如中所示的設計時資料圖 1

Expression Blend for Windows Store Apps with Design-Time Data**

圖 1 表達混合的設計時資料的 Windows 存儲程式**

MVVM 輕型工具組

MVVM 模式的一個缺點是一些所需的代碼是什麼有時稱為"樣板代碼"— — 基礎結構代碼,並不直接執行的函數,但所需的內部"管道"工作。樣板代碼的最佳例子也許是需要使屬性可觀測與 INotifyPropertyChanged 介面實現和其 PropertyChanged 事件,如中所示的代碼圖 2。此代碼演示不能使用自動屬性 (與 getter 和二傳手沒有身體的屬性)。相反,該屬性具有支援欄位。檢查,setter,以避免常常引發 PropertyChanged 事件。然後,如果該屬性值不會更改,就會有 PropertyChanged 事件引發。

圖 2 可觀察到屬性

private string _firstName;
public string FirstName
{
  get
  {
    return _firstName;
  }
  set
  {
    if (_firstName == value)
    {
      return;
    }
    _firstName = value;
    var handler = PropertyChanged;
    if (handler != null)
    {
      handler(this, new PropertyChangedEventArgs("FirstName"));
    }
  }
}

當然,這是最壞的情況,每個物件的屬性需要約 20 行代碼的位置。此外,"魔術弦"用於標識該屬性的名稱,它可能會導致問題,如果有一個錯字。為解決此問題,MVVM 光提出幾個解決辦法:

  • 提高 PropertyChanged 事件所需的邏輯可以存儲在每個模型繼承自的 ViewModelBase 類。
  • 屬性可以確定由 lambda 運算式而不是字串。這可以防止輸入錯誤的屬性的名稱更改時。
  • 使用 Visual Studio 中的程式碼片段,可以自動的剩餘行。

MVVM 光有不少有用塑造的分離應用程式更快和更容易,您將看到在應用程式範例中提出進一步在這篇文章中的元件。

Windows 8 還引入了一對夫婦的新類,以説明解決這個問題,如 BindableBase 類和 CallerMember­Name 屬性。不幸的是,這些不能用於其他基於 XAML 的框架,不能在共用代碼中使用。

在 Windows 8 中創建新的應用程式

最簡單的方法來創建新的應用程式是要啟動 Visual Studio 12,並選擇 MvvmLight (Win8) 專案範本。在創建應用程式之後,就可以通過按 Ctrl + F5 立即啟動它。主頁面是最小的並只顯示"歡迎到 MVVM 輕",如中所示圖 3

Creating the New MVVM Light Application
創建新的 MVVM 輕應用的圖 3**

更有趣的在 Visual Studio 設計器中打開相同的應用程式:在解決方案資源管理器中,按右鍵 MainPage.xaml,選擇視圖設計器。第一次載入視覺效果需要一定的時間,但一旦準備就緒,螢幕顯示"歡迎來到 MVVM 光 [設計]。"在表達混合中打開該應用程式還會顯示相同的結果:相同的檔上按一下滑鼠右鍵並選擇打開中查看視窗中的設計時文本的混合。注意 Windows 存儲區的表達混合應用程式安裝與 Visual Studio 2012 (甚至速成版)。隨著 Windows Phone 之前,現在是可以免費使用運算式混合。

剛剛發生什麼事了一些有趣的影響:可視設計器中運行該應用程式的部分,有一種方法來找出是否在或不在設計器中運行該應用程式。在運行時看到比可視設計器中的不同視圖是很好的體驗過程交互設計關鍵要求。這將允許繞過 Web 服務調用或在設計時就不會工作的資料庫連接。它還允許創建知名的資料 — — 例如,非常長的文本,以驗證如何佈局看起來在不同的方向或決議而不必運行應用程式。這在交互設計階段節省時間和很多的麻煩。

正在開發的應用程式是一個檢視器使用者的朋友,連接到 Web 服務 (但很大程度簡化) Facebook 的鼓舞。Web 服務返回的資訊使用者的第一次這樣的朋友的 JSON 格式字串和最後名稱的設定檔的圖片的 URI 出生日期等。此資訊存儲在朋友已模型層 (第一個"M"在 MVVM) 中創建類型的實例。朋友類繼承 (通過新的應用程式引用) 的 MVVM 光圖書館提供的 ObservableObject 類。這允許朋友類容易引發 PropertyChanged 事件。請注意這是有道理,即使屬於模型層的朋友 — — 它允許的使用者介面,以將資料繫結到朋友的屬性而不必重複這些模型層中的屬性。

正如我剛才所說,實現可觀察到的屬性需要一些樣板代碼,這是令人討厭,但減輕 MVVM 光:使用代碼片斷添加 INPC 屬性 (對於 INotifyPropertyChanged,定義的 PropertyChanged 事件的介面)。只需鍵入 mvvminpcset,然後選項卡以展開程式碼片段。若要跳轉到欄位的使用選項卡:輸入屬性的名稱 (名字),其類型 (字串),支援欄位名稱 (_firstName) 和最後,預設值 (字串。空)。然後鍵入按 Esc 鍵結束代碼段編輯模式。此外,在程式碼片段中添加該屬性的名稱的常量。後來我們註冊到 PropertyChanged 事件時,這將非常有用。

所有的 MVVM 光段開頭的 mvvm,可以方便地在智慧感知中找到它們。有幾個 mvvminpc 片段,變化的屬性的實現。使用 mvvminpcset,您還可以實現可觀察到的屬性命名為字串類型的姓氏。

屬性,如名字和姓氏是相當簡單的。有時,不過,這款應用程式獲取來自 Web 服務的資料格式不是最優的和轉換需要考慮的地方。在傳統的基於 XAML 的發展,開發人員有時使用轉換器 (IValueConverter 執行)。在 MVVM,但是,大多數轉換器可以替換的簡單屬性。例如,讓我們考慮出生的日期。JSON 欄位是"MM/DD/YYYY,"這是美國的格式表示日期的方式。但是,應用程式可能運行在任何地區設定,所以需要進行轉換。

讓我們開始通過添加字串類型,名為 DateOfBirthString,使用相同的程式碼片段 mvvminpcset 以前可觀察到屬性。然後,添加另一個屬性,如下所示 (此屬性使用 DateOfBirthString 作為支援欄位 ; 它負責將值轉換為正確的日期時間值):

public DateTime DateOfBirth
{
  get
  {
    if (string.IsNullOrEmpty(_dateOfBirthString))
    {
      return DateTime.MinValue;
    }
    return DateTime.ParseExact(DateOfBirthString, "d",
      CultureInfo.InvariantCulture);
  }
  set
  {
    _dateOfBirthString = value.ToString("d",
      CultureInfo.InvariantCulture);
  }
}

雖然,還有一件事被需要:每當 DateOfBirthString 變化,PropertyChanged 事件需要太提高為 DateOfBirth。 這種方式,資料繫結將重新查詢值和部隊再次進行轉換。 要執行此操作,請修改 DateOfBirthString 屬性 setter,如下面的代碼所示:

set
{
  if (Set(DateOfBirthStringPropertyName, 
    ref _dateOfBirthString, value))
  {
    RaisePropertyChanged(() => DateOfBirth);
  }
}

MVVM 光 ObservableObject 設置方法返回 true,如果更改的值。 這是在暗示太引發的 DateOfBirth 屬性的 PropertyChanged 事件 ! 此轉換機制是非常方便的。 應用程式範例使用它在幾個地方,如將轉換設定檔圖片 URL (作為字串保存) 一個 URI,例如。

實施和嘲諷的資料服務

這款應用程式已經有簡單的 dataservice 中可重用連接到實際的資料服務。 Web 服務是一個簡單的.NET HTTP 處理常式返回 JSON 格式的檔。 由於.NET 框架 4.5 (等待非同步/關鍵字) 仲介紹的非同步程式設計模式的用法,連接到 Web 服務是很簡單,作為放映中圖 4 (與 IDataService 介面)。 連接發生以非同步方式,SendAsync 方法名稱所示。 但是,由於等待關鍵字,該方法不需要會使代碼更複雜的回檔。

圖 4 連接到 Web 服務和反序列化的 JSON 結果

public interface IDataService
{
  Task<IList<Friend>> GetFriends();
}
public class DataService : IDataService
{
  private const string ServiceUrl
    = "http://www.galasoft.ch/labs/json/JsonDemo.ashx";
  private readonly HttpClient _client;
  public DataService()
  {
    _client = new HttpClient();
  }
  public async Task<IList<Friend>> GetFriends()
  {
    var request = new HttpRequestMessage(
      HttpMethod.Post,
      new Uri(ServiceUrl));
    var response = await _client.SendAsync(request);
    var result = await response.Content.ReadAsStringAsync();
    var serializer = new JsonSerializer();
    var deserialized = serializer.Deserialize<FacebookResult>(result);
    return deserialized.Friends;
  }
}

最後,在檢索 JSON 字串後,JSON 序列化程式用於到類型 FacebookResult.NET 物件反序列化該字串。 此類是一個説明器,該方法返回後將被丟棄。

MVVM 光還包括一個簡單的控制反演 (國際奧會) 容器調用 SimpleIoc。 IOC 容器是一個元件,不只在 MVVM 應用程式非常有用,但任何脫鉤的體系結構。 IOC 容器就像快取記憶體實例,可以創建需求,並解決在不同應用程式中的位置。

Dataservice 中實現 IDataService 介面。 由於國際奧會容器中,很容易類比資料服務和創建設計器中的設計時資料。 如中所示,此類稱為 DesignDataService, 圖 5

圖 5 設計時資料服務

public class DesignDataService : IDataService
{
  public async Task<IList<Friend>> GetFriends()
  {
    var result = new List<Friend>();
    for (var index = 0; index < 42; index++)
    {
      result.Add(
        new Friend
        {
          DateOfBirth = (DateTime.Now - TimeSpan.FromDays(index)),
          FirstName = "FirstName" + index,
          LastName = "LastName" + index,
          ImageUrl = "http://www.galasoft.ch/images/el20110730009_150x150.jpg"
        });
    }
    return result;
  }
}

註冊和調用服務

現在,實施服務,它是它們進行具現化並創建 ViewModels 的時間。 這是 ViewModelLocator 類任務。 此類是由 MVVM 光啟用的應用程式結構中相當重要的。 它是作為 XAML 資源 App.xaml 檔中創建的。 這將創建 XAML 標記和原始程式碼的代碼,使視覺化設計器創建 ViewModels,並運行設計階段代碼之間的重要聯繫。 登記所示圖 6

圖 6 註冊的服務和 ViewModels

static ViewModelLocator()
{
  ServiceLocator.SetLocatorProvider(() => SimpleIoc.Default);
  if (ViewModelBase.IsInDesignModeStatic)
  {
    SimpleIoc.Default.Register<IDataService, 
      Design.DesignDataService>();
    SimpleIoc.Default.Register<INavigationService,
      Design.DesignNavigationService>();
  }
  else
  {
    SimpleIoc.Default.Register<IDataService, DataService>();
    SimpleIoc.Default.Register<INavigationService>(() => 
      new NavigationService());
  }
  SimpleIoc.Default.Register<MainViewModel>();
}

由於 MainViewModel 建構函式將 IDataService 和 INavigationService 作為參數,可以自動創建的所有物件的 SimpleIoc 容器。 MainViewModel 的 ViewModelLocator 和在 XAML 中的資料繫結到首頁的 DataCoNtext 的屬性公開。 此綁定已經在 MVVM 光專案範本中創建。 當在運算式混合打開的網頁時,資料繫結是解決、 MainViewModel 實例創建 (如果需要) 和建構函式使用 dataservice (運行時或設計階段) 中正確的實例運行。

調用資料服務的行動暴露與中繼­中所示的命令圖 7。 此類是 MVVM 光工具組,實現 ICommand 介面,並提供,可以方便地將使用者介面元素 (如按鈕) 的命令屬性綁定到在模型上執行的方法的一個組成部分。

圖 7 RelayCommand 類

private RelayCommand _refreshCommand;
public RelayCommand RefreshCommand
{
  get
  {
    return _refreshCommand
      ??
(_refreshCommand = 
      new RelayCommand(ExecuteRefreshCommand));
  }
}
private async void ExecuteRefreshCommand()
{
  var friends = await _dataService.GetFriends();
  if (friends != null)
  {
    Friends.Clear();
    foreach (var friend in friends)
    {
      Friends.Add(new FriendViewModel(friend, _schema));
    }
  }
}

朋友添加到其中的朋友集合是類型的 ObservableCollection <FriendViewModel>。此集合類型通常用於基於 XAML 的框架,,因為任何清單控制項的資料繫結到此類集合自動更新其視圖內容更改時。而不是直接存儲到集合中的模型的朋友類的實例,他們被包裹成另一類稱為 FriendViewModel 的模型層。這允許在模型中添加特定視圖的屬性不會長期存在。例如,FriendViewModel 類公開一個名為 FullName 屬性。根據應用程式的設置,它可以返回的字串格式"名字、 姓氏"或"姓氏,名字。"這種邏輯是典型從模型的類,不應存儲在應用程式的較低層。

為了 FullName 屬性返回正確的格式,FriendViewModel 聽訊息類型 ChangeFullName­SchemaMessage。這是由於 MVVM,將寄件者和收件者一系列連接而無需創建它們之間強有力的連接鬆散耦合的事件匯流排的信使元件。請注意使者可以發送任何訊息類型,從簡單的值,如 int 到複雜物件的附加資訊。

當收到這樣一條消息時,PropertyChanged 事件引發 FullName 屬性。FriendViewModel 類示圖 8

圖 8 FriendViewModel 類

public class FriendViewModel : ViewModelBase
{
  private FullNameSchema _schema = FullNameSchema.FirstLast;
  public Friend Model
  {
    get;
    private set;
  }
  public FriendViewModel(Friend model, FullNameSchema schema)
  {
    Model = model;
    Model.PropertyChanged += (s, e) =>
    {
      if (e.PropertyName == Friend.FirstNamePropertyName
          || e.PropertyName == Friend.LastNamePropertyName)
      {
        RaisePropertyChanged(() => FullName);
        return;
      }
      if (e.PropertyName == Friend.DateOfBirthPropertyName)
      {
        RaisePropertyChanged(() => DateOfBirthFormatted);
      }
    };
    Messenger.Default.Register<ChangeFullNameSchemaMessage>(
      this,
      msg =>
      {
        _schema = msg.Schema;
        RaisePropertyChanged(() => FullName);
      });
  }
  public string DateOfBirthFormatted
  {
    get
    {
      return Model.DateOfBirth.ToString("d");
    }
  }
  public string FullName
  {
    get
    {
      switch (_schema)
      {
        case FullNameSchema.LastFirstComma:
          return string.Format(
            "{0}, {1}",
            Model.LastName, Model.FirstName);
        default:
          return string.Format(
            "{0} {1}",
            Model.FirstName, Model.LastName);
      }
    }
  }
}

指令從"名字、 姓氏"切換到"姓氏,名字"發送的 MainViewModel 中,如下所示:

private void SetSchema(FullNameSchema schema)
{
  _schema = schema;
  Messenger.Default.Send(new 
    ChangeFullNameSchemaMessage(_schema));
}

由於所經營的信使類的分離方式,會很容易地將其從 MainViewModel ; 移動 到後來的時候,例如設置類。

設置導航

它從視圖的代碼隱藏,由於導航啟動時,將很容易在 Windows 8 的頁面之間的導航­服務的每個頁面公開的屬性。 不過,為了從模型導航,被需要一點點的安裝程式。 它是很容易,因為負責導航的幀暴露以靜態方式作為 ((Frame)Window.Current.Content)。 應用程式可以公開獨立導航服務:

public class NavigationService : INavigationService
{
  public void Navigate(Type sourcePageType)
  {
    ((Frame)Window.Current.Content).Navigate(sourcePageType);
  }
  public void Navigate(Type sourcePageType, object parameter)
  {
    ((Frame)Window.Current.Content).Navigate(sourcePageType, parameter);
  }
  public void GoBack()
  {
    ((Frame)Window.Current.Content).GoBack();
  }
}

中的代碼圖 8 演示如何使用 SimpleIoc 容器註冊的導航服務。 它注入為 MainViewModel 建構函式中的參數,並可用於方便地直接從模型層啟動使用者介面導航。

在 MainViewModel,啟動了導覽屬性調用 SelectedFriend 時的更改。 此屬性是可觀察到的屬性,就像別人早些時候建立了。 此屬性將被綁定到資料在使用者介面中,所以導航由使用者的操作。 要顯示的朋友,請使用 GridView,並且它是資料繫結到朋友集合在 MainViewModel 上。 因為此模型設置為首頁 DataCoNtext 中,綁定易於創建,如下所示:

<GridView
  ItemsSource="{Binding Friends}"
  ItemTemplate="{StaticResource FriendTemplate}"
  SelectedItem="{Binding SelectedFriend, Mode=TwoWay}"/>

GridView SelectedItem 屬性和 MainViewModel SelectedFriend 屬性中所列之間創建另一個雙向綁定圖 9

圖 9 MainViewModel SelectedFriend 屬性

public const string 
  SelectedFriendPropertyName = "SelectedFriend";
private FriendViewModel _selectedFriend;
public FriendViewModel SelectedFriend
{
  get
  {
    return _selectedFriend;
  }
  set
  {
    if (Set(SelectedFriendPropertyName, 
      ref _selectedFriend, value)
        && value != null)
    {
      _navigationService.Navigate(typeof (FriendView));
    }
  }
}

最後,導航導致使用者詳細資訊頁為所選的朋友。在此頁中,DataCoNtext 是綁定到 MainViewModel SelectedFriend 屬性。這,再次,確保良好的設計時體驗。當然,在設計時 RefreshCommand 的執行時 MainViewModel 構造,並將 SelectedFriend 屬性設置:

#if DEBUG
private void CreateDesignTimeData()
{
  if (IsInDesignMode)
  {
    RefreshCommand.Execute(null);
    SelectedFriend = Friends[0];
  }
}
#endif

在這一點上,可以在運算式混合設計 UX。因為設計時代碼運行,混合顯示所有 gridview 的設計時朋友添加到首頁,如中所示圖 1。當然,創建資料範本需要花費一些時間和技能,但它可以很容易實現以直觀的方式而無需運行該應用程式。

總結

所有這一切都似乎是相當熟悉的開發人員熟悉 WPF、 Silverlight 或 Windows Phone 的 MVVM 模式。這是因為事情類似與 Windows 運行時。在這些以前的框架中獲得的技能是很容易轉移到 Windows 存儲應用程式開發。當然,一些概念 (如與等待非同步/非同步程式設計) 是新的並將代碼轉換為 Windows 運行時所需的一些工作。但 MVVM 模式和傭工例如 MVVM 光工具組,開發人員得到良好的開端,並能充分享受解耦的應用模式的優點。

Laurent · Bugnion IdentityMine inc.,Microsoft 合作夥伴與 Windows 的演示文稿基金會、 Silverlight、 表面、 Windows 8、 Windows Phone 和體驗等技術工作的高級總監他設在瑞士蘇黎世的。

由於下面的技術專家對本文的審閱:Karl Erickson 和 Rohit Sharma