<output id="qn6qe"></output>

    1. <output id="qn6qe"><tt id="qn6qe"></tt></output>
    2. <strike id="qn6qe"></strike>

      亚洲 日本 欧洲 欧美 视频,日韩中文字幕有码av,一本一道av中文字幕无码,国产线播放免费人成视频播放,人妻少妇偷人无码视频,日夜啪啪一区二区三区,国产尤物精品自在拍视频首页,久热这里只有精品12

      Attached Command for Windows 8 Metro Style in C#

      Introduction

      Windows 8 Developer Preview and Blend 5 Developer Preview edtion does not support the EventToCommandbehaviour yet (MVVM Light Toolkit is available for Metro:http://mvvmlight.codeplex.com but Blend behaviors not). And many developers want to implement the event to command in its MVVM pattern. So we need the Attached Command for Metro (Similar with the AttachedCommand in WPF).

       

      Design the code

      Well, let's start.

      Usually, in MVVM pattern, we like to declare the value properties and the Commands in the ViewModel, which use the DataBinding on the View. And that can do the "Data Drives UI" job. But let us check the Metro Style App. Although it use the XAML, and WinRT compoenets, it still can use MVVM pattern as its architecture. Metro still supports DataBinding and yes we still can let "Data" drive the "Metro UI".

      However, it is easy to implement the properties and commands in ViewModel, but not easy to assign one UI Control event to one Command. In WPF, we could use the Blend SDK behaviour to assign one event to a command, or I usually recommend to design one AttachedCommand, like this did:http://marlongrech.wordpress.com/2008/12/13/attachedcommandbehavior-v2-aka-acb . But just checking the MVVM Light Toolkit for Metro, it cannot provide the EventToCommand behaviour amd the Blend 5 Developer Preview version does not provide the behaviour. So we just need to design one AttachedCommand for Metro.

      In out AttachedCommand class, we should declare two attached properties, Command and RoutedEvent property.

          /// <summary>
      /// Command attached property
      /// </summary>
      public static readonly DependencyProperty CommandProperty =
      DependencyProperty.RegisterAttached("Command",
      "Object", // should be "Object" instead of "ICommand" interface, resolve the null reference exception
      typeof(AttachedCommand).FullName, new PropertyMetadata(DependencyProperty.UnsetValue));

      public static ICommand GetCommand(DependencyObject d)
      {
      return (ICommand)d.GetValue(CommandProperty);
      }
      public static void SetCommand(DependencyObject d, ICommand value)
      {
      d.SetValue(CommandProperty, value);
      }

      /// <summary>
      /// RoutedEvent property
      /// </summary>
      public static readonly DependencyProperty RoutedEventProperty =
      DependencyProperty.RegisterAttached("RoutedEvent",
      "String",
      typeof(AttachedCommand).FullName,
      new PropertyMetadata(String.Empty, new PropertyChangedCallback(OnRoutedEventChanged)));

      public static String GetRoutedEvent(DependencyObject d)
      {
      return (String)d.GetValue(RoutedEventProperty);
      }
      public static void SetRoutedEvent(DependencyObject d, String value)
      {
      d.SetValue(RoutedEventProperty, value);
      }

       

      We should register the Attached Property in Metro via the string of the type (similar with the Silverlight solution), and for Interface, we should use "Object" instead of. And not sure if it will be resolved in next Windows 8 version, but for interface, it will throw the NullReferenceException.

      Below is the property changed callback for RoutedEvent property:

          private static void OnRoutedEventChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
      {
      String routedEvent = (String)e.NewValue;

      if (!String.IsNullOrEmpty(routedEvent))
      {
      EventHooker eventHooker = new EventHooker();
      eventHooker.AttachedCommandObject = d;
      EventInfo eventInfo = GetEventInfo(d.GetType(), routedEvent);

      if (eventInfo != null)
      {
      eventInfo.AddEventHandler(d, eventHooker.GetEventHandler(eventInfo));
      }

      }
      }



      We need the EventInfo by reflecting the Metro DependecyObject. But in Metro, the reflection just can list the members which are declared in the current type directly. It cannot list all members inherits from the base type. So We should use one method to search the Event Member from its base types:

          /// <summary>
      /// Search the EventInfo from the type and its base types
      /// </summary>
      /// <param name="type"></param>
      /// <param name="eventName"></param>
      /// <returns></returns> <returns />
      private static EventInfo GetEventInfo(Type type, string eventName)
      {
      EventInfo eventInfo = null;
      eventInfo = type.GetTypeInfo().GetDeclaredEvent(eventName);
      if (eventInfo == null)
      {
      Type baseType = type.GetTypeInfo().BaseType;
      if (baseType != null)
      return GetEventInfo(type.GetTypeInfo().BaseType, eventName);
      else
      return eventInfo;
      }
      return eventInfo;
      }




      When the specific event is fired on the control, we should return the event handler. So there is an EventHooker that can return one "OnEventRaised" method, and execute the command in it:

        internal sealed class EventHooker
      {
      public DependencyObject AttachedCommandObject { get; set; }

      public Delegate GetEventHandler(EventInfo eventInfo)
      {
      Delegate del = null;
      if (eventInfo == null)
      throw new ArgumentNullException("eventInfo");

      if (eventInfo.EventHandlerType == null)
      throw new ArgumentNullException("eventInfo.EventHandlerType");

      if (del == null)
      del = this.GetType().GetTypeInfo().GetDeclaredMethod("OnEventRaised").CreateDelegate(eventInfo.EventHandlerType, this);

      return del;
      }

      private void OnEventRaised(object sender, object e) // the second parameter in Windows.UI.Xaml.EventHandler is Object
      {
      ICommand command = (ICommand)(sender as DependencyObject).GetValue(AttachedCommand.CommandProperty);

      if (command != null)
      command.Execute(null);
      }
      }




      How to use

      We should add one DelegateCommand or RelayCommand (ICommand) for Metro, which can help us to return the ICommand in the ViewModel. And we could bind this ICommand property on the AttachedCommand.Command property. Below is one DelegateCommand for Metro. And MVVM Light Toolkit provides the RelayCommand available for Metro also.

          public class DelegateCommand : ICommand
      {
      private readonly Predicate<object> _canExecute;
      private readonly Action<object> _execute;

      public event Windows.UI.Xaml.EventHandler CanExecuteChanged;

      public DelegateCommand(Action<object> execute)
      : this(execute, null)
      {
      }

      public DelegateCommand(Action<object> execute,
      Predicate<object> canExecute)
      {
      _execute = execute;
      _canExecute = canExecute;
      }

      public bool CanExecute(object parameter)
      {
      if (_canExecute == null)
      return true;

      return _canExecute(parameter);
      }

      public void Execute(object parameter)
      {
      _execute(parameter);
      }

      public void RaiseCanExecuteChanged()
      {
      if (CanExecuteChanged != null)
      {
      CanExecuteChanged(this, null);
      }
      }
      }



      Please note, WinRT EventHandler is different with the System.EventHandler. And Windows.UI.Xaml.EventHandler has two object parameters, the second one is not EventArgs.

      Then in the View, we just could set the AttachedCommand in any controls in Metro:

      <Button Content="Test Button"
      local:AttachedCommand.RoutedEvent
      ="PointerEntered" local:AttachedCommand.Command="{Binding TestCommand}"/>

       

      References

       

      posted @ 2012-01-25 22:33  Jarrey  閱讀(2948)  評論(2)    收藏  舉報
      主站蜘蛛池模板: 久久99精品久久久学生| 午夜精品极品粉嫩国产尤物| 四虎亚洲精品高清在线观看| 国产成人av免费观看| 亚洲中文字幕人妻系列| 久久精品蜜芽亚洲国产AV| 国产精品久久人人做人人爽| 特级毛片在线大全免费播放| 亚洲综合色网一区二区三区| 亚洲精品一区二区18禁| 国产一区二区三区精品综合| 国产精品亚洲аv无码播放| 日本在线 | 中文| 久久精品人人槡人妻人人玩| 免费国产一区二区不卡| 国产精品一二三区蜜臀av| 国产一区二区高清不卡| 孕妇特级毛片ww无码内射| 一区二区在线观看成人午夜| 中国美女a级毛片| 无码专区 人妻系列 在线| 亚洲码国产精品高潮在线| 亚洲天堂久久一区av| 日韩有码中文在线观看| 国产二区三区不卡免费| 中文字幕在线观看亚洲日韩| 亚洲精品一区二区区别| 日韩大片高清播放器| AV最新高清无码专区| 丁香花在线观看免费观看图片| 欧美牲交a欧美牲交aⅴ免费 | 亚洲精品中文av在线| 日本人妻巨大乳挤奶水免费| 国产AV福利第一精品| 无码人妻丰满熟妇区96| 麻豆麻豆麻豆麻豆麻豆麻豆| 国产无人区码一区二区| julia无码中文字幕一区| 在线看片免费人成视频久网| 亚洲男人第一无码av网站| 蜜臀av在线观看|