Привязка к свойству зависимостей с CoercedValue имеет Confusing Behavior [duplicate]

Я нашел отзыв о подсказке полезным, чтобы устранить эту проблему в Tomcat -

, обязательно загрузите драйвер, сначала выполнив Class.forName («org.postgresql.Driver»); в вашем коде.

Это из сообщения - https://www.postgresql.org/message-id/e13c14ec050510103846db6b0e@mail.gmail.com

Код jdbc работал нормально как автономная программа, но в TOMCAT он дал ошибку «Не найден подходящий драйвер»

10
задан H.B. 7 September 2011 в 17:29
поделиться

3 ответа

Ничего себе, это удивительно. Когда вы устанавливаете значение в свойстве зависимостей, выражения привязки обновляются до запуска значения.

Если вы посмотрите на DependencyObject.SetValueCommon в Reflector, вы можете увидеть вызов Expression.SetValue на полпути через этот метод. Вызов UpdateEffectiveValue, который будет вызывать ваш CoerceValueCallback, находится в самом конце, после того, как привязка уже обновлена.

Вы также можете увидеть это в классах инфраструктуры. Из нового приложения WPF добавьте следующий XAML:

<StackPanel>
    <Slider Name="Slider" Minimum="10" Maximum="20" Value="{Binding Value, 
        RelativeSource={RelativeSource AncestorType=Window}}"/>
    <Button Click="SetInvalid_Click">Set Invalid</Button>
</StackPanel>

и следующий код:

private void SetInvalid_Click(object sender, RoutedEventArgs e)
{
    var before = this.Value;
    var sliderBefore = Slider.Value;
    Slider.Value = -1;
    var after = this.Value;
    var sliderAfter = Slider.Value;
    MessageBox.Show(string.Format("Value changed from {0} to {1}; " + 
        "Slider changed from {2} to {3}", 
        before, after, sliderBefore, sliderAfter));
}

public int Value { get; set; }

Если вы перетащите ползунок, а затем нажмите кнопку, вы получите сообщение типа «Значение изменилось с 11 на -1, слайдер изменился с 11 на 10».

10
ответ дан Quartermeister 20 August 2018 в 10:20
поделиться

Новый ответ для старого вопроса:: -)

При регистрации ValueProperty используется экземпляр FrameworkPropertyMetadata. Установите для свойства UpdateSourceTrigger этого экземпляра значение Explicit. Это можно сделать при перегрузке конструктора.

public static readonly DependencyProperty ValueProperty =
    DependencyProperty.Register("Value", typeof(int), typeof(NumericUpDown), 
    new FrameworkPropertyMetadata(
      0, 
      FrameworkPropertyMetadataOptions.BindsTwoWayByDefault | FrameworkPropertyMetadataOptions.Journal, 
      HandleValueChanged, 
      HandleCoerceValue,
      false
      UpdateSourceTrigger.Explicit));

Теперь источник привязки ValueProperty не будет автоматически обновляться на PropertyChanged. Сделайте обновление вручную в своем методе HandleValueChanged (см. Код выше). Этот метод называется только «реальными» изменениями свойства ПОСЛЕ того, как был вызван метод coerce.

Вы можете сделать это следующим образом:

static void HandleValueChanged(DependencyObject obj, DependencyPropertyChangedEventArgs args)
{
    NumericUpDown nud = obj as NumericUpDown;
    if (nud == null)
        return;

    BindingExpression be = nud.GetBindingExpression(NumericUpDown.ValueProperty);
    if(be != null)
        be.UpdateSource();
}

Таким образом, вы можете избегайте обновления привязок с помощью не принудительных значений вашего DependencyProperty.

3
ответ дан Fratyx 20 August 2018 в 10:20
поделиться
  • 1
    Хорошее обходное решение. :) – Greg D 5 August 2015 в 15:59
  • 2
    Новый вопрос для старого ответа :). У меня есть эта проблема, но «GetBindingExpression» возвращает null. Я пытаюсь принудить, когда значение связано! Он работает, когда значение задается пользователем. Итак, должна быть какая-то проблема контекста (не полностью загружена или что-то еще)? Любые указатели? – Werner 3 August 2018 в 10:18

Вы принудительно выполняете v, который является int и как таковой тип значения. Поэтому он хранится в стеке. Он никоим образом не связан с baseValue. Таким образом, изменение v не изменит baseValue.

То же самое относится к baseValue.

v возвращается и явно используется для обновления интерфейса.

Вы можете хотите исследовать изменение типа данных свойств в ссылочный тип. Затем он будет передан по ссылке, и любые сделанные изменения отразятся на исходном. Предполагая, что процесс привязки данных не создает копию.

-1
ответ дан Philip Smith 20 August 2018 в 10:20
поделиться
  • 1
    Разве он не получает коробку, если он возвращается как объект из метода принуждения? – Rob Perkins 24 July 2010 в 03:49
Другие вопросы по тегам:

Похожие вопросы: