added samples
[windows-sources.git] / sdk / samples / WPFSamples / ExpenseIt / csharp / editbox.cs
blob76e1cc748446b2f3111df455c5b920e2a591e97b
1 using System;
2 using System.Collections.Generic;
3 using System.Text;
4 using System.Windows.Controls;
5 using System.Windows.Controls.Primitives;
6 using System.Windows.Input;
7 using System.Windows;
8 using System.Diagnostics;
9 using System.Windows.Documents;
10 using System.Windows.Media;
12 namespace Editing
14 /// <summary>
15 /// EditBox is a custom cotrol that can switch between two modes:
16 /// editing and normal. When it is in editing mode, the content is
17 /// displayed in a TextBox that provides editing capbability. When
18 /// the EditBox is in normal, its content is displayed in a TextBlock
19 /// that is not editable.
20 ///
21 /// This control is designed to be used in with a GridView View.
22 /// </summary>
23 public class EditBox : Control
26 #region Static Constructor
28 /// <summary>
29 /// Static constructor
30 /// </summary>
31 static EditBox()
33 DefaultStyleKeyProperty.OverrideMetadata(typeof(EditBox),
34 new FrameworkPropertyMetadata(typeof(EditBox)));
37 #endregion
39 #region Public Methods
41 /// <summary>
42 /// Called when the tree for the EditBox has been generated.
43 /// </summary>
44 public override void OnApplyTemplate()
46 base.OnApplyTemplate();
47 TextBlock textBlock = GetTemplateChild("PART_TextBlockPart")
48 as TextBlock;
49 Debug.Assert(textBlock != null, "No TextBlock!");
51 _textBox = new TextBox();
52 _adorner = new EditBoxAdorner(textBlock, _textBox);
53 AdornerLayer layer = AdornerLayer.GetAdornerLayer(textBlock);
54 layer.Add(_adorner);
56 _textBox.KeyDown += new KeyEventHandler(OnTextBoxKeyDown);
57 _textBox.LostKeyboardFocus +=
58 new KeyboardFocusChangedEventHandler(OnTextBoxLostKeyboardFocus);
60 //Receive notification of the event to handle the column
61 //resize.
62 HookTemplateParentResizeEvent();
64 //Capture the resize event to handle ListView resize cases.
65 HookItemsControlEvents();
67 _listViewItem = GetDependencyObjectFromVisualTree(this,
68 typeof(ListViewItem)) as ListViewItem;
70 Debug.Assert(_listViewItem != null, "No ListViewItem found");
73 #endregion
75 #region Protected Methods
77 /// <summary>
78 /// If the ListViewItem that contains the EditBox is selected,
79 /// when the mouse pointer moves over the EditBox, the corresponding
80 /// MouseEnter event is the first of two events (MouseUp is the second)
81 /// that allow the EditBox to change to editing mode.
82 /// </summary>
83 protected override void OnMouseEnter(MouseEventArgs e)
85 base.OnMouseEnter(e);
86 if (!IsEditing && IsParentSelected)
88 _canBeEdit = true;
92 /// <summary>
93 /// If the MouseLeave event occurs for an EditBox control that
94 /// is in normal mode, the mode cannot be changed to editing mode
95 /// until a MouseEnter event followed by a MouseUp event occurs.
96 /// </summary>
97 protected override void OnMouseLeave(MouseEventArgs e)
99 base.OnMouseLeave(e);
100 _isMouseWithinScope = false;
101 _canBeEdit = false;
103 /// <summary>
104 /// An EditBox switches to editing mode when the MouseUp event occurs
105 /// for that EditBox and the following conditions are satisfied:
106 /// 1. A MouseEnter event for the EditBox occurred before the
107 /// MouseUp event.
108 /// 2. The mouse did not leave the EditBox between the
109 /// MouseEnter and MouseUp events.
110 /// 3. The ListViewItem that contains the EditBox was selected
111 /// when the MouseEnter event occurred.
112 /// </summary>
113 /// <param name="e"></param>
114 protected override void OnMouseUp(MouseButtonEventArgs e)
116 base.OnMouseUp(e);
118 if (e.ChangedButton == MouseButton.Right ||
119 e.ChangedButton == MouseButton.Middle)
120 return;
122 if (!IsEditing)
124 if (!e.Handled && (_canBeEdit || _isMouseWithinScope))
126 IsEditing = true;
129 //If the first MouseUp event selects the parent ListViewItem,
130 //then the second MouseUp event puts the EditBox in editing
131 //mode
132 if (IsParentSelected)
133 _isMouseWithinScope = true;
137 #endregion
139 #region Public Properties
141 #region Value
143 /// <summary>
144 /// ValueProperty DependencyProperty.
145 /// </summary>
146 public static readonly DependencyProperty ValueProperty =
147 DependencyProperty.Register(
148 "Value",
149 typeof(object),
150 typeof(EditBox),
151 new FrameworkPropertyMetadata(null));
153 /// <summary>
154 /// Gets or sets the value of the EditBox
155 /// </summary>
156 public object Value
158 get { return GetValue(ValueProperty); }
159 set { SetValue(ValueProperty, value); }
162 #endregion
164 #region IsEditing
166 /// <summary>
167 /// IsEditingProperty DependencyProperty
168 /// </summary>
169 public static DependencyProperty IsEditingProperty =
170 DependencyProperty.Register(
171 "IsEditing",
172 typeof(bool),
173 typeof(EditBox),
174 new FrameworkPropertyMetadata(false));
176 /// <summary>
177 /// Returns true if the EditBox control is in editing mode.
178 /// </summary>
179 public bool IsEditing
181 get { return (bool)GetValue(IsEditingProperty); }
182 private set
184 SetValue(IsEditingProperty, value);
185 _adorner.UpdateVisibilty(value);
189 #endregion
191 #region IsParentSelected
193 /// <summary>
194 /// Gets whether the ListViewItem that contains the
195 /// EditBox is selected.
196 /// </summary>
197 private bool IsParentSelected
201 if (_listViewItem == null)
202 return false;
203 else
204 return _listViewItem.IsSelected;
208 #endregion
210 #endregion
212 #region Private Methods
214 /// <summary>
215 /// When an EditBox is in editing mode, pressing the ENTER or F2
216 /// keys switches the EditBox to normal mode.
217 /// </summary>
218 private void OnTextBoxKeyDown(object sender, KeyEventArgs e)
220 if (IsEditing && (e.Key == Key.Enter || e.Key == Key.F2))
222 IsEditing = false;
223 _canBeEdit = false;
227 /// <summary>
228 /// If an EditBox loses focus while it is in editing mode,
229 /// the EditBox mode switches to normal mode.
230 /// </summary>
231 private void OnTextBoxLostKeyboardFocus(object sender,
232 KeyboardFocusChangedEventArgs e)
234 IsEditing = false;
237 /// <summary>
238 /// Sets IsEditing to false when the ListViewItem that contains an
239 /// EditBox changes its size
240 /// </summary>
241 private void OnCouldSwitchToNormalMode(object sender,
242 RoutedEventArgs e)
244 IsEditing = false;
247 /// <summary>
248 /// Walk the visual tree to find the ItemsControl and
249 /// hook its some events on it.
250 /// </summar
251 private void HookItemsControlEvents()
253 _itemsControl = GetDependencyObjectFromVisualTree(this,
254 typeof(ItemsControl)) as ItemsControl;
255 if (_itemsControl != null)
257 //Handle the Resize/ScrollChange/MouseWheel
258 //events to determine whether to switch to Normal mode
259 _itemsControl.SizeChanged +=
260 new SizeChangedEventHandler(OnCouldSwitchToNormalMode);
261 _itemsControl.AddHandler(ScrollViewer.ScrollChangedEvent,
262 new RoutedEventHandler(OnScrollViewerChanged));
263 _itemsControl.AddHandler(ScrollViewer.MouseWheelEvent,
264 new RoutedEventHandler(OnCouldSwitchToNormalMode), true);
268 /// <summary>
269 /// If an EditBox is in editing mode and the content of a ListView is
270 /// scrolled, then the EditBox switches to normal mode.
271 /// </summary>
272 private void OnScrollViewerChanged(object sender, RoutedEventArgs args)
274 if (IsEditing && Mouse.PrimaryDevice.LeftButton ==
275 MouseButtonState.Pressed)
277 IsEditing = false;
281 /// <summary>
282 /// Walk visual tree to find the first DependencyObject
283 /// of the specific type.
284 /// </summary>
285 private DependencyObject
286 GetDependencyObjectFromVisualTree(DependencyObject startObject,
287 Type type)
289 //Walk the visual tree to get the parent(ItemsControl)
290 //of this control
291 DependencyObject parent = startObject;
292 while (parent != null)
294 if (type.IsInstanceOfType(parent))
295 break;
296 else
297 parent = VisualTreeHelper.GetParent(parent);
300 return parent;
303 /// <summary>
304 /// When the size of the column containing the EditBox changes
305 /// and the EditBox is in editing mode, switch the mode to normal mode
306 /// </summary>
307 private void HookTemplateParentResizeEvent()
309 FrameworkElement parent = TemplatedParent as FrameworkElement;
310 if (parent != null)
312 parent.SizeChanged +=
313 new SizeChangedEventHandler(OnCouldSwitchToNormalMode);
317 #endregion
319 #region private variable
321 private EditBoxAdorner _adorner;
322 //A TextBox in the visual tree
323 private FrameworkElement _textBox;
324 //Specifies whether an EditBox can switch to editing mode.
325 //Set to true if the ListViewItem that contains the EditBox is
326 //selected, when the mouse pointer moves over the EditBox
327 private bool _canBeEdit;
328 //Specifies whether an EditBox can switch to editing mode.
329 //Set to true when the ListViewItem that contains the EditBox is
330 //selected when the mouse pointer moves over the EditBox.
331 private bool _isMouseWithinScope;
332 //The ListView control that contains the EditBox
333 private ItemsControl _itemsControl;
334 //The ListViewItem control that contains the EditBox
335 private ListViewItem _listViewItem;
337 #endregion