[WPF]MVVM Demo


    最近一直搞Java,VS好久沒有打開了,感覺有必要把以前.Net體系下一些經驗給整理一下。現在越來越感覺,只會一門語言或者一種環境的開發,局限性會很大。下面先科普一下幾種常用架構模式的發展過程吧:MVC - MVP - MVVM。MVC這個不用多說了,JAVA SSH框架下就是一種經典的MVC的應用了。關於MVP之前寫過一個Asp.Net的MVP Demo有興趣的朋友可以去參考一下:http://www.cnblogs.com/CopyPaster/archive/2011/01/10/1931705.html;現在再把MVVM補充一下吧。

MVVM的背景歷史(以下內容是我對一些英文Blog部分內容的翻譯,大家湊合讀讀吧)

    自從人們開始用面向接口的方式開發軟件,利用設計模式使之簡化漸漸開始流行起來。例如:MVP模式在多樣UI平台編程上的應用和流行。MVP模式是MVC模式提出后十年來的一種演變。如果你以前從未使用過MVP模式,這里有一個簡單的解釋:任何在屏幕上所能看到的被稱之為View,視圖中顯示的數據稱之為Model,View和Model之間通訊和聯系由Presenter負責。視圖依賴於Prensenter的數據處理邏輯,比如說:對於用戶輸入的響應,提供一個輸入驗證等。如果你深入了解MVP模式,建議去讀Jean-Paul Boodhoo's的文章:http://msdn.microsoft.com/en-us/magazine/cc188690.aspx

    2004年,Martin Fowler發表了一篇名為PM模式的文章。PM模式與MVP模式很類似,都將視圖與其狀態和行為相分離。PM模式中不同點是:在PM中創建了一個視圖的抽象,於是視圖的功能僅僅只是呈現PM。Fowler解釋到:PM頻繁更新視圖,且兩互相同步。由此可見,PM模式邏輯處理均以同步形式存在。

    2005年,恰逢微軟發布WPF和Silverlight,John Gossman,在他的博客提出了MVVM模式。MVVM模式和Fowler的PM模式一樣均定義了視圖狀態和行為的抽象。Fowler介紹的PM模式是一種開發UI獨立平台的方法。Gossman介紹的MVVM模式是一種充分利用WPF新特性創建用戶接口的標准方法。換而言之,我認為MVVM是一種特殊的PM模式,是為WPF和Silverlight平台下的開發而量身打造的。   

Demo說明:

    Demo本身不包含什么業務邏輯,只是寫了一些UI上的邏輯,主要的目的是展示MVVMDemo.SysFramwork.MVVM命名空間下核心代碼,以及MVVM模式下的開發方式。Demo代碼結構圖如下:

Demo UI Xaml:

<Window x:Class="MVVMDemo.UI.View.TestWindow"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" 
    xmlns:mvvm="clr-namespace:MVVMDemo.SysFramwork.MVVM;assembly=MVVMDemo.SysFramwork" 
    xmlns:common="clr-namespace:MVVMDemo.UI.Common" Title="TestWindow" Height="300" Width="500"
    Name="rootControl"
    >
    <Window.Resources>
        <ResourceDictionary>
            <Style x:Key="PaymentInputTextBoxStyle" TargetType="TextBox">
                <Setter Property="mvvm:CommandSource.Trigger">
                    <Setter.Value>
                        <mvvm:CommandTriggerGroup>
                            <mvvm:EventCommandTrigger 
                                    RoutedEvent="FrameworkElement.Loaded"
                                    CommandParameter="{Binding RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type TextBox}}}"
                                    Command="{Binding ElementName=rootControl, Path=DataContext.PaymentInputTextBoxLoadCommand}"/>
                            <mvvm:EventCommandTrigger 
                                    RoutedEvent="TextBox.GotFocus" 
                                    Command="{Binding ElementName=rootControl, Path=DataContext.PaymentInputTextBoxGotFocusCommand}"/>
                            <mvvm:EventCommandTrigger 
                                    RoutedEvent="TextBox.GotMouseCapture"
                                    Command="{Binding ElementName=rootControl, Path=DataContext.PaymentInputTextBoxGotFocusCommand}"/>
                            <mvvm:EventCommandTrigger 
                                    RoutedEvent="TextBox.KeyDown"
                                    Command="{Binding ElementName=rootControl, Path=DataContext.PaymentInputTextBoxKeyDownCommand}"/>
                        </mvvm:CommandTriggerGroup>
                    </Setter.Value>
                </Setter>
            </Style>
        </ResourceDictionary>
    </Window.Resources>
    <DockPanel Margin="10,50,10,10">
        <Grid DockPanel.Dock="Top" Margin="5,5,5,5">
            <Grid.RowDefinitions>
                <RowDefinition Height="30" />
            </Grid.RowDefinitions>
            <Grid.ColumnDefinitions>
                <ColumnDefinition Width="Auto"/>
                <ColumnDefinition />
            </Grid.ColumnDefinitions>
            <TextBlock Text="需要支付:" />
            <TextBox Grid.Column="1" Name="tbRequiredAmount"  Height="25"  HorizontalAlignment="Stretch"
                     common:TextBoxMaskBehavior.Mask="Decimal"
                     Text="{Binding Path=RequiredAmount, UpdateSourceTrigger=PropertyChanged}"/>
        </Grid>
        <Grid DockPanel.Dock="Top" Margin="5,5,5,5" KeyboardNavigation.TabNavigation="Cycle">
            <Grid.RowDefinitions>
                <RowDefinition Height="30" />
                <RowDefinition Height="30" />
            </Grid.RowDefinitions>
            <Grid.ColumnDefinitions>
                <ColumnDefinition Width="Auto"/>
                <ColumnDefinition />
                <ColumnDefinition Width="Auto"/>
                <ColumnDefinition />
            </Grid.ColumnDefinitions>
            <TextBlock Text="現金:" />
            <TextBox Grid.Column="1" Name="textBoxCash" TabIndex="1"  Height="25"  HorizontalAlignment="Stretch" Style="{StaticResource PaymentInputTextBoxStyle}"
                     common:TextBoxMaskBehavior.Mask="Decimal"
                     Tag="{Binding PaymentTypeCashRcd}"
                     Text="{Binding Path=CashierAmount, UpdateSourceTrigger=PropertyChanged}" />
            <TextBlock Grid.Column="2" Text="信用卡:" />
            <TextBox  Grid.Column="3" Name="textBoxCreditCard" TabIndex="2"  Height="25" HorizontalAlignment="Stretch" Style="{StaticResource PaymentInputTextBoxStyle}"
                      common:TextBoxMaskBehavior.Mask="Decimal"
                      Tag="{Binding PaymentTypeCreditCardRcd}"
                      Text="{Binding Path=CreditCardAmount, UpdateSourceTrigger=PropertyChanged}"/>
            <TextBlock Grid.Row="1" Text="支票:" />
            <TextBox  Grid.Column="1" Grid.Row="1" Name="textBoxCheck" TabIndex="3" Height="25" HorizontalAlignment="Stretch" Style="{StaticResource PaymentInputTextBoxStyle}"
                      common:TextBoxMaskBehavior.Mask="Decimal"
                      Tag="{Binding PaymentTypeCheckRcd}"
                      Text="{Binding Path=CheckAmount, UpdateSourceTrigger=PropertyChanged}" />
            <TextBlock Grid.Column="2" Grid.Row="1" Text="保險:" />
            <TextBox Grid.Column="3" Grid.Row="1" Name="textBoxInsuranceCard" TabIndex="4" Height="25" HorizontalAlignment="Stretch" Style="{StaticResource PaymentInputTextBoxStyle}"
                     common:TextBoxMaskBehavior.Mask="Decimal"
                     Tag="{Binding PaymentTypeInsuranceCardRcd}"
                     Text="{Binding Path=InsuranceCardAmount, UpdateSourceTrigger=PropertyChanged}" />
        </Grid>
        <DockPanel DockPanel.Dock="Bottom" LastChildFill="False">
            <Button Name="buttonConfirm" DockPanel.Dock="Right" Height="30" Width="75" Content="確認" 
                    IsEnabled="{Binding IsReadyToSubmit}" 
                    Command="{Binding Path=ButtonConfirmCommand}">
                <mvvm:CommandSource.Trigger>
                    <mvvm:CommandTriggerGroup>
                        <mvvm:EventCommandTrigger 
                                    RoutedEvent="FrameworkElement.Loaded" 
                                    CommandParameter="{Binding ElementName=buttonConfirm}"
                                    Command="{Binding ElementName=rootControl, Path=DataContext.ConfirmButtonLoadCommand}"/>
                    </mvvm:CommandTriggerGroup>
                </mvvm:CommandSource.Trigger>
            </Button>
            <Button Name="buttonCancel" DockPanel.Dock="Right" Height="30" Width="75" Content="取消" 
                    CommandParameter="{Binding ElementName=rootControl}"
                    Command="{Binding Path=ButtonCancelCommand}"/>
        </DockPanel>
    </DockPanel>
</Window>

 

Demo下載地址:

http://download.csdn.net/detail/camelials/4858119


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM