/// <summary> /// Позволяет корректировать данное свойство на основе других свойств. /// Этот Callback срабатывает вторым. /// </summary> /// <param name="d">Объект вызвавший Callback</param> /// <param name="value">Значение для корректировки</param> /// <returns>Скорректированное значение</returns> private static object CoerceValueString(DependencyObject d, object value) { XNumericBoxLite numBox = (XNumericBoxLite)d; double oldValue = numBox.Value; //Запоминаем старое значение string sVal = (value is null) ? "" : value.ToString(); if (string.IsNullOrEmpty(sVal))//(numBox._valueString))//Пустая строка является допустимой. Приводить к константе double.NaN { numBox.Value = double.NaN; DoValueChanged(numBox, oldValue); return(value); } //numBox._valueString = numBox._valueString.Replace(",", dec_sep).Replace(".", dec_sep); string dec_sep = System.Threading.Thread.CurrentThread.CurrentCulture.NumberFormat.NumberDecimalSeparator; sVal = sVal.Replace(",", dec_sep).Replace(".", dec_sep); double _val; //Нужна, чтобы TryParse не перезаписал _Value при неуспешной конвертации. То есть храним последнее успешно сконвертированное значение. bool IsNewValid = double.TryParse(sVal, out _val); //numBox._valueString, out _val); if (IsNewValid) //Если валидное значение, то сохраняем его { numBox.Value = _val; //if ((_val >= numBox.Min) && (_val <= numBox.Max)) //Если попадает в диапазон, то вызываем событие ValueChange if (IsInRange(_val, numBox.Min, numBox.Max, numBox.IncludeMin, numBox.IncludeMax, numBox.AllowEmptyValue)) { DoValueChanged(numBox, oldValue); } } //if (Regex.IsMatch(sVal, @"^\.\d*$|^\,\d*$")) // sVal = '0' + sVal; return(sVal); }
/// <summary> /// Позволяет корректировать другие свойства после изменения данного /// Этот Callback срабатывает третьим. /// </summary> /// <param name="d">Объект вызвавший Callback</param> /// <param name="e">Данные события изменения свойства</param> private static void OnValueStringChanged(DependencyObject d, DependencyPropertyChangedEventArgs e) { string oldVal = e.OldValue == null ? "" : e.OldValue.ToString(); string newVal = e.NewValue == null ? "" : e.NewValue.ToString(); bool isValid = (newVal is null) ? true : Regex.IsMatch(newVal, @"^$|^\d*\.\d+$|^\d*\,\d+$|^[0-9]+$|^[0-9]+[,.]{0,1}[0-9]*$|^[-][0-9]+$|^[-][0-9]+[,.]{0,1}[0-9]*$"); if (newVal != "") { double val = 0; if (double.TryParse(newVal, out val)) { XNumericBoxLite numBox = (XNumericBoxLite)d; //if ((val < (double)d.GetValue(MinProperty)) || (val > (double)d.GetValue(MaxProperty))) if (!IsInRange(val, numBox.Min, numBox.Max, numBox.IncludeMin, numBox.IncludeMax, numBox.AllowEmptyValue)) { isValid = false; } } else { isValid = false; } d.SetValue(IsValidProperty, isValid); } DoValueStringChanged(d, oldVal, newVal); //XNumericBoxLite numBox = (XNumericBoxLite)d; //double oldValue = numBox.Value; //Запоминаем старое значение //string sValueString = e.NewValue.ToString(); //if (string.IsNullOrEmpty(sValueString)) //Пустая строка является допустимой. Приводить к константе double.NaN //{ // numBox.Value = double.NaN; // DoValueChanged(numBox, oldValue); //} //string dec_sep = System.Threading.Thread.CurrentThread.CurrentCulture.NumberFormat.NumberDecimalSeparator; //sValueString = sValueString.Replace(",", dec_sep).Replace(".", dec_sep); //double _val; //Нужна, чтобы TryParse не перезаписал _Value при неуспешной конвертации. То есть храним последнее успешно сконвертированное значение. //bool IsNewValid = double.TryParse(sValueString, out _val); //if (IsNewValid) //Если валидное значение, то сохраняем его //{ // numBox.Value = _val; // if ((_val >= numBox.Min) && (_val <= numBox.Max)) //Если попадает в диапазон, то вызываем событие ValueChange // { // DoValueChanged(numBox, oldValue); // } //} // d.SetValue(ValueProperty, value); //SetValue(ValueProperty, value); //d.CoerceValue(GroupIndexProperty); //Пример вызова корректировки в другом свойстве }
/// <summary> /// Позволяет корректировать другие свойства после изменения данного /// Этот Callback срабатывает третьим. /// </summary> /// <param name="d">Объект вызвавший Callback</param> /// <param name="e">Данные события изменения свойства</param> private static void OnMinChanged(DependencyObject d, DependencyPropertyChangedEventArgs e) { double newMinVal = (double)e.NewValue; if (double.IsNaN(newMinVal)) { return; } string newVal = d.GetValue(ValueStringProperty) == null ? "" : d.GetValue(ValueStringProperty).ToString(); bool isValid = (newVal is null) ? true : Regex.IsMatch(newVal, @"^$|^\d*\.\d+$|^\d*\,\d+$|^[0-9]+$|^[0-9]+[,.]{0,1}[0-9]*$|^[-][0-9]+$|^[-][0-9]+[,.]{0,1}[0-9]*$"); if (newVal != "") { XNumericBoxLite numBox = (XNumericBoxLite)d; double val = 0; if (double.TryParse(newVal, out val)) { //if ((val < (double)d.GetValue(MinProperty)) || (val > (double)d.GetValue(MaxProperty))) if (!IsInRange(val, numBox.Min, numBox.Max, numBox.IncludeMin, numBox.IncludeMax, numBox.AllowEmptyValue, out string errMsg)) { numBox.Error = errMsg;// "Значение не входит в диапазон от " + numBox.Min + " до " + numBox.Max + "."; //(d as XNumericBoxLite).Error = "Значение не входит в диапазон от " + d.GetValue(MinProperty) + " до " + d.GetValue(MaxProperty) + "."; isValid = false; } } else { numBox.Error = "Значение не является действительным числом"; //(d as XNumericBoxLite).Error = "Значение не является действительным числом"; isValid = false; } d.SetValue(IsValidProperty, isValid); //d. Error. } }