/// <summary> /// Raise the UnitsChanged event when the units change. /// </summary> /// <param name="sender">The TermLength</param> /// <param name="eventArgs">The event arguments.</param> private static void OnUnitsChanged(DependencyObject sender, DependencyPropertyChangedEventArgs eventArgs) { TermLength termLength = sender as TermLength; termLength.Text = String.Format("{0:0.###} {1}", termLength.Length, termLength.Units == null ? "" : (Object)(TimeUnitList.Default.Find(termLength.Units.Value).TimeUnitCode)); (sender as TermLength).RaiseEvent(new RoutedEventArgs(TermLength.UnitsChangedEvent)); }
/// <summary> /// Handles a change in the text. Updates the bindings with Length and Units. /// </summary> /// <param name="eventArgs">The event arguments</param> protected override void OnTextChanged(TextChangedEventArgs eventArgs) { string[] valueAndUnits = this.Text.Split(new char[] { ' ' }, StringSplitOptions.None); // BindingExpression binding; base.OnTextChanged(eventArgs); #if false binding = this.GetBindingExpression(TermLength.LengthProperty); if (binding != null) { binding.UpdateTarget(); } binding = this.GetBindingExpression(TermLength.UnitsProperty); if (binding != null) { binding.UpdateTarget(); } if (this.SelectionStart == this.Text.Length && this.Units == null && valueAndUnits.Length > 1 && valueAndUnits[1] != "" && !eventArgs.Changes.Any(c => c.RemovedLength > 0)) { string rest = TermLength.CompleteUnit(valueAndUnits[1]); this.SelectionLength = rest.Length; this.Text += rest; } #endif }
/// <summary> /// Handle the LostFocus event. If necessary, swap in the last valid value. /// </summary> /// <param name="eventArgs">The event arguments.</param> protected override void OnLostKeyboardFocus(KeyboardFocusChangedEventArgs eventArgs) { // When the user is done editing, making sure we have valid values for Length and Units. if (!this.IsReadOnly) { string[] valueAndUnits = this.Text.Split(new char[] { ' ' }); if (valueAndUnits.Length > 1) { string unitText = TermLength.CompleteUnit(valueAndUnits[1]); if (!String.IsNullOrEmpty(unitText)) { try { this.Units = TimeUnitList.Default.Find((TimeUnit)Enum.Parse(typeof(TimeUnit), unitText, true)).TimeUnitId; } catch { this.Units = null; } } } if (Regex.Match(valueAndUnits[0], @"^[-+]?\d*\.?\d").Success) { Boolean parsed = false; Decimal parsedValue = 0m; parsed = Decimal.TryParse(valueAndUnits[0], out parsedValue); this.Length = parsed ? (Decimal?)Math.Abs(parsedValue) : null; } if (this.Length == null) { this.Length = this.lastValue; } if (this.Units == null) { this.Units = TimeUnitList.Default.Find(this.lastUnits).TimeUnitId; } this.Text = String.Format("{0:0.###} {1}", this.Length, this.Units == null ? "" : (Object)(TimeUnitList.Default.Find(this.Units.Value).TimeUnitCode)); } base.OnLostKeyboardFocus(eventArgs); }
/// <summary> /// Handle the text of the control changing. Maintain the number-space-unit formatting as much as is possible. If the user is typing in the /// units, try to complete it for them. /// </summary> /// <param name="sender">The TermLength.</param> /// <param name="newText">The event arguments.</param> private static object CoerceText(DependencyObject sender, object newText) { #if false TermLength termLength = sender as TermLength; string text = newText as string; string[] valueAndUnits = text.Split(new char[] { ' ' }, StringSplitOptions.None); if (!String.IsNullOrEmpty(text) && !Regex.Match(text, @"^[-+]?\d*\.?\d+ +(Days|Weeks|Months)$").Success) { string value = ""; string units = ""; int caret = termLength.SelectionStart; if (valueAndUnits.Length >= 2) { value = TermLength.VerifyDecimal(valueAndUnits[0]); units = TermLength.VerifyUnit(valueAndUnits[1]); text = value + " " + units; } else if (valueAndUnits.Length == 1) { if (Regex.Match(valueAndUnits[0], @"\d|\.").Success) { value = TermLength.VerifyDecimal(valueAndUnits[0]); text = value; } else { units = TermLength.VerifyUnit(valueAndUnits[0]); text = units; } } if (caret < text.Length && caret >= 0) { termLength.SelectionStart = caret; } else { termLength.SelectionStart = text.Length; } } #endif return(newText); }
/// <summary> /// Create a converter and bind it to a TermLength. /// </summary> /// <param name="termLength">The TermLength object this converter is associated with.</param> public TermLengthConverter(TermLength termLength) { this.termLength = termLength; }