Windows Phone 7 MVVM模式通讯方式之实现Command




Windows
Phone 7 MVVM模式通讯方式之实现Command



MVVM模式的View与ViewModel的三大通讯方式:Binding
Data(实现数据的传递)、Command(实现操作的调用)和Attached Behavior(实现控件加载过程中的操作)。




下面通过一个实例实现MVVM模式的Command通讯


(1)MainPage.xaml文件的代码,实现View层











<phone:PhoneApplicationPage

    x:Class="CommandDemo.MainPage"



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

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



    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">

    <!--设置整个页面的上下文数据DataContext为RadiusViewModel-->

    <phone:PhoneApplicationPage.DataContext>

        <my:RadiusViewModel/>

    </phone:PhoneApplicationPage.DataContext>


    <Grid x:Name="LayoutRoot" Background="Transparent">

        <Grid.RowDefinitions>

            <RowDefinition Height="Auto"/>

            <RowDefinition Height="*"/>

        </Grid.RowDefinitions>


        <StackPanel x:Name="TitlePanel" Grid.Row="0" Margin="12,17,0,28">

            <TextBlock x:Name="ApplicationTitle" Text="MY APPLICATION" Style="{StaticResource PhoneTextNormalStyle}"/>

            <TextBlock x:Name="PageTitle" Text="Command" Margin="9,-7,0,0" Style="{StaticResource PhoneTextTitle1Style}"/>

        </StackPanel>



        <Grid x:Name="ContentPanel" Grid.Row="1" Margin="12,0,12,0">

            <Ellipse Fill="Red"

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

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

            <Button Content="小" Height="72" HorizontalAlignment="Left" Margin="0,385,0,0" Name="button1" VerticalAlignment="Top" Width="160">

                <Custom:Interaction.Triggers>

                    <Custom:EventTrigger EventName="Click">

                        <my_Interactivity:ExecuteCommandAction CommandName="MinRadius"/>

                    </Custom:EventTrigger>

                </Custom:Interaction.Triggers>

            </Button>

            <Button Content="中" Height="72" HorizontalAlignment="Left" Margin="149,384,0,0" Name="button2" VerticalAlignment="Top" Width="160" >

                <Custom:Interaction.Triggers>

                    <Custom:EventTrigger EventName="Click">

                        <my_Interactivity:ExecuteCommandAction CommandName="MedRadius"/>

                    </Custom:EventTrigger>

                </Custom:Interaction.Triggers>

            </Button>

            <Button Content="大" Height="72" HorizontalAlignment="Left" Margin="299,382,0,0" Name="button3" VerticalAlignment="Top" Width="160" >

                <Custom:Interaction.Triggers>

                    <Custom:EventTrigger EventName="Click">

                        <my_Interactivity:ExecuteCommandAction  CommandName="MaxRadius"/>

                    </Custom:EventTrigger>

                </Custom:Interaction.Triggers>

            </Button>

        </Grid>

    </Grid>


</phone:PhoneApplicationPage>

(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 => Radius = 100);

            MedRadius =
new ActionCommand(p => Radius = 200);

            MaxRadius =
new ActionCommand(p => Radius = 300);

        }


        public
event PropertyChangedEventHandler PropertyChanged;


        public
ICommand MinRadius

        {

            get; private set;

        }


        public
ICommand MedRadius

        {

            get;

            private set;

        }


        public
ICommand MaxRadius

        {

            get;

            private set;

        }


        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;

using
System.Windows;

using
System.Windows.Input;

using
System.Windows.Interactivity;

using
System.Reflection;


namespace CommandDemo.Command

{

    public
class ExecuteCommandAction :
TriggerAction<FrameworkElement>

    {

        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) &&
String.Equals(info.Name, CommandName, StringComparison.Ordinal))

                {

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

                    break;

                }

            }


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

            {

                command.Execute(CommandParameter);

            }

        }


        private
static bool IsCommandProperty(PropertyInfo property)

        {

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

        }


        public
string CommandName

        {

            get

            {

                return (string)GetValue(CommandNameProperty);

            }

            set

            {

                SetValue(CommandNameProperty, value);

            }

        }


        public
object CommandParameter

        {

            get

            {

                return GetValue(CommandParameterProperty);

            }

            set

            {

                SetValue(CommandParameterProperty, value);

            }

        }

    }

}

posted @ 2012-07-25 16:53  therockthe  阅读(183)  评论(0编辑  收藏  举报