PageRenderTime 5ms CodeModel.GetById 1ms app.highlight 9ms RepoModel.GetById 1ms app.codeStats 0ms

/MVVMSidekick/MVVMSidekick.Shared/Commands.cs

https://github.com/zoujuny/MVVM-Sidekick
C# | 342 lines | 207 code | 88 blank | 47 comment | 18 complexity | d3139f0ca25b98f7c68ca28c9b709668 MD5 | raw file
  1using System;
  2using System.Collections.Generic;
  3using System.Linq;
  4using System.Text;
  5using System.ComponentModel;
  6using System.Linq.Expressions;
  7using System.Runtime.Serialization;
  8using System.Reflection;
  9using System.Threading.Tasks;
 10using System.Threading;
 11using System.Windows.Input;
 12using MVVMSidekick.ViewModels;
 13using MVVMSidekick.Commands;
 14using System.Runtime.CompilerServices;
 15using MVVMSidekick.Reactive;
 16using System.Reactive.Linq;
 17using System.Reactive.Subjects;
 18using System.Reactive;
 19using System.Collections.ObjectModel;
 20using System.Collections.Specialized;
 21using System.IO;
 22using System.Collections;
 23using MVVMSidekick.Utilities;
 24using MVVMSidekick.Patterns;
 25using MVVMSidekick.Collections;
 26using MVVMSidekick.Views;
 27using MVVMSidekick.EventRouting;
 28#if NETFX_CORE
 29using Windows.UI.Xaml;
 30using Windows.UI.Xaml.Data;
 31using Windows.UI.Xaml.Controls;
 32using System.Collections.Concurrent;
 33using Windows.UI.Xaml.Navigation;
 34
 35using Windows.UI.Xaml.Controls.Primitives;
 36
 37#elif WPF
 38using System.Windows;
 39using System.Windows.Controls;
 40using System.Windows.Data;
 41using System.Collections.Concurrent;
 42using System.Windows.Navigation;
 43
 44using System.Windows.Controls.Primitives;
 45
 46#elif SILVERLIGHT_5||SILVERLIGHT_4
 47using System.Windows;
 48using System.Windows.Controls;
 49using System.Windows.Data;
 50using System.Windows.Navigation;
 51using System.Windows.Controls.Primitives;
 52#elif WINDOWS_PHONE_8||WINDOWS_PHONE_7
 53using System.Windows;
 54using System.Windows.Controls;
 55using Microsoft.Phone.Controls;
 56using System.Windows.Data;
 57using System.Windows.Navigation;
 58using System.Windows.Controls.Primitives;
 59#endif
 60
 61
 62
 63
 64
 65namespace MVVMSidekick
 66{
 67
 68    namespace Commands
 69    {
 70        /// <summary>
 71        /// Command被运行触发的事件数据类型
 72        /// </summary>
 73        public class EventCommandEventArgs : EventArgs
 74        {
 75            public Object Parameter { get; set; }
 76            public Object ViewModel { get; set; }
 77            public Object ViewSender { get; set; }
 78            public Object EventArgs { get; set; }
 79            public string EventName { get; set; }
 80            public Type EventHandlerType { get; set; }
 81            public static EventCommandEventArgs Create(
 82                Object parameter = null,
 83                Object viewModel = null,
 84                object viewSender = null,
 85                object eventArgs = null,
 86               string eventName = null,
 87                Type eventHandlerType = null
 88                )
 89            {
 90                return new EventCommandEventArgs { Parameter = parameter, ViewModel = viewModel, ViewSender = viewSender, EventArgs = eventArgs, EventHandlerType = eventHandlerType, EventName = eventName };
 91            }
 92        }
 93
 94        /// <summary>
 95        /// 事件Command的助手类
 96        /// </summary>
 97        public static class EventCommandHelper
 98        {
 99            /// <summary>
100            /// 为一个事件Command制定一个VM
101            /// </summary>
102            /// <typeparam name="TCommand">事件Command具体类型</typeparam>
103            /// <param name="cmd">事件Command实例</param>
104            /// <param name="viewModel">VM实例</param>
105            /// <returns>事件Command实例本身</returns>
106            public static TCommand WithViewModel<TCommand>(this TCommand cmd, BindableBase viewModel)
107                where TCommand : EventCommandBase
108            {
109                cmd.ViewModel = viewModel;
110                return cmd;
111            }
112
113        }
114
115        /// <summary>
116        /// 带有VM的Command接口
117        /// </summary>
118        public interface ICommandWithViewModel : ICommand
119        {
120            BindableBase ViewModel { get; set; }
121        }
122
123        /// <summary>
124        /// 事件Command,运行后马上触发一个事件,事件中带有Command实例和VM实例属性
125        /// </summary>
126        public abstract class EventCommandBase : ICommandWithViewModel
127        {
128            /// <summary>
129            /// VM
130            /// </summary>
131            public BindableBase ViewModel { get; set; }
132
133            /// <summary>
134            /// 运行时触发的事件
135            /// </summary>
136            public event EventHandler<EventCommandEventArgs> CommandExecute;
137            /// <summary>
138            /// 执行时的逻辑
139            /// </summary>
140            /// <param name="args">执行时的事件数据</param>
141            internal protected virtual void OnCommandExecute(EventCommandEventArgs args)
142            {
143                if (CommandExecute != null)
144                {
145                    CommandExecute(this, args);
146                }
147            }
148
149
150            /// <summary>
151            /// 该Command是否能执行
152            /// </summary>
153            /// <param name="parameter">判断参数</param>
154            /// <returns>是否</returns>
155            public abstract bool CanExecute(object parameter);
156
157            /// <summary>
158            /// 是否能执行的值产生变化的事件
159            /// </summary>
160            public event EventHandler CanExecuteChanged;
161
162            /// <summary>
163            /// 是否能执行变化时触发事件的逻辑
164            /// </summary>
165            protected void OnCanExecuteChanged()
166            {
167                if (CanExecuteChanged != null)
168                {
169                    CanExecuteChanged(this, EventArgs.Empty);
170                }
171            }
172
173            /// <summary>
174            /// 执行Command
175            /// </summary>
176            /// <param name="parameter">参数条件</param>
177            public virtual void Execute(object parameter)
178            {
179                if (CanExecute(parameter))
180                {
181                    OnCommandExecute(EventCommandEventArgs.Create(parameter, ViewModel));
182                }
183            }
184
185
186
187        }
188
189
190
191        namespace EventBinding
192        {
193
194
195
196
197
198
199            public class CommandBinding : FrameworkElement
200
201            {
202
203                public CommandBinding()
204                {
205                    base.Width = 0;
206                    base.Height = 0;
207                    base.Visibility =  Visibility.Collapsed ;
208                }
209
210
211
212             
213
214
215
216
217                public string EventName { get; set; }
218
219
220                public FrameworkElement EventSource
221                {
222                    get { return (FrameworkElement)GetValue(EventSourceProperty); }
223                    set { SetValue(EventSourceProperty, value); }
224                }
225
226                // Using a DependencyProperty as the backing store for EventSource.  This enables animation, styling, binding, etc...
227                public static readonly DependencyProperty EventSourceProperty =
228                    DependencyProperty.Register("EventSource", typeof(FrameworkElement), typeof(CommandBinding), new PropertyMetadata(null,
229                        (dobj, arg) =>
230                        {
231                            CommandBinding obj = dobj as CommandBinding;
232                            if (obj == null)
233                            {
234                                return;
235                            }
236                            if (obj.oldEventDispose != null)
237                            {
238                                obj.oldEventDispose.Dispose();
239                            }
240                            var nv = arg.NewValue;
241                            if (nv != null)
242                            {
243
244                                obj.oldEventDispose = nv.BindEvent(
245                                    obj.EventName,
246                                    (o, a, en, ehType) =>
247                                    {
248                                        obj.ExecuteFromEvent(o, a, en, ehType);
249                                    });
250
251                            }
252
253                        }
254
255
256                        ));
257
258
259                IDisposable oldEventDispose;
260
261                public ICommand Command
262                {
263                    get { return (ICommand)GetValue(CommandProperty); }
264                    set { SetValue(CommandProperty, value); }
265                }
266
267                // Using a DependencyProperty as the backing store for Command.  This enables animation, styling, binding, etc...
268                public static readonly DependencyProperty CommandProperty =
269                    DependencyProperty.Register("Command", typeof(ICommand), typeof(CommandBinding), new PropertyMetadata(null));
270
271
272
273
274                public Object Parameter
275                {
276                    get { return (Object)GetValue(ParameterProperty); }
277                    set { SetValue(ParameterProperty, value); }
278                }
279
280                // Using a DependencyProperty as the backing store for Parameter.  This enables animation, styling, binding, etc...
281                public static readonly DependencyProperty ParameterProperty =
282                    DependencyProperty.Register("Parameter", typeof(Object), typeof(CommandBinding), new PropertyMetadata(null));
283
284
285
286                public void ExecuteFromEvent(object sender, object eventArgs, string eventName, Type eventHandlerType)
287                {
288                    object vm = null;
289
290                    var s = (sender as FrameworkElement);
291
292                    if (Command == null)
293                    {
294                        return;
295                    }
296                    var cvm = Command as ICommandWithViewModel;
297                    if (cvm != null)
298                    {
299                        vm = cvm.ViewModel;
300                    }
301
302
303                    var newe = EventCommandEventArgs.Create(Parameter, vm, sender, eventArgs, eventName, eventHandlerType);
304
305                    if (Command.CanExecute(newe))
306                    {
307                        var spEventCommand = Command as EventCommandBase;
308                        if (spEventCommand == null)
309                        {
310                            Command.Execute(newe);
311                        }
312                        else
313                        {
314                            spEventCommand.OnCommandExecute(newe);
315
316                        }
317                    }
318
319                }
320
321
322
323            }
324
325
326
327
328
329
330
331
332
333
334
335
336
337        }
338
339
340    }
341
342}