Loading

豆瓣电台WP7客户端 MVVM重构记录之使用MVVM Light实现数据绑定

最近面试多次被问及MVVM,虽然看过园子里的教程,毕竟未实际实现过,都回答“只了解,未实践过”。今天终于逼自己去用MVVM重构下这个应用。

这里就不多说MVVM的理论等东西了。需要了解的搜一下园子吧,大把大把的!

这次我选择了MVVM Light框架去实现MVVM。我也没用过其他的框架,也不知道有什么特别的地方或者优势,使用MVVM Light也全听别人说不错。

首先去codeplex下载下来MVVM Light:http://mvvmlight.codeplex.com/ 安装之。安装完成之后在原来的项目上添加引用:

image

调整项目目录结构:

image

新建View,ViewModel两个文件夹。把ChannelTile.xaml,MainPage.xaml移动到View文件夹下。在ViewModel文件夹下右键新建类,选择MVVM Light为我们提供的模板:MvvmViewModel(wp7)。

image

新建一个叫ChannelTileViewModel的类。把原来在ChannelTile.cs文件里的代码移植了一部分过来。

using GalaSoft.MvvmLight;
using Microsoft.Xna.Framework.Input.Touch;
using Helper;
using System;
using System.Windows;

namespace DBFM7.ViewModel
{
    /// <summary>
    /// This class contains properties that a View can data bind to.
    /// <para>
    /// Use the <strong>mvvminpc</strong> snippet to add bindable properties to this ViewModel.
    /// </para>
    /// <para>
    /// See http://www.galasoft.ch/mvvm/getstarted
    /// </para>
    /// </summary>
    public class ChannelTileViewModel : ViewModelBase
    {
        /// <summary>
        /// Initializes a new instance of the ChannelTileViewModel class.
        /// </summary>
        public ChannelTileViewModel()
        {
            TouchPanel.EnabledGestures = GestureType.Tap | GestureType.HorizontalDrag;
            if (!PlayListHelper.IsInited)
            {
                PlayListHelper.InitChannelComplete += new Action(PlayListHelper_InitChannelComplete);
                PlayListHelper.InitChannel();//初始化播放列表
            }
            else
                this.IsShowGoBtn = Visibility.Visible;
        }


        private string _Title="频道正在初始化...";
        /// <summary>
        /// 标题
        /// </summary>
        public string Title
        { get { return _Title; } 
          set 
          {
              this._Title = value;
              this.RaisePropertyChanged("Title");
          } 
        }


        private Visibility _IsShowGoBtn=Visibility.Collapsed;
        /// <summary>
        /// 是否显示右边的箭头
        /// </summary>
        public Visibility IsShowGoBtn
        {
            get { return this._IsShowGoBtn; }
            set
            {
                this._IsShowGoBtn = value;
                this.RaisePropertyChanged("IsShowGoBtn");
            }
        }

        /// <summary>
        /// 初始化tile的image跟title
        /// </summary>
        protected void PlayListHelper_InitChannelComplete()
        {
  
            this.Title = "请选择一个你喜欢的频道";

        }

    }
}

这个类继承ViewModelBase,它已经帮我们实现了INotifyPropertyChanged接口,所以简化了实现ViewModelBase的步骤。我们只要定义一个属性,然后在set方法里调用RaisePropertyChanged()方法就实现了依赖属性。

然后在项目目录下新建一个MvvmViewModelLocator,还是使用MVVM Light的模板:

image

 


using GalaSoft.MvvmLight;
using GalaSoft.MvvmLight.Ioc;
using Microsoft.Practices.ServiceLocation;
using DBFM7.ViewModel;

namespace DBFM7
{
    /// <summary>
    /// This class contains static references to all the view models in the
    /// application and provides an entry point for the bindings.
    /// <para>
    /// Use the <strong>mvvmlocatorproperty</strong> snippet to add ViewModels
    /// to this locator.
    /// </para>
    /// <para>
    /// See http://www.galasoft.ch/mvvm/getstarted
    /// </para>
    /// </summary>
    public class MvvmViewModelLocator
    {
        static MvvmViewModelLocator()
        {
            ServiceLocator.SetLocatorProvider(() => SimpleIoc.Default);

            if (ViewModelBase.IsInDesignModeStatic)
            {
                // SimpleIoc.Default.Register<IDataService, Design.DesignDataService>();
            }
            else
            {
                // SimpleIoc.Default.Register<IDataService, DataService>();
            }

            SimpleIoc.Default.Register<ChannelTileViewModel>();
        }

        /// <summary>
        /// Gets the Main property.
        /// </summary>
        [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Performance",
            "CA1822:MarkMembersAsStatic",
            Justification = "This non-static member is needed for data binding purposes.")]
        public ChannelTileViewModel ChannelTile
        {
            get
            {
                return ServiceLocator.Current.GetInstance<ChannelTileViewModel>();
            }
        }

    }
}
把生成的MainViewModel替换成ChannelTileViewModel。
 
在APP.Xaml添加一个静态资源:
 
    <Application.Resources>
        <vm:MvvmViewModelLocator xmlns:vm="clr-namespace:DBFM7"
                                   x:Key="Locator" />
    </Application.Resources>

 

把ChannelTileViewModel跟ChannelTile.xaml绑定起来。

<phone:PhoneApplicationPage xmlns:toolkit="clr-namespace:Microsoft.Phone.Controls;assembly=Microsoft.Phone.Controls.Toolkit"  
    x:Class="DBFM7.View.ChannelTile"
。。。。。。。。。。。。
    DataContext="{Binding ChannelTile,Source={StaticResource Locator}}">

    <!--LayoutRoot is the root grid where all page content is placed-->
    <Grid x:Name="LayoutRoot" Background="Transparent">
        <Grid.RowDefinitions>
            <RowDefinition Height="Auto"/>
            <RowDefinition Height="*"/>
        </Grid.RowDefinitions>

        <!--TitlePanel contains the name of the application and page title-->
        <StackPanel x:Name="TitlePanel" Grid.Row="0" Margin="12,17,0,0">
            <TextBlock x:Name="ApplicationTitle" Text="DB.FM 7" Style="{StaticResource PhoneTextNormalStyle}"/>
            <TextBlock HorizontalAlignment="Center" x:Name="PageTitle" 
                       Text="{Binding Title}" 
                       Margin="0,40,0,0" FontSize="22"/>
        </StackPanel>
。。。。。。。。。。。。。。。。。。
            <Image  Grid.Column="2"
                VerticalAlignment="Top"
                Margin="0,12,0,0"
                Width="48" Height="48" 
                Source="..\ICON\RightGo.png" 
                x:Name="imgGo" Tap="imgGo_Tap"
                 Visibility="{Binding IsShowGoBtn}" />
 
这样就用MVVM Light基本实现了数据绑定的功能。
posted @ 2012-02-26 02:10  Agile.Zhou  阅读(1515)  评论(4编辑  收藏  举报