1

私はWPFでカスタム日付コンバーターを実装しています。これは、日付入力についてより賢くするためのアイデアであり、Outlookのように(「今日」を入力できるなど)、機能している独自のコンバーターを作成しました。ユーザーのエントリを M/d/yy の形式でフォーマットします。たとえば、「8-2」と入力すると、8/2/09 と表示されます。素晴らしい。

問題は、ユーザーが入力できるものがいくつかあり、最終的に同じ日付になるということです。(簡単な例として、8-2 と 8/2)。つまり、8/2 と入力して開始し、ConvertBack と Convert を介して実行され、8/2/09 と表示されるとしましょう。ここまでは順調ですね。次に、同じフィールドに 8-2 (または 8/2) を入力したとします。これは、バインドされたプロパティに既に存在する同じ日付を生成する ConvertBack を介して実行されるため、わざわざ Convert を実行する必要はありません。つまり、「8/2」がテキスト ボックスに表示されます。ヤッ!データの問題はなく、表示上の問題はありますが、きれいさが重要です。

WPF にすべての (エラー以外の) エントリの後に Convert を実行させるにはどうすればよいですか?

コンバーターの簡略化されたバージョンを次に示します。

    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
}

使用方法は次のとおりです。

      <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>

ありがとう!スコット

以下のコメントへの応答として、バッキング プロパティを次に示します。

      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
        }
    }
4

2 に答える 2

3

バッキングデータプロパティがPropertyChanged実際に値を変更した場合にのみ起動する可能性はありますか?PropertyChanged値が変化するかどうかに関係なく、set関数が呼び出されるたびに起動を試みることができます。これにより、バインディングが更新されます。

于 2009-04-22T21:19:29.267 に答える
0

Josh G に感謝します - 彼の助けを借りて、私は (または少なくとも) 答えを見つけました。

これは、私が作成している DatePicker コントロール内のテキスト ボックス用でした。したがって、テキスト ボックスをコントロールの値に直接 "ロック" するのではなく、依存関係プロパティのセットを呼び出す中間プロパティを作成しました。

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

これは完全に正常に機能します。ありがとう、ジョシュ!

于 2009-04-24T17:00:00.220 に答える