【问题标题】:Execute Silverlight 4 Command on Load加载时执行 Silverlight 4 命令
【发布时间】:2011-02-11 06:19:19
【问题描述】:

如何实现 Silverlight 4 命令以在用户控件加载而不是映射到显式按钮单击时执行?

【问题讨论】:

    标签: silverlight mvvm silverlight-4.0


    【解决方案1】:

    或者只是在 xaml 中为您的 UserControl 添加一个trigger

    <i:Interaction.Triggers>
        <i:EventTrigger EventName="Loaded">
            <si:InvokeDataCommand Command="{Binding MyCommand}"/>
        </i:EventTrigger>
    </i:Interaction.Triggers>
    

    【讨论】:

    • 这很好用,但并不那么简单,您需要添加适当的引用,这反过来会增加应用程序的下载大小。如果这些引用有各种其他用途,但如果没有,那么编码解决方案就无需为此要求提供额外的引用。
    • 没错,您必须参考 System.Windows.Interactivity (45K) 和 Expression.Samples.Interactivity (53K) 才能使其工作。
    【解决方案2】:

    创建DependencyProperty 类型的ICommand:-

        #region public ICommand LoadedCommand
    
        public ICommand LoadedCommand
        {
            get { return GetValue(LoadedCommandProperty) as ICommand; }
            set { SetValue(LoadedCommandProperty, value); }
        }
    
        public static readonly DependencyProperty LoadedCommandProperty =
                DependencyProperty.Register(
                        "LoadedCommand",
                        typeof(ICommand),
                        typeof(MainPage),
                        new PropertyMetadata(null));
    
        #endregion public ICommand LoadedCommand
    

    还添加一个东西作为命令参数:-

        #region public object LoadedCommandParameter
    
        public object LoadedCommandParameter
        {
            get { return GetValue(LoadedCommandParameterProperty) as object; }
            set { SetValue(LoadedCommandParameterProperty, value); }
        }
    
        public static readonly DependencyProperty LoadedCommandParameterProperty =
                DependencyProperty.Register(
                        "LoadedCommandParameter",
                        typeof(object),
                        typeof(MainPage),
                        new PropertyMetadata(null));
    
        #endregion public object LoadedCommandParameter
    

    现在像这样设置它的执行:-

        public UserControl1()
        {
            InitializeComponent();
            Loaded += UserControl1_Loaded;
        }
    
        void UserControl1_Loaded(object sender, RoutedEventArgs e)
        {
            if (LoadedCommand != null && LoadedCommand.CanExecute(LoadedCommandParameter))
            {
                LoadedCommand.Execute(LoadedCommandParameter);
            }
        }
    

    现在,如果您的 ViewModel(有一个名为 StartStuff 的命令),那么:-

      <UserControl1 LoadedCommand="{Binding StartStuff}" .... >
    

    【讨论】:

      【解决方案3】:

      那是一大堆代码。没有代码的简洁版本

      public class LoadedBehaviour
      {
         public static ICommand GetLoadedCommand(DependencyObject dependencyObject)
         {
            return (ICommand)dependencyObject.GetValue(LoadedCommandProperty);
         }
      
         public static void SetLoadedCommand(DependencyObject dependencyObject, ICommand value)
         {
            dependencyObject.SetValue(LoadedCommandProperty, value);
         }
      
         public static Action GetLoadedCommandExecutor(DependencyObject dependencyObject)
         {
            return (Action)dependencyObject.GetValue(LoadedCommandExecutorProperty);
         }
      
         public static void SetLoadedCommandExecutor(DependencyObject dependencyObject, Action value)
         {
            dependencyObject.SetValue(LoadedCommandExecutorProperty, value);
         }
      
         public static readonly DependencyProperty LoadedCommandProperty = DependencyProperty.Register("LoadedCommand", typeof(ICommand), typeof(FrameworkElement), new PropertyMetadata(OnPropertyChanged));
         public static readonly DependencyProperty LoadedCommandExecutorProperty = DependencyProperty.Register("LoadedCommandExecutor", typeof(Action), typeof(FrameworkElement), new PropertyMetadata(OnPropertyChanged));
      
         private static void OnPropertyChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
         {
            if (!(d is FrameworkElement))
            {
               throw new ArgumentException("Loaded command can only be used on FrameworkElements");
               var executor = GetLoadedCommandExecutor(d);
               if(executor == null)
               {
                  executor = () =>
                  {
                         var command = GetLoadedCommand(d);
                         command.Execute(e);
               };
                  SetLoadedCommandExecutor(d, executor);
                  ((FrameworkElement)d).Loaded += (obj, args) => executor();
            }
         }
      }
      

      【讨论】:

        猜你喜欢
        • 2011-03-01
        • 2012-10-13
        • 2019-12-26
        • 1970-01-01
        • 2010-10-07
        • 1970-01-01
        • 2019-08-06
        • 1970-01-01
        • 2012-09-11
        相关资源
        最近更新 更多