Forçando Converter para sempre correr ao usar conversor personalizado no WPF?

StackOverflow https://stackoverflow.com/questions/779243

  •  13-09-2019
  •  | 
  •  

Pergunta

Estou implementando um conversor de data personalizado no WPF, a idéia de ser mais inteligente sobre a entrada de data, a la Outlook (poder entrar "hoje", etc.) Então eu escrevi o meu próprio conversor, que é trabalhando. Ele formata a entrada do usuário no formato M / d / aa. Assim, por exemplo, se eles entram: 8-2, ele verá 8/2/09. Encantador.

A questão é: há várias coisas que o usuário pode inserir que, finalmente, resultar na mesma data. (2/8 e 8/2, sendo exemplos simples). Então vamos apenas dizer que eles começam inserindo 8/2, que é executado através ConvertBack e converter, e é exibido como 8/2/09. Por enquanto, tudo bem. Agora vamos dizer que eles entram 8-2 (ou 8/2 de novo) no mesmo campo, logo depois. Isso é executado embora ConvertBack, que produz a mesma data que já está lá na propriedade ligada, por isso não se preocupa em executar Convert, o que significa que que "8/2" está sentado lá na caixa de texto. Yick! Não há nenhum problema de dados, apenas uma exibição de um, mas hey, as contagens asseio.

Como posso forçar WPF para executar Convert depois de tudo (não erro) entradas?

Aqui está uma versão simplificada do conversor:

    public class DateConverter : IValueConverter
{
    #region IValueConverter Members

    public object Convert(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
    {
        if (value != null)
        {
            string tempStr = value.ToString();
            return ((DateTime.Parse(tempStr)).ToString("M/d/yy"));
        }
        else
        {
            return null;
        }
    }

    public object ConvertBack(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
    {
        return DateTime.Parse(value.ToString());
    }

    #endregion
}

e aqui está o que o uso de ele se parece com:

      <local:FilteredTextBox.Text>
        <Binding Path="Value" ElementName="root" Converter="{StaticResource DateConv}" 
           UpdateSourceTrigger="LostFocus"  Mode="TwoWay" diagnostics:PresentationTraceSources.TraceLevel="High"
        NotifyOnValidationError="True" ValidatesOnDataErrors="True" ValidatesOnExceptions="True">
          <Binding.ValidationRules>
                <local:DateValidation/>
          </Binding.ValidationRules>
        </Binding>
      </local:FilteredTextBox.Text>

Obrigado! Scott

Em resposta a um comentário abaixo, aqui é a propriedade backing:

      public DateTime? Value
    {
        get
        {
            return (DateTime?)GetValue(ValueProperty);
        }
        set
        {
            SetValue(ValueProperty, value);
            OnPropertyChanged(new DependencyPropertyChangedEventArgs(ValueProperty, null, value)); // I just added this line, it makes no difference
        }
    }
Foi útil?

Solução 2

Muito obrigado a Josh G - com a sua ajuda, eu descobri o (ou pelo menos uma) resposta .

Este foi para uma caixa de texto dentro de um controle DatePicker eu estou criando. Então ao invés de "bloqueio" caixa de texto diretamente para o valor do controle, eu criei uma propriedade intermediária, que em seguida, chama o conjunto para a propriedade de dependência:

  public DateTime? DateValue
    {
        get
        {
            return _dateValue;
        }
        set
        {
            _dateValue = value;
            OnPropertyChanged("DateValue");
            SetValue(ValueProperty, _dateValue);
        }
    }

e isso totalmente funciona como deveria. Obrigado mais uma vez, Josh!

Outras dicas

É possível que a propriedade de dados de apoio só é disparando PropertyChanged se ele realmente muda de valor? Você poderia tentar disparar PropertyChanged sempre que a função conjunto é chamado, independentemente do valor muda. Isso faria com que a ligação seja atualizada.

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top