[NUI] Fix exception defect when LanguageChanged event has come
[platform/core/csapi/tizenfx.git] / src / Tizen.NUI / src / public / XamlBinding / Command.cs
1 using System;
2 using System.Reflection;
3 using System.Windows.Input;
4 using System.ComponentModel;
5
6 namespace Tizen.NUI.Binding
7 {
8     /// This will be public opened in tizen_5.0 after ACR done. Before ACR, need to be hidden as inhouse API.
9     [EditorBrowsable(EditorBrowsableState.Never)]
10     public sealed class Command<T> : Command
11     {
12         /// This will be public opened in tizen_5.0 after ACR done. Before ACR, need to be hidden as inhouse API.
13         [EditorBrowsable(EditorBrowsableState.Never)]
14         public Command(Action<T> execute)
15             : base(o =>
16             {
17                 if (IsValidParameter(o))
18                 {
19                     execute((T)o);
20                 }
21             })
22         {
23             if (execute == null)
24             {
25                 throw new ArgumentNullException(nameof(execute));
26             }
27         }
28
29         /// This will be public opened in tizen_5.0 after ACR done. Before ACR, need to be hidden as inhouse API.
30         [EditorBrowsable(EditorBrowsableState.Never)]
31         public Command(Action<T> execute, Func<T, bool> canExecute)
32             : base(o =>
33             {
34                 if (IsValidParameter(o))
35                 {
36                     execute((T)o);
37                 }
38             }, o => IsValidParameter(o) && canExecute((T)o))
39         {
40             if (execute == null)
41                 throw new ArgumentNullException(nameof(execute));
42             if (canExecute == null)
43                 throw new ArgumentNullException(nameof(canExecute));
44         }
45
46         static bool IsValidParameter(object o)
47         {
48             if (o != null)
49             {
50                 // The parameter isn't null, so we don't have to worry whether null is a valid option
51                 return o is T;
52             }
53
54             var t = typeof(T);
55
56             // The parameter is null. Is T Nullable?
57             if (Nullable.GetUnderlyingType(t) != null)
58             {
59                 return true;
60             }
61
62             // Not a Nullable, if it's a value type then null is not valid
63             return !t.GetTypeInfo().IsValueType;
64         }
65     }
66
67     /// <summary>
68     /// Defines an ICommand implementation that wraps a Action.
69     /// </summary>
70     [EditorBrowsable(EditorBrowsableState.Never)]
71     public class Command : ICommand
72     {
73         readonly Func<object, bool> _canExecute;
74         readonly Action<object> _execute;
75
76         /// <summary>
77         /// Initializes a new instance of the Command class.
78         /// </summary>
79         /// <param name="execute">An instance to execute when the Command is executed.</param>
80         /// This will be public opened in tizen_5.0 after ACR done. Before ACR, need to be hidden as inhouse API.
81         [EditorBrowsable(EditorBrowsableState.Never)]
82         public Command(Action<object> execute)
83         {
84             if (execute == null)
85                 throw new ArgumentNullException(nameof(execute));
86
87             _execute = execute;
88         }
89
90         /// <summary>
91         /// Initializes a new instance of the Command class.
92         /// </summary>
93         /// <param name="execute">An Action to execute when the Command is executed.</param>
94         /// This will be public opened in tizen_5.0 after ACR done. Before ACR, need to be hidden as inhouse API.
95         [EditorBrowsable(EditorBrowsableState.Never)]
96         public Command(Action execute) : this(o => execute())
97         {
98             if (execute == null)
99                 throw new ArgumentNullException(nameof(execute));
100         }
101
102         /// <summary>
103         /// Initializes a new instance of the Command class.
104         /// </summary>
105         /// <param name="execute">An Action to execute when the Command is executed.</param>
106         /// <param name="canExecute">A instance indicating if the Command can be executed.</param>
107         /// This will be public opened in tizen_5.0 after ACR done. Before ACR, need to be hidden as inhouse API.
108         [EditorBrowsable(EditorBrowsableState.Never)]
109         public Command(Action<object> execute, Func<object, bool> canExecute) : this(execute)
110         {
111             if (canExecute == null)
112                 throw new ArgumentNullException(nameof(canExecute));
113
114             _canExecute = canExecute;
115         }
116
117         /// <summary>
118         /// Initializes a new instance of the Command class.
119         /// </summary>
120         /// <param name="execute">An Action to execute when the Command is executed.</param>
121         /// <param name="canExecute">A instance indicating if the Command can be executed.</param>
122         /// This will be public opened in tizen_5.0 after ACR done. Before ACR, need to be hidden as inhouse API.
123         [EditorBrowsable(EditorBrowsableState.Never)]
124         public Command(Action execute, Func<bool> canExecute) : this(o => execute(), o => canExecute())
125         {
126             if (execute == null)
127                 throw new ArgumentNullException(nameof(execute));
128             if (canExecute == null)
129                 throw new ArgumentNullException(nameof(canExecute));
130         }
131
132         /// <summary>
133         /// Returns a Boolean indicating if the Command can be exectued with the given parameter.
134         /// </summary>
135         /// <param name="parameter">An Object used as parameter to determine if the Command can be executed.</param>
136         /// <returns>true if the Command can be executed, false otherwise.</returns>
137         /// This will be public opened in tizen_5.0 after ACR done. Before ACR, need to be hidden as inhouse API.
138         [EditorBrowsable(EditorBrowsableState.Never)]
139         public bool CanExecute(object parameter)
140         {
141             if (_canExecute != null)
142                 return _canExecute(parameter);
143
144             return true;
145         }
146
147         /// <summary>
148         /// Occurs when the target of the Command should reevaluate whether or not the Command can be executed.
149         /// </summary>
150         /// This will be public opened in tizen_5.0 after ACR done. Before ACR, need to be hidden as inhouse API.
151         [EditorBrowsable(EditorBrowsableState.Never)]
152         public event EventHandler CanExecuteChanged;
153
154         /// <summary>
155         /// Invokes the execute Action.
156         /// </summary>
157         /// <param name="parameter">An Object used as parameter for the execute Action.</param>
158         /// This will be public opened in tizen_5.0 after ACR done. Before ACR, need to be hidden as inhouse API.
159         [EditorBrowsable(EditorBrowsableState.Never)]
160         public void Execute(object parameter)
161         {
162             _execute(parameter);
163         }
164
165         /// <summary>
166         /// Send a CanExecuteChanged.
167         /// </summary>
168         /// This will be public opened in tizen_5.0 after ACR done. Before ACR, need to be hidden as inhouse API.
169         [EditorBrowsable(EditorBrowsableState.Never)]
170         public void ChangeCanExecute()
171         {
172             EventHandler changed = CanExecuteChanged;
173             changed?.Invoke(this, EventArgs.Empty);
174         }
175     }
176 }