Adding reference source for part of Workflow Foundation
[mono.git] / mcs / class / referencesource / System.Activities.Presentation / System.Activities.Core.Presentation / System / Activities / Core / Presentation / CaseKeyBox.xaml.cs
1 //-----------------------------------------------------------------------------
2 // Copyright (c) Microsoft Corporation.  All rights reserved.
3 //-----------------------------------------------------------------------------
4
5 namespace System.Activities.Core.Presentation
6 {
7     using System;
8     using System.Activities.Presentation;
9     using System.Windows;
10     using System.Windows.Controls;
11     using System.Windows.Data;
12     using System.Windows.Input;
13     using System.Windows.Threading;
14
15     partial class CaseKeyBox : UserControl, ICaseKeyBoxView
16     {
17         public static readonly DependencyProperty DisplayHintTextProperty =
18             DependencyProperty.Register("DisplayHintText", typeof(bool), typeof(CaseKeyBox));
19
20         public static readonly DependencyProperty LabelTextProperty =
21           DependencyProperty.Register("LabelText", typeof(string), typeof(CaseKeyBox), new UIPropertyMetadata(string.Empty));
22
23         public static readonly DependencyProperty ValueProperty =
24             DependencyProperty.Register("Value", typeof(object), typeof(CaseKeyBox), new PropertyMetadata(OnValueChanged));
25
26         public static readonly DependencyProperty ValueTypeProperty =
27             DependencyProperty.Register("ValueType", typeof(Type), typeof(CaseKeyBox), new PropertyMetadata(OnValueTypeChanged));
28         
29         public static RoutedEvent ValueCommittedEvent =
30             EventManager.RegisterRoutedEvent("ValueCommitted", RoutingStrategy.Bubble, typeof(RoutedEventHandler), typeof(CaseKeyBox));
31
32         public static RoutedEvent EditCancelledEvent =
33             EventManager.RegisterRoutedEvent("EditCancelled", RoutingStrategy.Bubble, typeof(RoutedEventHandler), typeof(CaseKeyBox));
34
35         public static readonly DependencyProperty CaseKeyValidationCallbackProperty =
36             DependencyProperty.Register("CaseKeyValidationCallback", typeof(CaseKeyValidationCallbackDelegate), typeof(CaseKeyBox));
37
38         public static readonly DependencyProperty ErrorCallbackProperty =
39             DependencyProperty.Register("ErrorCallback", typeof(Action<CaseKeyBox>), typeof(CaseKeyBox));
40
41         public static readonly DependencyProperty CommitExplicitlyProperty =
42             DependencyProperty.Register("CommitExplicitly", typeof(bool), typeof(CaseKeyBox), new PropertyMetadata(false));
43
44         Control visibleBox;
45
46
47         public CaseKeyBox()
48         {
49             this.ViewModel = new CaseKeyBoxViewModel(this);
50             InitializeComponent();
51         }
52
53         public event RoutedEventHandler ValueCommitted
54         {
55             add { AddHandler(ValueCommittedEvent, value); }
56             remove { RemoveHandler(ValueCommittedEvent, value); }
57         }
58
59         public virtual void OnValueCommitted()
60         {
61             RoutedEventArgs args = new RoutedEventArgs();
62             args.RoutedEvent = ValueCommittedEvent;
63             RaiseEvent(args);
64         }
65
66         public event RoutedEventHandler EditCancelled
67         {
68             add { AddHandler(EditCancelledEvent, value); }
69             remove { RemoveHandler(EditCancelledEvent, value); }
70         }
71
72         public virtual void OnEditCancelled()
73         {
74             RoutedEventArgs args = new RoutedEventArgs();
75             args.RoutedEvent = EditCancelledEvent;
76             RaiseEvent(args);
77         }
78
79         public CaseKeyValidationCallbackDelegate CaseKeyValidationCallback
80         {
81             get { return (CaseKeyValidationCallbackDelegate)GetValue(CaseKeyValidationCallbackProperty); }
82             set { SetValue(CaseKeyValidationCallbackProperty, value); }
83         }
84
85         public Action<CaseKeyBox> ErrorCallback
86         {
87             get { return (Action<CaseKeyBox>)GetValue(ErrorCallbackProperty); }
88             set { SetValue(ErrorCallbackProperty, value); }
89         }
90
91         public bool CommitExplicitly
92         {
93             get { return (bool)GetValue(CommitExplicitlyProperty); }
94             set { SetValue(CommitExplicitlyProperty, value); }
95         }
96
97         public string LabelText
98         {
99             get { return (string)GetValue(LabelTextProperty); }
100             set { SetValue(LabelTextProperty, value); }
101         }
102
103         void DisableKeyboardLostFocus()
104         {
105             if (this.visibleBox != null)
106             {
107                 this.visibleBox.LostKeyboardFocus -= OnLostKeyboardFocus;
108             }
109         }
110
111         void EnableKeyboardLostFocus()
112         {
113             if (!this.CommitExplicitly)
114             {
115                 if (this.visibleBox != null)
116                 {
117                     this.visibleBox.LostKeyboardFocus += OnLostKeyboardFocus;
118                 }
119             }
120         }
121
122         void ReportError(string errorMessage)
123         {
124             // Invoking error message box will cause LostFocus of the control.
125             // Thus we need to disable LostFocus first and then add the handlers back.
126             DisableKeyboardLostFocus();
127             ErrorReporting.ShowErrorMessage(errorMessage);
128
129             this.Dispatcher.BeginInvoke(DispatcherPriority.ApplicationIdle, (Action)(() =>
130             {
131                 if (this.ErrorCallback != null)
132                 {
133                     this.ErrorCallback(this);
134                     this.Dispatcher.BeginInvoke(DispatcherPriority.ApplicationIdle, (Action)(() =>
135                     {
136                         RegainFocus();
137                         EnableKeyboardLostFocus();
138                     }));
139                 }
140                 else
141                 {
142                     RegainFocus();
143                     EnableKeyboardLostFocus();
144                 }
145             }));
146         }
147
148         void OnBoxMouseUp(object sender, MouseButtonEventArgs e)
149         {
150             // disable the context menu for textbox and combobox
151             if (e.ChangedButton == MouseButton.Right && e.RightButton == MouseButtonState.Released)
152             {
153                 e.Handled = true;
154             }
155         }
156
157         #region ICaseKeyBoxView Implementation
158
159         public bool DisplayHintText
160         {
161             get { return (bool)GetValue(DisplayHintTextProperty); }
162             set { SetValue(DisplayHintTextProperty, value); }
163         }
164
165         public object Value
166         {
167             get { return (object)GetValue(ValueProperty); }
168             set { SetValue(ValueProperty, value); }
169         }
170
171         public Type ValueType
172         {
173             get { return (Type)GetValue(ValueTypeProperty); }
174             set { SetValue(ValueTypeProperty, value); }
175         }
176
177         public void RegainFocus()
178         {
179             if (this.visibleBox != null)
180             {
181                 Keyboard.Focus((IInputElement)this.visibleBox);
182             }
183         }
184
185         #endregion
186
187         #region Delegating Event Handlers
188
189         public CaseKeyBoxViewModel ViewModel { get; set; }
190
191         static void OnValueChanged(DependencyObject sender, DependencyPropertyChangedEventArgs eventArgs)
192         {
193             ((CaseKeyBox)sender).ViewModel.OnValueChanged();
194         }
195
196         static void OnValueTypeChanged(DependencyObject sender, DependencyPropertyChangedEventArgs eventArgs)
197         {
198             ((CaseKeyBox)sender).ViewModel.OnValueTypeChanged();
199         }
200
201         void OnLabelGotFocus(object sender, RoutedEventArgs e)
202         {
203             this.ViewModel.OnLabelGotFocus();
204             e.Handled = true;
205         }
206
207         void OnLostKeyboardFocus(object sender, KeyboardFocusChangedEventArgs e)
208         {
209             e.Handled = true;
210
211             if (ComboBoxHelper.ShouldFilterUnnecessaryComboBoxEvent(sender as ComboBox))
212             {
213                 return;
214             }
215
216             CommitChanges();
217         }
218
219         public bool CommitChanges()
220         {
221             UpdateSource(this.visibleBox);
222             if (this.CommitExplicitly || this.ViewModel.TextHasBeenChanged())
223             {
224                 string reason = null;
225                 if (!this.ViewModel.CanResolveInputText(out reason))
226                 {
227                     ReportError(reason);
228                     return false;
229                 }
230                 else
231                 {
232                     return this.ViewModel.OnLostFocus();
233                 }
234             }
235             else
236             {
237                 CancelChanges();
238                 return false;
239             }
240         }
241
242         public void CancelChanges()
243         {
244             DisableKeyboardLostFocus();
245             this.ViewModel.OnEscapePressed(); // simulate cancel
246         }
247
248         void OnBoxLoaded(object sender, RoutedEventArgs e)
249         {
250             UIElement box = (UIElement)sender;
251             ComboBox comboBox = box as ComboBox;
252             if (comboBox != null && comboBox.IsVisible)
253             {
254                 ComboBoxHelper.SynchronizeComboBoxSelection(comboBox, this.ViewModel.Text);
255             }
256             if (box.IsVisible)
257             {
258                 box.Focus();
259             }
260             Control control = sender as Control;
261             if (control != null && control.Visibility == Visibility.Visible)
262             {
263                 this.visibleBox = control;
264                 EnableKeyboardLostFocus();
265             }
266
267             this.ViewModel.SaveOldText();
268         }
269
270         void OnBoxUnloaded(object sender, RoutedEventArgs e)
271         {
272             if (this.visibleBox != null)
273             {
274                 DisableKeyboardLostFocus();
275                 this.visibleBox = null;
276             }
277         }
278
279         void OnBoxKeyDown(object sender, KeyEventArgs e)
280         {
281             if (!CommitExplicitly)
282             {
283                 if (e.Key == Key.Escape)
284                 {
285                     e.Handled = true;
286                     CancelChanges();
287                 }
288                 else if (e.Key == Key.Enter)
289                 {
290                     e.Handled = true;
291                     CommitChanges();
292                 }
293             }
294         }
295
296         void UpdateSource(object sender)
297         {
298             if (sender is TextBox)
299             {
300                 BindingExpression binding = ((TextBox)sender).GetBindingExpression(TextBox.TextProperty);
301                 if (binding != null)
302                 {
303                     binding.UpdateSource();
304                 }
305             }
306             else if (sender is ComboBox)
307             {
308                 BindingExpression binding = ((ComboBox)sender).GetBindingExpression(ComboBox.TextProperty);
309                 if (binding != null)
310                 {
311                     binding.UpdateSource();
312                 }
313             }
314         }
315
316         #endregion
317
318         public void ResetText()
319         {
320             this.ViewModel.ResetText();
321         }
322     }
323
324 }