MVVM學習筆記 1、MVVM的簡介 MVVM模式是Model-View-ViewModel模式的簡稱,也就是由模型(Model)、視圖(View)、視圖模型(ViewModel),其目的是為了實現將業務和界面分開,降低耦合度。 2、示例(綁定TextBox和Combox控制項) 總體結構: View ...
MVVM學習筆記
1、MVVM的簡介
MVVM模式是Model-View-ViewModel模式的簡稱,也就是由模型(Model)、視圖(View)、視圖模型(ViewModel),其目的是為了實現將業務和界面分開,降低耦合度。
2、示例(綁定TextBox和Combox控制項)
總體結構:
View層代碼:
<Label Content="購買數:" Style="{StaticResource LabStyle}" Grid.Row="3" Grid.Column="0" /> <TextBox Grid.Row="3" Grid.Column="1" Style="{StaticResource TextBoxStyle}" Text="{Binding BuyTextBox,UpdateSourceTrigger=PropertyChanged}"> </TextBox> <ComboBox Grid.Row="0" Grid.Column="1" Style="{StaticResource ComboxStyle}"> <ComboBoxItem Content="西瓜" /> </ComboBox> <ComboBox Grid.Row="1" Grid.Column="1" Style="{StaticResource ComboxStyle}" ItemsSource="{Binding Prices}" SelectedItem="{Binding SelectPrice, UpdateSourceTrigger=PropertyChanged}"> </ComboBox>View Code
ViewModel層代碼
/// <summary> /// 設置購買量屬性 /// </summary> public int BuyTextBox { get { return m_buyNum; } set { m_buyNum = value; //計算金額 m_money = m_selectPrice*m_buyNum; if (m_buyNum > m_surplus) { MessageBox.Show("購買數量大於剩餘數量,請重新輸入購買數量!"); m_buyNum = 0; m_money = 0; } OnPropertyChange<CalculateFruitVm>(vm => vm.BuyTextBox); } }View Code
/// <summary> /// 設置價格屬性 /// </summary> public ObservableCollection<int> Prices { get { return m_prices; } set { m_prices = value; OnPropertyChange<CalculateFruitVm>(vm => vm.Prices); } }View Code
/// <summary> /// 設置選擇價格屬性 /// </summary> public int SelectPrice { get { return m_selectPrice; } set { m_selectPrice = value; m_money = m_selectPrice*m_buyNum; OnPropertyChange<CalculateFruitVm>(vm => vm.SelectPrice); } }View Code
/// <summary> /// 構造函數CalculateFruitVm /// </summary> public CalculateFruitVm() { m_prices.Add(4); m_selectPrice = 4; m_prices.Add(5); }View Code
註意:這裡是在構造函數CalculateFruitVm中設置價格並選擇價格,因價格是combox控制項,除了需要設置價格屬性外,還需要設置價格選擇屬性。
Button按鈕
View層代碼
<Button Content="返回" Grid.Column="2" Style="{StaticResource ButtonStyle}" HorizontalAlignment="Left" Command="{Binding CancleCommand}"></Button>View Code
ViewModel層代碼
/// <summary> /// CancleCommand命令 /// </summary> public ICommand CancleCommand { get { return m_cancelCommand; } }View Code
/// <summary> /// 構造函數CalculateFruitVm /// </summary> public CalculateFruitVm() { m_cancelCommand = ICommandFactory.CreateCommand(CancelCmdExecute, CanCancelCmdExecute); }View Code
/// <summary> /// 聲明CancelEvent事件 /// </summary> public event EventHandler<EventArgs> CancelEvent; /// <summary> /// CanCancelCmdExecute事件 /// </summary> /// <param name="arg"></param> /// <returns></returns> private bool CanCancelCmdExecute(object arg) { return true; }View Code
/// <summary> /// CancelCmdExecute事件 /// </summary> /// <param name="obj"></param> private void CancelCmdExecute(object obj) { if (CancelEvent != null) { CancelEvent(this, EventArgs.Empty); } }View Code
.xaml.cs代碼
public CalculateFruit() { InitializeComponent(); CalculateFruitVm calculateFruitVm = new CalculateFruitVm(); DataContext = calculateFruitVm; calculateFruitVm.CancelEvent += calculateFruitVm_CancelEvent; }View Code
/// <summary> /// 點擊返回按鈕,返回主界面 /// </summary> /// <param name="sender"></param> /// <param name="e"></param> private void calculateFruitVm_CancelEvent(object sender, EventArgs e) { MainWindow mainWindow = new MainWindow(); mainWindow.Show(); this.Hide(); }View Code
Button按鈕需要在View層用command綁定事件,ViewModel中創建命令、構造函數、聲明事件,最後在.xaml.cs中載入ViewModel,並實現界面跳轉、關閉等操作。
3、總結
MVVM 中更好的實現了面向對象中的繼承和封裝,所有的命令都繼承自ICommand介面,將所有的命令用ViewModel層去實現。
當界面之間需要互相傳值時,需要在VM中傳遞界面需要的值,實例化需要傳到哪個界面的VM,示例如下:
隱藏事件
private void HideCmdExecute(object obj) { if (m_buyNum > 0 && m_selectPrice > 0) { if (HideEvent != null) { //計算剩餘量 m_surplus -= m_buyNum; //計算售賣總量 CalculateNum += m_buyNum; //計算售賣總金額 CalculateMoney += m_money; //new出ResultCalculateVm並賦值 ResultCalculateVm resultCalculateVm = new ResultCalculateVm(); resultCalculateVm.SalesNumberTextBox = CalculateNum; resultCalculateVm.TotalMoney = CalculateMoney; resultCalculateVm.TotalSurplus = m_surplus; HideEvent(this, new FruitEventArgs {ResultCalculateVm = resultCalculateVm}); } } }View Code