Я реализовал пользовательский слайдер, который происходит из RangeBase, который имеет добавленное свойство ResetValue, которое можно использовать для сброса значения в начальное значение. К сожалению, для этого требуется двойное связывание источника значений, а также использование режима привязки OneTime для ResetValue.
<ButtonSlider
Minimum="0" Maximum="500" TickFrequency="1"
Value="{Binding Path=MaxVoltageUv}"
ResetValue="{Binding Path=MaxVoltageUv, Mode=OneTime}" />
В идеале у него было бы свойство логической зависимости CanReset, которое бы захватило ResetValue при первом связывании, если оно было включено. Я попытался реализовать его, захватив первый параметр Value, но по какой-то причине это работает только некоторое время.
Сначала он переопределяет метаданные в ValueProperty:
ValueProperty.OverrideMetadata(typeof(ButtonSlider), new FrameworkPropertyMetadata(OnValueChanged, OnCoerceValue));
А затем реализует измененные обработчики пользовательских транзакций и значений.
private static void OnValueChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
{
var buttonSlider = ((ButtonSlider)d);
if (buttonSlider != null)
{
if (!buttonSlider.valueInitialized && e.NewValue is double)
{
buttonSlider.resetValue = (double)e.NewValue;
buttonSlider.valueInitialized = true;
}
buttonSlider.CheckResetEnabled();
}
}
private static object OnCoerceValue(DependencyObject d, object baseValue)
{
var buttonSlider = ((ButtonSlider)d);
if (buttonSlider != null)
{
if(baseValue is double)
return Math.Max(Math.Min((double)baseValue, buttonSlider.Maximum), buttonSlider.Minimum);
}
return DependencyProperty.UnsetValue;
}
По какой-то причине OnValueChanged вызывается со значением 0, а исходное связывание должно быть равным 2. Это, по-видимому, связано с шаблонами данных. Элементы управления, которые не находятся в шаблоне данных, работают правильно.
Есть ли другой способ захватить начальное значение свойства зависимостей?
Если в XAML установлены как контекст данных, так и привязка, вы можете использовать событие Loaded вашего настраиваемого элемента управления, чтобы сохранить текущее значение в качестве значения сброса. Это также будет работать, если ваш элемент управления находится в шаблоне данных, например.
Если контекст данных задан из кода, это будет работать, только если оно установлено до того, как элемент управления будет добавлен в логическое дерево.
Мои мысли
MaxVoltageUv
которому вы привязываетесь, является двойным.ResetValue
это просто создает шум при попытке решить эту проблему.0
может быть значением по умолчанию для свойства зависимостей, которое устанавливается перед фактическим привязкой. Почему бы не поместить в -1.0
по умолчанию вместе с логикой в OnValueChanged
чтобы обнаружить этот сценарий и проигнорировать до тех пор, пока не произойдет надлежащее значение.