豆瓣电台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基本实现了数据绑定的功能。

你可能感兴趣的:(数据绑定)