Windows 8实用窍门系列:21.Windows 8 下进行MVVM开发

  在本文中将演示如何在Windows 8进行MVVM开发,首先我们准备两个辅助类如下:

  ViewModeBase类:

    public class ViewModeBase : INotifyPropertyChanged
    {
        public event PropertyChangedEventHandler PropertyChanged;
        /// <summary>
        /// 属性变化时触发事件
        /// </summary>
        /// <param name="propertyName"></param>
        protected void OnPropertyChanged( string propertyName )
        {
            var handler = this.PropertyChanged;
            if ( handler != null )
            {
                handler( this, new PropertyChangedEventArgs( propertyName ) );
            }
        }
    }

  DelegateCommand类:

   public class DelegateCommand : ICommand
    {
        private readonly Action m_exeAction;
        private readonly Func<bool> m_canExeAction;

        /// <summary>
        /// 构造函数
        /// </summary>
        /// <param name="executeAction"></param>
        /// <param name="canExecuteAction"></param>
        public DelegateCommand(Action executeAction, Func<bool> canExecuteAction)
        {
            m_exeAction = executeAction;
            m_canExeAction = canExecuteAction;
        }

        /// <summary>
        /// 构造函数
        /// </summary>
        /// <param name="executeAction"></param>
        /// <param name="canExecuteAction"></param>
        public DelegateCommand(Action executeAction)
            : this(executeAction, null)
        {
        }
        /// <summary>
        /// 判断是否执行操作
        /// </summary>
        /// <param name="parameter"></param>
        /// <returns></returns>
        public bool CanExecute(object parameter)
        {
            if (m_canExeAction != null)
            {
                return m_canExeAction();
            }
            return true;
        }
        /// <summary>
        /// 是否执行操作的变更发生时
        /// </summary>
        public event EventHandler CanExecuteChanged;

        /// <summary>
        /// 执行操作的内容,可以变为Action行为
        /// </summary>
        /// <param name="parameter"></param>
        public void Execute(object parameter)
        {
            if (CanExecute(parameter))
            {
                m_exeAction();
            }
        }

        protected void OnCanExecuteChanged(object sender, EventArgs args)
        {
            var handler = CanExecuteChanged;
            if ( handler != null )
            {
                handler( this, EventArgs.Empty );
            }
        }

        public void RaiseCanExecuteChanged()
        {
            OnCanExecuteChanged(this, EventArgs.Empty);
        }
    }

  Model层如下:

    /// <summary>
    /// 图片Model
    /// </summary>
    public class BookModel : ViewModeBase
    {
        private string txtTitle;
        private string txtContent;
        private string imageUrl;
        private bool isSelect;

        /// <summary>
        /// 标题
        /// </summary>
        public string TxtTitle
        {
            get { return txtTitle; }
            set
            {
                txtTitle = value;
                OnPropertyChanged("TxtTitle");
            }
        }

        /// <summary>
        /// 内容
        /// </summary>
        public string TxtContent
        {
            get { return txtContent; }
            set { 
                txtContent = value;
                OnPropertyChanged("TxtContent");
            }
        }

        /// <summary>
        /// 图片URL地址
        /// </summary>
        public string ImageUrl
        {
            get { return imageUrl; }
            set
            {
                imageUrl = value;
                OnPropertyChanged("ImageUrl");
            }
        }
    }

  ViewModel层代码如下:

    public class MainPageViewModel:ViewModeBase
    {
        private ICommand getTextCommand;
        private ICommand btnCommand;
        private string showText;
        private string getText;

        ObservableCollection<BookModel> books = new ObservableCollection<BookModel>(){
                        new BookModel(){ TxtTitle="盘龙",TxtContent="大小的血睛鬃毛狮,力大无穷的紫睛金毛猿,毁天灭地的九头蛇皇,携带着毁灭雷电的恐怖雷龙这里无奇不有,这是一个广博的魔幻世界。", ImageUrl="http://image.qidian.com/books/1017141/1017141.jpg" },
                        new BookModel(){ TxtTitle="纵横轮回",TxtContent="李沐然,本为身怀诸子百家所长的大神通者,在收取世间最后一颗神雷珠之时和神雷珠一道重生异世神雷之力,刑罚天下", ImageUrl="http://image.qidian.com/books/1.jpg" },
                        new BookModel(){ TxtTitle="巫师世界",TxtContent="穿越到异世界成为普通的小家族子弟,带着具有分析能力的生物芯片开始强大之旅..... ", ImageUrl="http://image.qidian.com/books/2443169/2443169.jpg" },
                        new BookModel(){ TxtTitle="杀神",TxtContent="在这个人吃人的疯狂世界,神已无力回天,就让我踏着漫天诸神的累累尸骨来普渡这芸芸众生……", ImageUrl="http://image.qidian.com/books/1911245/1911245.jpg" }
                    };
        public ICommand GetTextCommand
        {
            get { return getTextCommand; }
            set { getTextCommand = value; }
        }

        public ICommand BtnCommand
        {
            get { return btnCommand; }
            set { btnCommand = value; }
        }

        public string ShowText
        {
            get { return showText; }
            set
            {
                showText = value;
                OnPropertyChanged("ShowText");
            }
        }
        public string GetText
        {
            get { return getText; }
            set
            {
                getText = value;
                OnPropertyChanged("GetText");
            }
        }
        public MainPageViewModel()
        {
            BtnCommand = new DelegateCommand(Btn_Executed);
            GetTextCommand = new DelegateCommand(GetText_Executed);
        }

        private void GetText_Executed()
        {
            GetText = "'" + ShowText + "'是我获取到的值";
        }

        private void Btn_Executed()
        {
            ShowText = "您已经点击了按钮,请在这里输入值";
        }
        public ObservableCollection<BookModel> Books { get { return books; } }
    }

  最后View层代码如下:

    <Page.DataContext>
        <local:MainPageViewModel />
    </Page.DataContext>
    
    <Grid Background="{StaticResource ApplicationPageBackgroundThemeBrush}">
        <Button Command="{Binding BtnCommand}" Content="点击我" Padding="8"
                Margin="72,138,0,494" Height="60" Width="100" Grid.Row="0"/>
        <TextBox   Name="tbshow" Height="60" Text="{Binding ShowText,Mode=TwoWay}" Margin="230,176,744,532"/>
        <GridView x:Name="mainGridView" ItemsSource="{Binding Books}"  VerticalAlignment="Center" Grid.Row="1">
            <GridView.ItemsPanel>
                <ItemsPanelTemplate>
                    <StackPanel Orientation="Horizontal" />
                </ItemsPanelTemplate>
            </GridView.ItemsPanel>
            <GridView.ItemTemplate>
                <DataTemplate>
                    <Grid Width="250" Height="200" Background="#33CCCCCC">
                        <Grid.ColumnDefinitions>
                            <ColumnDefinition Width="110"></ColumnDefinition>
                            <ColumnDefinition></ColumnDefinition>
                        </Grid.ColumnDefinitions>
                        <Image Grid.Column="0" Margin="5,0,0,0" Source="{Binding ImageUrl}" Stretch="None"></Image>
                        <TextBlock Grid.Column="1" Margin="15,15,0,0" Foreground="White" Text="{Binding TxtTitle}"
                                    FontWeight="Bold" FontSize="18" TextWrapping="Wrap"/>
                        <TextBlock Grid.Column="1" Margin="15,40,0,0" Foreground="White" Text="{Binding TxtContent}"
                                    FontWeight="Light" FontSize="13" TextWrapping="Wrap"/>
                    </Grid>
                </DataTemplate>
            </GridView.ItemTemplate>
        </GridView>
        <Button Command="{Binding GetTextCommand}" Content="点击我获取值" Padding="8" 
                Margin="667,176,0,532" Height="60" Width="123" Grid.Row="0"/>
        <TextBlock HorizontalAlignment="Left" Margin="795,198,0,0" TextWrapping="Wrap"
                   Text="{Binding GetText,Mode=TwoWay}" VerticalAlignment="Top"
                   Height="22" Width="379"/>
    </Grid>
</Page>

  这样我们就可以将前台和后台代码分层编写,一边UI和后台开发人员同时进行开发任务。当然这是最简单的MVVM开发框架,实际开发中我们还需要完善各种事件的辅助类和其他相关辅助方法才能形成一个完整的MVVM框架。当然也可以使用网上的一些现成框架如MVVMLight等。

  下面我们看本文的示例图片,如需源码请点击 Win8MVVM.rar 下载。

posted @ 2013-03-25 12:41  程兴亮  阅读(1689)  评论(0编辑  收藏