天天看點

Windows Phone 7 MVVM模式通訊方式之實作Command

MVVM模式的View與ViewModel的三大通訊方式:Binding Data(實作資料的傳遞)、Command(實作操作的調用)和Attached Behavior(實作控件加載過程中的操作)。

<a href="http://www.cnblogs.com/linzheng/archive/2011/06/09/2076958.html" target="_blank">(1)Windows Phone 7 MVVM模式通訊方式之實作Binding Data。</a>

<a href="http://www.cnblogs.com/linzheng/archive/2011/06/18/2084246.html">(2)Windows Phone 7 MVVM模式通訊方式之實作Command。</a>

<a href="http://www.cnblogs.com/linzheng/archive/2011/06/19/2084575.html" target="_blank">(3)Windows Phone 7 MVVM模式通訊方式之實作Attached Behavior。</a>

下面通過一個執行個體實作MVVM模式的Command通訊

(1)MainPage.xaml檔案的代碼,實作View層

&lt;phone:PhoneApplicationPage 

    x:Class="CommandDemo.MainPage" 

    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" 

    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" 

    xmlns:phone="clr-namespace:Microsoft.Phone.Controls;assembly=Microsoft.Phone" 

    xmlns:shell="clr-namespace:Microsoft.Phone.Shell;assembly=Microsoft.Phone" 

    xmlns:d="http://schemas.microsoft.com/expression/blend/2008" 

    xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" 

    xmlns:my="clr-namespace:CommandDemo.ViewModel" 

    xmlns:my_Interactivity="clr-namespace:CommandDemo.Command" 

    xmlns:Custom="clr-namespace:System.Windows.Interactivity;assembly=System.Windows.Interactivity" xmlns:ic="clr-namespace:Microsoft.Expression.Interactivity.Core;assembly=Microsoft.Expression.Interactions" 

    mc:Ignorable="d" d:DesignWidth="480" d:DesignHeight="768" 

    FontFamily="{StaticResource PhoneFontFamilyNormal}" 

    FontSize="{StaticResource PhoneFontSizeNormal}" 

    Foreground="{StaticResource PhoneForegroundBrush}" 

    SupportedOrientations="Portrait" Orientation="Portrait" 

    shell:SystemTray.IsVisible="True"&gt; 

    &lt;!--設定整個頁面的上下文資料DataContext為RadiusViewModel--&gt; 

    &lt;phone:PhoneApplicationPage.DataContext&gt; 

        &lt;my:RadiusViewModel/&gt; 

    &lt;/phone:PhoneApplicationPage.DataContext&gt; 

    &lt;Grid x:Name="LayoutRoot" Background="Transparent"&gt; 

        &lt;Grid.RowDefinitions&gt; 

            &lt;RowDefinition Height="Auto"/&gt; 

            &lt;RowDefinition Height="*"/&gt; 

        &lt;/Grid.RowDefinitions&gt; 

        &lt;StackPanel x:Name="TitlePanel" Grid.Row="0" Margin="12,17,0,28"&gt; 

            &lt;TextBlock x:Name="ApplicationTitle" Text="MY APPLICATION" Style="{StaticResource PhoneTextNormalStyle}"/&gt; 

            &lt;TextBlock x:Name="PageTitle" Text="Command" Margin="9,-7,0,0" Style="{StaticResource PhoneTextTitle1Style}"/&gt; 

        &lt;/StackPanel&gt; 

        &lt;Grid x:Name="ContentPanel" Grid.Row="1" Margin="12,0,12,0"&gt; 

            &lt;Ellipse Fill="Red" 

                     Height="{Binding Radius}" Width="{Binding Radius}" 

                     HorizontalAlignment="Left" Margin="119,84,0,0" Name="ellipse1" Stroke="Black" StrokeThickness="1" VerticalAlignment="Top" /&gt; 

            &lt;Button Content="小" Height="72" HorizontalAlignment="Left" Margin="0,385,0,0" Name="button1" VerticalAlignment="Top" Width="160"&gt; 

                &lt;Custom:Interaction.Triggers&gt; 

                    &lt;Custom:EventTrigger EventName="Click"&gt; 

                        &lt;my_Interactivity:ExecuteCommandAction CommandName="MinRadius"/&gt; 

                    &lt;/Custom:EventTrigger&gt; 

                &lt;/Custom:Interaction.Triggers&gt; 

            &lt;/Button&gt; 

            &lt;Button Content="中" Height="72" HorizontalAlignment="Left" Margin="149,384,0,0" Name="button2" VerticalAlignment="Top" Width="160" &gt; 

                        &lt;my_Interactivity:ExecuteCommandAction CommandName="MedRadius"/&gt; 

            &lt;Button Content="大" Height="72" HorizontalAlignment="Left" Margin="299,382,0,0" Name="button3" VerticalAlignment="Top" Width="160" &gt; 

                        &lt;my_Interactivity:ExecuteCommandAction  CommandName="MaxRadius"/&gt; 

        &lt;/Grid&gt; 

    &lt;/Grid&gt; 

&lt;/phone:PhoneApplicationPage&gt; 

(2)RadiusViewModel.cs檔案的代碼,實作ViewModel層

using System;  

using System.Windows.Input;  

using System.ComponentModel;  

using Microsoft.Expression.Interactivity.Core;  

namespace CommandDemo.ViewModel  

{  

    public class RadiusViewModel : INotifyPropertyChanged  

    {  

        private Double radius;  

        public RadiusViewModel()  

        {  

            Radius = 0;  

            MinRadius = new ActionCommand(p =&gt; Radius = 100);  

            MedRadius = new ActionCommand(p =&gt; Radius = 200);  

            MaxRadius = new ActionCommand(p =&gt; Radius = 300);  

        }  

        public event PropertyChangedEventHandler PropertyChanged;  

        public ICommand MinRadius  

            get; private set;  

        public ICommand MedRadius  

            get;  

            private set;  

        public ICommand MaxRadius  

        public Double Radius  

            get  

            {  

                return radius;  

            }  

            set  

                radius = value;  

                OnPropertyChanged("Radius");  

        protected virtual void OnPropertyChanged(string propertyName)  

            var propertyChanged = PropertyChanged;  

            if(propertyChanged != null)  

                propertyChanged(this, new PropertyChangedEventArgs(propertyName));  

    }  

(3)ExecuteCommandAction.cs類,實作Command操作

using System.Windows;  

using System.Windows.Interactivity;  

using System.Reflection;  

namespace CommandDemo.Command  

    public class ExecuteCommandAction : TriggerAction&lt;FrameworkElement&gt; 

        public static readonly DependencyProperty CommandNameProperty =  

             DependencyProperty.Register("CommandName", typeof(string), typeof(ExecuteCommandAction), null);  

        public static readonly DependencyProperty CommandParameterProperty =  

            DependencyProperty.Register("CommandParameter", typeof(object), typeof(ExecuteCommandAction), null);  

        protected override void Invoke(object parameter)  

            if (AssociatedObject == null)  

                return;  

            ICommand command = null;  

            var dataContext = AssociatedObject.DataContext;  

            foreach (var info in dataContext.GetType().GetProperties(BindingFlags.Public | BindingFlags.Instance))  

                if (IsCommandProperty(info) &amp;&amp; String.Equals(info.Name, CommandName, StringComparison.Ordinal))  

                {  

                    command = (ICommand)info.GetValue(dataContext, null);  

                    break;  

                }  

            if ((command != null) &amp;&amp; command.CanExecute(CommandParameter))  

                command.Execute(CommandParameter);  

        private static bool IsCommandProperty(PropertyInfo property)  

            return typeof(ICommand).IsAssignableFrom(property.PropertyType);  

        public string CommandName  

                return (string)GetValue(CommandNameProperty);  

                SetValue(CommandNameProperty, value);  

        public object CommandParameter  

                return GetValue(CommandParameterProperty);  

                SetValue(CommandParameterProperty, value);  

本文轉自linzheng 51CTO部落格,原文連結:http://blog.51cto.com/linzheng/1078577

繼續閱讀