MVVM part 3 – First Real App
כאמור, הצגנו את הרעיון של MVVM בחלק א (מבוא) ובחלק ב’ בנינו command
עכשיו הגיע הזמן לבנות תכנית קטנה שנציגה איך עובדים עם התבנית.
ראשית נפתח תכנית חדשה בVisual Studio מסוג WPF ונוסיף שני קלאסים. אחד ייקרא Model והשני MainViewModel כמובן שהמודל יכול להיות
באסמבלי חיצוני, אבל בשביל הדוגמא זה לא רלוונטי.
אנחנו נצטרך להשתמש בCommand שבניתי
בפוסט הקודם או בכל
אחד מוכן אחר, אז תכינו לכם אחד כזה
או שתורידו אחר מהרשת, ותצרפו גם אותו לפרוייקט (שוב , גם הוא יכול
לשבת בספרייה חיצונית).
התכנית צריכה להכיל: א. את פרוייקט המקור של WPF
כמו
שהוא נפתח עם Main Window,
ב. קלאס מודל שנשים בתוכו פרופרטי אחד או יותר, ג. קלאס View Model וקלאס Command.
כדי שהתכנית תעבוד יפה נוסיף לקלאס הViewModel רפרנס לספריית System.ComponentModel
ונקבע שהקלאס מממש את INotifyPropertyChanged וזה ייראה כך עם הevent שלו.
public class MainViewModel:INotifyPropertyChanged
{
public event PropertyChangedEventHandler PropertyChanged;
}
בדוגמא שלי קבעתי שהמודל הוא בס”ה רשימה של אותיות ואני רוצה
לעדכן אותו מהView וכמובן לצפות בו.
מבחינתי זה מודל ושכבת DAL גם יחד. המודל נראה כך
כשהתכנית עולה:
namespace MVVM_Demo
{
public class Model
{
public List<string> Data = new List<string>{ “a”, “b”, “c” };
}
}
ונחזור לView – ViewModel. כדי שהView יכיר את הViewModel שלו, אנחנו צריכים להגיד
לו מי הDataContext שלו, שבלי להרחיב יותר
מדי זה אומר מי הcode behind של הView, עם מי הView ידבר במהלך חיי התכנית,
כל מה שנכתוב בViewModel יהיה רלוונטי לView שלו.
ישנם המון שיטות איך ואיפה למקם את
הDatacontext של הView ואני אשתמש בדרך הכי פשוטה וברורה כרגע.
פשוט נפנה ל codeBehind של הMain windowונוסיף שם את השורה הבאה כך שזה המראה החדש שלו :
public partial class MainWindow : Window
{
public MainWindow()
{
InitializeComponent();
DataContext = new MainViewModel();
}
}
ועכשיו אני אבנה את הViewModel שיכלול את כל מה שיש בView רק בצורה לוגית יותר,
בדף הViewModel שהוא
תמיד החלק הכי מורכב בתכנית נעשה את הדברים הבאים.
1.
ניצור
אינסטנט של המודל(מישהו צריך להרים אותו מתישהו).
2.
ניצור 2 Commands (כאמור אם הוספנו את הcommand המתאים לתכנית) אחד
לריענון תצוגה ואחד להוספה ונאתחל אותם בקונסטרקטור של הקלאס (ישנם דרכים נוספות
וטובות יותר, אבל זה הכי פשוט) אנו מציג אותם כפרפרטיז.
3.
ניצור 2
פונקציות שיופעלו ע”י הcommands בהתאמה.
4.
פרופרטי
עבור שדה הערך החדש להוספה למודל (אפשר גם בלי אלא להעביר ערך דרך Command Parameter ).
5.
פרופרטי
מסוג ObservableCollection שזה List מיוחד שכולל מימוש של NotifyPropertyChanged ובעצם נעשה אליו Bindingוהוא
יהיה סוג של מתווך בין הרשימה שבמודל לזאת שתוצג באמת.
וזהו, אז כך נראה הViewModel של הדוגמא:
namespace MVVM_Demo
{
public class MainViewModel:INotifyPropertyChanged
{
Model model;
public MainViewModel()
{
model = new Model();
ObservableDataModel = new ObservableCollection<string>();
AddCommand = new MyCommand(addValue);
ShowDataCommand = new MyCommand(showData);
}
ObservableCollection<string> observableDataModel;
public ObservableCollection<string> ObservableDataModel
{
get { return observableDataModel; }
set { observableDataModel = value; }
}
public string UserData { get; set; }
private void addValue()
{
if(UserData!= null)
model.Data.Add(UserData);
}
private void showData()
{
ObservableDataModel.Clear();
foreach (var item in model.Data)
{
ObservableDataModel.Add(item);
}
}
public MyCommand AddCommand { get; set; }
public MyCommand ShowDataCommand { get; set; }
public event PropertyChangedEventHandler PropertyChanged;
}
}
* 2 הערות:
1 כרגע לא השתמשנו בINotifyPropertyChanged אבל טוב שנתרגל אליו כשמדברים על ViewModel
כי אי אפשר לתחזק
דוגמא אמיתית בלעדיו,
2. באיתחול הCommand בקונסטרקטור שלי אני משתמש בCommand הפשוט ביותר, ויש כאמור שתי אופציות נוספות אחת עם canExecute והשנייה עם פרמטר.
ונעצב רגע את הView שלנו. שאמור לכלול: רשימה של הנתונים מהמודל,
כפתור הוספה עם שדה TextBox לערך אותו נרצה להוסיף, וכפתור ריענון הרשימה או
סתם כפתור “הצג נתונים” אם תרצו,
*הערה מקובל להכניס Event שמרענן את הView כשהמודל משתנה, אבל זה לא
רלוונטי לנו רק יסבך את הדוגמא לכן פשוט ניצור כפתור ריענון.
כך נראה הXamlשלי שמייצג View בסיסי עם הbinding המתאימים:
<Window x:Class="MVVM_Demo.MainWindow"
xmlns=http://schemas.microsoft.com/winfx/2006/xaml/presentation
xmlns:x=http://schemas.microsoft.com/winfx/2006/xaml
Title="MainWindow" Height="350" Width="525">
<Grid>
<Grid.RowDefinitions>
<RowDefinition/>
<RowDefinition/>
</Grid.RowDefinitions>
<Grid.ColumnDefinitions>
<ColumnDefinition />
<ColumnDefinition Width="2*"/>
</Grid.ColumnDefinitions>
<ListBox ItemsSource="{Binding ObservableDataModel}"
Grid.Column="1" Grid.Row="0" />
<Button Content="Show Items"
Command="{Binding ShowDataCommand}" Height="20"/>
<StackPanel Grid.Column="0" Grid.Row="1">
<TextBox Text="{Binding UserData}" />
<Button Content="Add New Item"
Command="{Binding AddCommand}"/>
</StackPanel>
</Grid>
</Window>
אז הצגנו MVVM בסיסי בלי התחכמויות, ומכאן ואילך אפשר להרחיב בלי גבול או כמו
שאומרים Let the Fun begin..