/// <summary>
 /// Raises the ValueChanging event when Value property is changing.
 /// </summary>
 /// <param name="e">Event args.</param>
 protected virtual void OnValueChanging(RoutedPropertyChangingEventArgs <T> e)
 {
     if (ValueChanging != null)
     {
         ValueChanging(this, e);
     }
 }
        /// <summary>
        /// Raises the DropDownClosing event.
        /// </summary>
        /// <param name="e">
        /// Provides any observers the opportunity to cancel the operation
        /// and halt closing the drop down.
        /// </param>
        protected virtual void OnDropDownClosing(RoutedPropertyChangingEventArgs <bool> e)
        {
            RoutedPropertyChangingEventHandler <bool> handler = DropDownClosing;

            if (handler != null)
            {
                handler(this, e);
            }
        }
        /// <summary>
        /// ValueProperty property changed handler.
        /// </summary>
        /// <param name="d">UpDownBase whose Value changed.</param>
        /// <param name="e">Event arguments.</param>
        private static void OnValuePropertyChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
        {
            UpDownBase <T> source = (UpDownBase <T>)d;

            // Ignore the change if requested
            if (source._ignoreValueChange)
            {
                return;
            }

            T oldValue = (T)e.OldValue;
            T newValue = (T)e.NewValue;

            // simulate pre and post events
            // The Value has already been changed when this function is called.
            // So if user's chaning event handler check Value, it will be the changed value.
            // This is confusing, because we are simulating pre event on the platform that doesn't natively support it.
            RoutedPropertyChangingEventArgs <T> changingArgs = new RoutedPropertyChangingEventArgs <T>(e.Property, oldValue, newValue, true);

            source.OnValueChanging(changingArgs);

            // hack: work around the class hierarchy for value coercion in NumericUpDown
            if (changingArgs.InCoercion)
            {
            }
            else if (!changingArgs.Cancel)
            {
                newValue = (T)changingArgs.NewValue;
                ////if (!oldValue.Equals(newValue))
                ////{
                ////UpDownBaseAutomationPeer peer = nud.GetAutomationPeer() as UpDownBaseAutomationPeer;
                ////if (peer != null)
                ////{
                ////    peer.RaiseValuePropertyChangedEvent(oldValue, newValue);
                ////}
                RoutedPropertyChangedEventArgs <T> changedArgs = new RoutedPropertyChangedEventArgs <T>(oldValue, newValue);
                source.OnValueChanged(changedArgs);
                ////}
            }
            else
            {
                // revert back to old value if an event handler canceled the changing event.
                source._ignoreValueChange = true;
                source.Value = oldValue;
                source._ignoreValueChange = false;
            }
        }
        /// <summary>
        /// ValueProperty property changed handler.
        /// </summary>
        /// <param name="d">UpDownBase whose Value changed.</param>
        /// <param name="e">Event arguments.</param>
        private static void OnValuePropertyChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
        {
            TimePickerPopup source = (TimePickerPopup)d;

            // Ignore the change if requested
            if (source._ignoreValueChange)
            {
                // we do want to raise the event, but won't react to anything.
                source.OnValueChanged(new RoutedPropertyChangedEventArgs <DateTime?>(e.OldValue as DateTime?, e.NewValue as DateTime?));
                return;
            }

            DateTime?oldValue = (DateTime?)e.OldValue;
            DateTime?newValue = (DateTime?)e.NewValue;

            // simulate pre and post events
            // The Value has already been changed when this function is called.
            // So if user's chaning event handler check Value, it will be the changed value.
            // This is confusing, because we are simulating pre event on the platform that doesn't natively support it.
            RoutedPropertyChangingEventArgs <DateTime?> changingArgs = new RoutedPropertyChangingEventArgs <DateTime?>(e.Property, oldValue, newValue, true);

            source.OnValueChanging(changingArgs);

            // workaround the class hierarchy for value coercion
            if (changingArgs.InCoercion)
            {
            }
            else if (!changingArgs.Cancel)
            {
                newValue = changingArgs.NewValue;
                RoutedPropertyChangedEventArgs <DateTime?> changedArgs = new RoutedPropertyChangedEventArgs <DateTime?>(oldValue, newValue);
                source.OnValueChanged(changedArgs);

                TimePickerPopupAutomationPeer peer = FrameworkElementAutomationPeer.FromElement(source) as TimePickerPopupAutomationPeer;
                if (peer != null)
                {
                    peer.RaiseValueAutomationEvent(oldValue, newValue);
                }
            }
            else
            {
                // revert back to old value if an event handler canceled the changing event.
                source._ignoreValueChange = true;
                source.Value = oldValue;
                source._ignoreValueChange = false;
            }
        }
        /// <summary>
        /// Raises the ValueChanging event when Value property is changing.
        /// </summary>
        /// <param name="e">Event args.</param>
        /// <remarks>Cancels the event when the value is not part of the domain.</remarks>
        protected override void OnValueChanging(RoutedPropertyChangingEventArgs <object> e)
        {
            // value needs to be contained in the items collection.
            if (e != null && ((e.NewValue == null && GetActualItems().Count() > 0) ||
                              (e.NewValue != null && !GetActualItems().Contains(e.NewValue))))
            {
                e.Cancel = true;

                if (_valueDuringInitialization == null && e.NewValue != null)
                {
                    _valueDuringInitialization = e.NewValue;
                }
            }
            else
            {
                base.OnValueChanging(e);
            }
        }
        protected virtual void OnValueChanging(RoutedPropertyChangingEventArgs <DateTime?> e)
        {
            // change is from value itself.
            bool success = _timeCoercionHelper.CoerceValue(e.OldValue, e.NewValue);

            if (success)
            {
                e.InCoercion = false;
                e.NewValue   = Value;
                RoutedPropertyChangingEventHandler <DateTime?> handler = ValueChanging;
                if (handler != null)
                {
                    handler(this, e);
                }
            }
            else
            {
                e.InCoercion = true;
            }
        }
        /// <summary>
        /// Override UpDownBase&lt;T&gt;.OnValueChanging to do validation and coercion.
        /// </summary>
        /// <param name="e">Event args.</param>
        protected override void OnValueChanging(RoutedPropertyChangingEventArgs <double> e)
        {
            // Note: this section is a workaround, containing my
            // logic to hold all calls to the property changed
            // methods until after all coercion has completed
            // ----------
            if (_levelsFromRootCall == 0)
            {
                // validation
                EnsureValidDoubleValue(this, e.Property, e.OldValue, e.NewValue);

                _initialVal   = e.OldValue;
                _requestedVal = e.NewValue;
                e.InCoercion  = true;
            }
            _levelsFromRootCall++;
            // ----------

            CoerceValue();

            // Note: this section completes my workaround to call
            // the property changed logic if all coercion has completed
            // ----------
            _levelsFromRootCall--;
            if (_levelsFromRootCall == 0)
            {
                e.InCoercion = false;
                double value = Value;
                if (_initialVal != value)
                {
                    e.NewValue = Value;
                    base.OnValueChanging(e);
                }
            }
            // ----------
        }
        /// <summary>
        /// IsDropDownOpenProperty property changed handler.
        /// </summary>
        /// <param name="d">Picker that changed its IsDropDownOpen.</param>
        /// <param name="e">Event arguments.</param>
        private static void OnIsDropDownOpenPropertyChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
        {
            Picker source = (Picker)d;

            // Ignore the change if requested
            if (source._ignorePropertyChange)
            {
                source._ignorePropertyChange = false;
                return;
            }

            bool oldValue             = (bool)e.OldValue;
            bool newValue             = (bool)e.NewValue;
            bool delayedClosingVisual = source._popupClosedVisualState;
            RoutedPropertyChangingEventArgs <bool> args = new RoutedPropertyChangingEventArgs <bool>(e.Property, oldValue, newValue, true);

            PickerAutomationPeer peer = FrameworkElementAutomationPeer.FromElement(source) as PickerAutomationPeer;

            if (peer != null)
            {
                peer.RaiseExpandCollapseAutomationEvent(oldValue, newValue);
            }

            if (newValue)
            {
                // Opening
                source.OnDropDownOpening(args);

                // Opened
                if (!args.Cancel)
                {
                    source.OpenDropDown(oldValue, newValue);
                }
            }
            else
            {
                // Closing
                source.OnDropDownClosing(args);

                // Immediately close the drop down window:
                // When a popup closed visual state is present, the code path is
                // slightly different and the actual call to CloseDropDown will
                // be called only after the visual state's transition is done
                if (!args.Cancel && !delayedClosingVisual)
                {
                    source.CloseDropDown(oldValue, newValue);
                }
            }

            // If canceled, revert the value change
            if (args.Cancel)
            {
                // source._ignorePropertyChange = true;
                source.SetValue(e.Property, oldValue);
            }

            // Closing call when visual states are in use
            if (delayedClosingVisual)
            {
                source.UpdateVisualState(true);
            }
        }