• <ins id="pjuwb"></ins>
    <blockquote id="pjuwb"><pre id="pjuwb"></pre></blockquote>
    <noscript id="pjuwb"></noscript>
          <sup id="pjuwb"><pre id="pjuwb"></pre></sup>
            <dd id="pjuwb"></dd>
            <abbr id="pjuwb"></abbr>
            隨筆 - 55  文章 - 15  trackbacks - 0
            <2012年10月>
            30123456
            78910111213
            14151617181920
            21222324252627
            28293031123
            45678910

            常用鏈接

            留言簿

            隨筆分類

            隨筆檔案

            搜索

            •  

            最新評論

            閱讀排行榜

            評論排行榜

            MVVM--Model  View  ModelView 設計模式,目的是為了將表現與邏輯分離,使開發者更容易開發大型程序。
            一般情況下就是Xaml負責View,描述控件、用戶輸入、結果輸出等,C++文件負責ModelView,負責邏輯。Model是數據和原始內容,一般可省略。
            調用關系是Model->View->ModelView,但是可以用event來反向調用。
            正向:
            Model(文件中或者網站的)數據傳給View,View接收數據,傳遞給ViewModel后臺邏輯。
            反向:
            后臺邏輯進行處理,產生一個事件,View通過處理器處理,并顯示ModelView更新的數據,View再發生一個事件,被Model接收,Model將最后的數據寫入文件或者網絡。
            MVVM的核心目的就是要降低代碼量。

            MVVM用于數據綁定
            1 數據綁定通知
            <TextBlock Text = "{Binding ElementName = slider, Path=Value}"/>
            這是兩個FrameworkElement派生對象之間的數據綁定,其中源是:Slider對象的Value屬性,目標是:TextBlock的Text屬性。兩個屬性都是DependencyProperty(依賴屬性),對于數據綁定來說,目標對象的屬性必須為依賴屬性,源對象的屬性可以不是。
            上面的程序片段的意思是,當Slider的Value發生變化時,變化的結果實時顯示在TextBlock的Text屬性里。這個過程是怎么實現的呢?(這里源和目標都是依賴屬性,所以后面的過程是自動發生的,相當于編譯器自動添加了一段代碼,幫助我們做數據綁定)通過事件,Binding是一個對象,當Value屬性變化時,它提供了一個處理器來響應Value變化的事件,并將結果放入Text中。當然這些都是WinRT幫我們做了,并且這種綁定感覺只是在View層操作。
            當我們要在ViewModel層做數據綁定的時候,跟上面有點不一樣。我們的綁定目標依然放在Xaml文件中,而源(source)則放在ViewModel類中。這種方法是View(Xaml)和ViewModel(C++/Cx class)交互的基本模式。

            綁定源不必是依賴屬性,但是得有一套機制來通知Binding對象,該屬性被改變了。如果不是依賴屬性的話,這種通知不像上面的代碼那樣自動發生,必須通過event來實現。

            下面是幾種實現的方法:
            1. 標準方法通過INotifyPropertyChanged接口,該接口非常簡單,只有一個event
                 public interface class INotifyPropertyChanged{
                     event PropertyChangedEventHandler PropertyChanged;//更改屬性時fire這個event
                 }

                 event PropertyChangedEventHandler^ PropertyChanged {
                              void add (PropertyChangedEventHandler^ value);
                              void remove (PropertyChangedEventHandler^ value);
                           }

                 下面是摘抄的MSDN上的:
                 INotifyPropertyChanged 接口用于向客戶端(通常是執行綁定的客戶端)發出某一屬性值已更改的通知。

            例如,考慮一個帶有名為 FirstName 屬性的 Person 對象。 若要提供一般性屬性更改通知,則 Person 類型實現 INotifyPropertyChanged 接口并在 FirstName 更改時引發 PropertyChanged 事件。

            若要在將客戶端與數據源進行綁定時發出更改通知,則綁定類型應具有下列任一功能:

            • 實現 INotifyPropertyChanged 接口(首選)。

            • 為綁定類型的每個屬性提供更改事件。

             不能同時執行這兩個方法。
            摘抄一段程序以便理解:C++代碼

             1 [Windows::UI::Xaml::Data::Bindable]
             2    public ref class RgbViewModel sealed : Windows::UI::Xaml::Data::INotifyPropertyChanged
             3    {
             4    private:
             5        double red, green, blue;
             6    public:
             7        virtual event Windows::UI::Xaml::Data::PropertyChangedEventHandler^ PropertyChanged;
             8
             9        property double Red
            10        {
            11            double get();
            12            void set(double value);
            13        }

            14//
            15     protected:
            16        void OnPropertyChanged(Platform::String^ propertyName);
            17}
            ;

            定義了一個屬性Red,當Red改變時,調用OnPropertyChanged(..)方法,該方法調用PropertyChanged()event

            void RgbViewModel::Red::set(double value)
            {
                
            if (red != value)
                
            {
                    red 
            = value;
                    OnPropertyChanged(
            "Red");
                    Calculate();
                }

            }


            void RgbViewModel::OnPropertyChanged(String^ propertyName)
            {
                PropertyChanged(
            thisref new PropertyChangedEventArgs(propertyName));
            }


            到此為止,我了解到的邏輯是這樣的:一個類的屬性想要作為源數據,必須要實現INotifyPropertyChenged接口,該接口中有一個event,當相應的屬性改變時,激發這個event,這時,通知Binding這個對象,將改變了的值放入目標屬性中去。所以下一步,就是將源和對象屬性用Binding對象聯系起來。這一過程是在View中做的,即在Xaml文件中。

            <Page.Resources>
                    
            <local:RgbViewModel x:Key="rgbViewModel" /> //初始化rgbViewModel。將ViewModel作為資源是一種Xaml訪問該對象的方法。還有另外一種方法
            </Page.Resources>

                 
            <Slider Grid.Column="0"
                            Grid.Row
            ="1"
                            Value
            ="{Binding Source={StaticResource rgbViewModel}, 
                                            Path=Red, 
                                            Mode=TwoWay}"

                            ThumbToolTipValueConverter
            ="{StaticResource hexConverter}"
                            Orientation
            ="Vertical"
                            Foreground
            ="Red" />

                    
            <TextBlock Text="{Binding Source={StaticResource rgbViewModel}, 
                                              Path=Red, 
                                              Converter={StaticResource hexConverter}}"

                               Grid.Column
            ="0"
                               Grid.Row
            ="2"
                               Foreground
            ="Red" />



            另外,在做練習的時候發現,在聲明一個新類做綁定源的時候,必須加上:[Windows::UI::Xaml::Data::Bindable]這句話,不然不能實現綁定。

            2. 書中的另一個方法是用一個BindableBase類來實現,這個類也是繼承了INotifyPropertyChanged接口。如果我們從這個類繼承,那就省去了OnPropertyChanged()這一步,因為基類已經為我們實現了。但是,在c++中我沒有查到這個類,而且書中的程序也是直接繼承接口來做,跟第一種方法相同。

            3. DataContext屬性
            目前為止,我們看到了三種方法:
                 1). Source and Target are both dependency property, just use <TextBlock Text = "{Binding ElementName = slider, Path=Value}"/> to do binding.
                 2). Source property is not denpendency property. Implement a class derived from INotifyPropertyChanged, and add a event which is when property chenged fired. Like : Value="{Binding Source={StaticResource rgbViewModel}, 
                                            Path=Red, 
                                            Mode=TwoWay}"


                 3).Source property is not denpendency property. Implement a class derived from BindableBase class.
            第四種方法:指定一個綁定源,如果ElementName, Source, RelativeSource都為NULL的話,那么Binding(它是個對象)將檢查綁定目標的DataContext屬性。DataContext是FrameworkElement定義的屬性,它可以從Visual Tree從上到下傳播,不是所有的屬性都可以這么做。Foreground,和所有的Font-related屬性可以。

            在代碼中,你可以在構造函數中實例化一個DataContext of Page

            先說下我的理解,DataContext翻譯過來就是數據上下文,就是說,一些東西包含在這個上下文中,你不需要明確地指出來。像之前的第二種方法,利用INotifyPropertyChanged接口來做的,在Xaml文件中,你要綁定一個東西,要寫長長的一段話,如果你明確地表示你要綁定的東西在上下文中,那么你可以省略很多東西。確實也是這樣的。
            你可以用兩種方法設置DataContext
                  第一種方法:在code中寫,注意這個屬性是Page的:
                                    第一步,在構造函數中: RgbViewModel^ viewModel = ref new RgbViewModel();
                                                                      this->DataContext = viewModel;
                                    第二步,在Xaml文件中:
                                                                    <Slider Grid.Column="0"
                                                                      Grid.Row="1"
                                                                      Value="{Binding Red, Mode=TwoWay}"
                                    就結束了。
                 第二種方法:全部在Xaml文件中做:
                                   第一步, 在page.Resources中:
                                                                 <Page.Resources>
                                                                      <local:rgbColor x:Key="RgbColor"/>
                                                                  </Page.Resources>
                                   第二步,在Grid中:
                                                                 <Grid  DataContext="{StaticResource RgbViewModel}"> or
                                                                 <Grid DataContext="{ Binding Source={StaticResource RgbViewModel} }".../>
                                   第三步,同第一種方法第二步。


            總結:MVVM的目的是為了把表現與邏輯分開來,相互之間不要有太大的影響,讓程序員能夠專心地做某一塊。但有些時候必須要有聯系,外部傳入數據,控件接收數據,并傳入后臺處理,后臺處理后的數據又要顯示在控件上,這就需要數據綁定。數據綁定的方法已經說了幾遍了,有3種方法,一種是源和目標都是依賴屬性的時候,直接在Xaml文件中binding就行了,方法也比較簡單;第二種和第三種方法針對的都是源不是依賴屬性的時候,但目標必須是依賴屬性,這時第二種方法要使用INotifyPropertyChanged接口,當屬性改變的時候,一個Event被激活,并且提醒Binding對象將新值寫入目標數據;第三種方法是設置DataContext,這種方法最簡單,只需要在Xaml文件中設置一下就好。
            附一個OnSizeChanged方法,以

            void SliderViewModel::MainPage::OnSizeChanged(Platform::Object^ sender, Windows::UI::Xaml::SizeChangedEventArgs^ e)
            {
                
            if(e->NewSize.Width < e->NewSize.Height)
                
            {
                    forChangeRow
            ->Height = GridLength(1,GridUnitType::Star);
                    forChangeColumn
            ->Width = GridLength(0);
                    

                    Grid::SetColumn(resultRect, 
            0);
                    Grid::SetRow(resultRect,
            3);
                    Grid::SetColumnSpan(resultRect,
            3);
                }

                
            else
                
            {
                    forChangeRow
            ->Height = GridLength(0);
                    forChangeColumn
            ->Width = GridLength(3, GridUnitType::Star);
                    Grid::SetColumn(resultRect, 
            3);
                    Grid::SetRow(resultRect,
            0);
                    Grid::SetRowSpan(resultRect,
            3);
                }

            }

            后用




            posted on 2012-06-26 17:24 Dino-Tech 閱讀(1403) 評論(0)  編輯 收藏 引用
            久久综合狠狠综合久久综合88| 国产精品久久久香蕉| 日韩精品无码久久久久久| 久久综合久久性久99毛片| 亚洲国产成人乱码精品女人久久久不卡| 青青草原综合久久大伊人导航 | 久久综合久久综合久久综合| 99久久国产主播综合精品| 亚洲Av无码国产情品久久| 久久播电影网| 久久综合88熟人妻| 久久99国产乱子伦精品免费| 国内精品久久久久久中文字幕| 91久久精品电影| 久久一本综合| 亚洲综合伊人久久综合| 女同久久| 亚洲国产另类久久久精品黑人| 久久久久18| 色成年激情久久综合| 日本精品久久久久影院日本| 久久天天躁狠狠躁夜夜不卡| 国产精品美女久久久网AV| AV无码久久久久不卡蜜桃| 婷婷综合久久中文字幕| 久久久久久国产精品无码下载| 国产成人精品综合久久久| 97r久久精品国产99国产精| 久久久无码精品亚洲日韩京东传媒| 中文字幕日本人妻久久久免费 | www久久久天天com| 久久99精品久久久久久齐齐| 久久人人爽人人爽人人爽 | 2022年国产精品久久久久| 久久最新精品国产| 狠狠色婷婷久久综合频道日韩| jizzjizz国产精品久久| 久久人妻无码中文字幕| 国产一区二区精品久久凹凸| 无码AV波多野结衣久久| 久久国产影院|