Silverlight-モデルを表示
この章では、Silverlightのソフトウェア開発における重要な手法である View Models。
ザ・ view model は、ビューをモデルから分離することにより、分離プレゼンテーションと呼ばれる手法を導入する重要な部分です。
View Models 個別のプレゼンテーションを実現する一方向を提供し、Silverlightのデータバインディングを活用してユーザーインターフェイスに必要なコードの量を削減する方法を見ていきます。
UI開発の課題
View Modelsユーザーインターフェイスソフトウェアを開発するときに頻繁に発生する特定の問題を解決するように設計されています。おそらく最も重要なのは、特に自動化された単体テストでは、ユーザーインターフェイスコードを密接にテストすることが難しい場合が多いことです。コードの継続的な柔軟性と保守性に影響を与える可能性のあるコード品質の問題もあります。
Visual Studioの設計ツールが導く最小の抵抗の道をたどると、コードビハインドにあまりにも多くのコードを入れてしまう可能性があります。
大量のアプリケーション機能がコードビハインドに追加されるのはよくあることです。
実際にビジネスロジックをユーザーインターフェイスクラスに配置することを計画している開発者はほとんどいませんが、Visual Studioがイベントハンドラーを配置する場所であるため、作業を行うには非常に便利な場所になります。
クラスが明確に定義され、適度に狭い責任を持っている場合、ソフトウェアの開発と保守が容易になることは広く受け入れられています。
背後にあるコードは、必要に応じてユーザーインターフェイスを構成するオブジェクトと直接対話することです。
アプリケーションがそこでどのように動作するかを決定するコードを配置し始めるとすぐに、問題が発生する傾向があります。
アプリケーションロジックは、ユーザーインターフェイスに関係するはずのコードに流れ込むだけでなく、一部の開発者は、重要なアプリケーションの状態を保持するために、コントロールやその他のユーザーインターフェイスオブジェクトに依存し始めます。
モデルは単にデータを保持し、ビューは単にフォーマットされた日付を保持し、コントローラー(ViewModel)は2つの間の連絡役として機能します。コントローラは、ビューから入力を取得してモデルに配置する場合があり、その逆の場合もあります。
個別のプレゼンテーション
コードビハインドまたはXAMLにアプリケーションロジックを配置することによって引き起こされる問題を回避するには、次のような手法を使用するのが最善です。 separated presentation。XAMLとコードビハインドがあり、ユーザーインターフェイスオブジェクトを直接操作するために最低限必要なものがあります。ユーザーインターフェイスクラスには、以下に示すように、複雑な対話動作、アプリケーションロジック、およびその他すべてのコードも含まれています。
分離プレゼンテーションの重要な機能-
個別の表示により、ユーザーインターフェイスクラスははるかに単純になります。もちろんXAMLもありますが、背後にあるコードは実用的ではありません。
アプリケーションロジックは別のクラスに属しており、これはしばしば model。
多くの開発者は、データバインディングを使用して、XAMLの要素をモデルのプロパティに直接接続しようとしています。
問題は model ユーザーがアプリケーションをどのように操作するかではなく、アプリケーションが何をするかという問題に完全に関心があります。
ほとんどのユーザーインターフェイスには、アプリケーションモデルに属さない状態があります。たとえば、ユーザーインターフェースでドラッグアンドドロップを使用する場合、ドラッグされているアイテムが現在どこにあるか、可能なドロップターゲット上を移動するときに外観がどのように変化するか、それらのドロップターゲットがどのように変化するかなどを追跡する必要があります。アイテムがそれらの上にドラッグされると変化します。
この種の状態は驚くほど複雑になる可能性があり、徹底的にテストする必要があります。
実際には、通常、ユーザーインターフェイスとモデルの間に他のクラスを配置する必要があります。これには2つの重要な役割があります。
まず、アプリケーションモデルを特定のユーザーインターフェイスビューに適合させます。
第二に、それは重要な相互作用ロジックが存在する場所です。つまり、ユーザーインターフェイスを希望どおりに動作させるために必要なコードを意味します。
モデル/ビュー/ ViewModel
View Modelは分離されたプレゼンテーションアプローチの例ですが、各レイヤーにどのようなものがあるかを正確に明確にしましょう。3つの層があります-
- Model
- View
- ViewModel
モデル
これは classic ユーザーインターフェイスと直接の関係がない通常のC#クラスで構成されるオブジェクトモデル。
通常、モデルコードは、ユーザーインターフェイスライブラリを参照せずにコンパイルできることが期待されます。実際、まったく同じソースコードを取得して、Silverlightアプリケーション、通常の.NETコンソールアプリケーション、またはサーバー側のWebコードにコンパイルすることもできます。
モデルのタイプは、アプリケーションが機能する概念を表す必要があります。
見る
ビューは通常、UserControlであるか、MainPageであるか、ページの一部である可能性があります。
ほとんどのSilverlightアプリケーションでは、ユーザーインターフェイスを小さな部分に分割して、UserControlまたは各部分のビューを定義することをお勧めします。
Silverlightアプリケーションは、この点でユニークではありません。明らかにSilverlight固有のものは、ビューです。ユーザーインターフェイスがきめ細かくなればなるほど、物事は良くなる傾向があります。同じファイルで作業している他の開発者につまずく可能性が低いだけでなく、物事を小さくシンプルに保つことで、スパゲッティのようなコードにつながるショートカットを自然に思いとどまらせます。
たとえば、を定義することは非常に一般的です View リスト内の個々のアイテムを表します。
ViewModel
最後に、それぞれについて View、あなたは書く ViewModel。だから、これはの重要な機能の1つですViewModel クラス。
特定のビューを提供するために存在します。ザ・ViewModel リストに表示される特定のデータ項目など、物事を表示する特定の方法に特化しています。
これがそれが呼ばれる理由です ViewModel; 特に特定のビューに対して、基礎となるモデルを適合させます。モデルのように、ViewModelまた、通常のC#クラスです。特定のタイプから派生する必要はありません。
たまたま、一部の開発者は、いくつかの一般的な機能を基本のViewModelクラスに入れると便利だと感じていますが、パターンはそれを要求していません。特に、あなたのViewModelSilverlight固有のタイプから派生したものではありません。ただし、モデルとは異なり、プロパティでSilverlightタイプを使用できます。
たとえば、ViewModelは、ユーザーインターフェイスの特定の部分を特定の条件下でのみ表示することを選択する場合があるため、Silverlight要素がVisibilityプロパティに使用するタイプであるSystem.Windows.Visibilityタイプのプロパティを提供する場合があります。これにより、パネルなどの要素の可視性をViewModelに直接バインドできます。
例
使用する簡単な例を見てみましょう Model-View-ViewModel (MVVM) アプローチ。
Step 1 −新しいSilverlightアプリケーションプロジェクトを作成する SilverlightMVVMDemo。
Step 2 −以下に示すように、3つのフォルダー(Model、ViewModel、およびViews)をプロジェクトに追加します。
Step 3 − ModelフォルダーにStudentModelクラスを追加し、そのクラスに以下のコードを貼り付けます。
using System.ComponentModel;
namespace SilverlightMVVMDemo.Model {
public class StudentModel {}
public class Student : INotifyPropertyChanged {
private string firstName;
private string lastName;
public string FirstName {
get { return firstName; }
set {
if (firstName != value) {
firstName = value;
RaisePropertyChanged("FirstName");
RaisePropertyChanged("FullName");
}
}
}
public string LastName {
get { return lastName; }
set {
if (lastName != value) {
lastName = value;
RaisePropertyChanged("LastName");
RaisePropertyChanged("FullName");
}
}
}
public string FullName {
get {
return firstName + " " + lastName;
}
}
public event PropertyChangedEventHandler PropertyChanged;
private void RaisePropertyChanged(string property) {
if (PropertyChanged != null) {
PropertyChanged(this, new PropertyChangedEventArgs(property));
}
}
}
}
Step 4 −別のStudentViewModelクラスをViewModelフォルダーに追加し、次のコードを貼り付けます。
using SilverlightMVVMDemo.Model;
using System.Collections.ObjectModel;
namespace SilverlightMVVMDemo.ViewModel {
public class StudentViewModel {
public ObservableCollection<Student> Students {
get;
set;
}
public void LoadStudents() {
ObservableCollection<Student> students = new ObservableCollection<Student>();
students.Add(new Student { FirstName = "Mark", LastName = "Allain" });
students.Add(new Student { FirstName = "Allen", LastName = "Brown" });
students.Add(new Student { FirstName = "Linda", LastName = "Hamerski" });
Students = students;
}
}
}
Step 5 −追加 Silverlight User Control 右クリックして Views フォルダと選択 Add New Item…。
Step 6− [追加]をクリックします。これで、XAMLファイルが表示されます。次のコードをに追加しますStudentView.xaml さまざまなUI要素を含むファイル。
<UserControl x:Class = "SilverlightMVVMDemo.Views.StudentView"
xmlns = "http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x = "http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:d = "http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc = "http://schemas.openxmlformats.org/markup-compatibility/2006"
mc:Ignorable = "d"
d:DesignHeight = "300" d:DesignWidth = "400">
<Grid x:Name = "LayoutRoot" Background = "White">
<StackPanel HorizontalAlignment = "Left">
<ItemsControl ItemsSource = "{Binding Path=Students}">
<ItemsControl.ItemTemplate>
<DataTemplate>
<StackPanel Orientation = "Horizontal">
<TextBox Text = "{Binding Path = FirstName, Mode = TwoWay}"
Width = "100" Margin = "3 5 3 5"/>
<TextBox Text = "{Binding Path = LastName, Mode = TwoWay}"
Width = "100" Margin = "0 5 3 5"/>
<TextBlock Text = "{Binding Path = FullName, Mode=OneWay}"
Margin = "0 5 3 5"/>
</StackPanel>
</DataTemplate>
</ItemsControl.ItemTemplate>
</ItemsControl>
</StackPanel>
</Grid>
</UserControl>
Step 7 −ここで、 StudentView あなたに MainPage.xaml 以下に示すようにファイルします。
<UserControl x:Class = "SilverlightMVVMDemo.MainPage"
xmlns = "http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x = "http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:d = "http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc = "http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:views = "clr-namespace:SilverlightMVVMDemo.Views"
mc:Ignorable = "d"
d:DesignHeight = "576.316" d:DesignWidth = "863.158">
<Grid x:Name = "LayoutRoot" Background = "White">
<views:StudentView x:Name = "StudentViewControl" Loaded = "StudentViewControl_Loaded"/>
</Grid>
</UserControl>
Step 8 −これがの実装です Loaded のイベント MainPage.xaml.cs ファイル、更新します View から ViewModel。
using System.Windows;
using System.Windows.Controls;
namespace SilverlightMVVMDemo {
public partial class MainPage : UserControl {
public MainPage() {
InitializeComponent();
}
}
private void StudentViewControl_Loaded(object sender, RoutedEventArgs e) {
SilverlightMVVMDemo.ViewModel.StudentViewModel
studentViewModelObject = new SilverlightMVVMDemo.ViewModel.
StudentViewModel();
studentViewModelObject.LoadStudents();
StudentViewControl.DataContext = studentViewModelObject;
}
}
Step 9 −上記のコードをコンパイルして実行すると、Webページに次の出力が表示されます。
UIとViewModel
MVVMアプローチの最も難しい部分の1つは、境界線がどこに来るかを検討することです。どの物がどこに属しているかは必ずしも明らかではありません。
特に、一部のユーザーインターフェイス要素は機能を提供します。これは、厳密なビューによれば、間違いなくViewModelに属する必要があります。
一般に、で実装されているすべての動作が View そうです ViewModel フレンドリー。
この理由の一部は、ViewModelの動作を再利用するためにパッケージ化する標準的な方法がないことです。特に、VisualStudioやBlendなどのデザイン環境を使用する場合はそうではありません。
MVVMの利点
MVVMには次の利点があります-
プレゼンテーションの懸念事項の分離(View、ViewModel、Model)
テスト可能で管理しやすいコードをクリーンアップします。単体テストにプレゼンテーション層ロジックを含めることができます。
コードの背後にコードがないため、プレゼンテーション層とロジックは疎結合されています。
データバインディングのより良い方法。
MVVMのデメリット
単純なUIの場合、MVVMはやり過ぎになる可能性があります。複雑なデータバインディングがある場合、デバッグは少し難しいでしょう。