1

単純なDatePickerを定義しました。

<DatePicker SelectedDate="{Binding SomeDate}"/>

また、特定の条件下でユーザーが値をクリアできないようにしたいと思います。

これが私がこれまでに得たものです:

public DateTime? SomeDate
{
    get { return someDate; }
    set
    {
        if (someDate != value)
        {
            if (value == null && someCondition)
                TellTheUserHeCannotClearTheField();
            else
                someDate = value;
            NotifyPropertyChanged(() => SomeDate);
        }
    }
}

これにより、基になるフィールドが更新されなくなりますが、DatePickerは空の値(つまり、「<ここにテキストを入力>」)を表示し、ユーザーがタブで移動するたびにプロパティをnullに更新しようとします。

DatePickerに現在の変更されていない値を表示させるにはどうすればよいですか?


Docのコメントの回答に基づいて、これを少し一般化させてください。

ドロップダウンを使用すると、この方法で日付の変更を拒否できます(たとえば、範囲を制限したい場合)。

ただし、キーボードを使用する場合、入力した内容はすべてそこに残り、DatePickerはフォーカスを失うたびにキーボードをコミットしようとします。

4

3 に答える 3

1

私はかなり良い修正を見つけました。

問題は、SelectedDateプロパティが正しく更新されているのに、Textプロパティ(表示されているもの)が同期していないことです。

したがって、同期を維持するためのヘルパーを作成しました。

public class SelectedDateSyncBehavior
{
    public static readonly DependencyProperty SyncTextProperty =
        DependencyProperty.RegisterAttached("SyncText", typeof(bool), 
            typeof(SelectedDateSyncBehavior), new PropertyMetadata(false, 
                                                  HandleSyncTextChanged));

    static void HandleSyncTextChanged(DependencyObject d, 
                                      DependencyPropertyChangedEventArgs e)
    {
        if ((bool)e.NewValue)
            ((DatePicker)d).LostFocus += SyncText;
        else
            ((DatePicker)d).LostFocus -= SyncText;
    }

    static void SyncText(object sender, RoutedEventArgs e)
    {
        var picker = (DatePicker)sender;
        if (picker.SelectedDate != null)
            picker.Text = picker.SelectedDate.Value.ToShortDateString();
    }

    public static void SetSyncText(DatePicker element, bool value)
    {
        element.SetValue(SyncTextProperty, value);
    }

    public static bool GetSyncText(DatePicker element)
    {
        return (bool)element.GetValue(SyncTextProperty);
    }
}

今私がしなければならないのは:

<DatePicker SelectedDate="{Binding SomeDate}" 
            myns:SelectedDateSyncBehavior.SyncText="True"/>
于 2013-01-22T20:53:26.877 に答える
0

再現できないようです。

私は次のようにプロパティを設定しましたTestDate

private DateTime? _testDate = DateTime.Now;

public DateTime? TestDate {
  get { return _testDate; }
  set {
    if (value < DateTime.Now)
      System.Windows.MessageBox.Show("BAD!");
    else
      _testDate = value;
    OnPropertyChanged("TestDate");
  }
}

そして、そのようなDatePicker:

<DatePicker SelectedDate="{Binding TestDate}" />

そしてこれが私の行動です:

  • 「悪い」日付の選択(1月16日)

ここに画像の説明を入力してください

  • 悪いメッセージ

ここに画像の説明を入力してください

  • 元の値から変更されていない値

ここに画像の説明を入力してください

  • 選ばれた良い日(作品)

ここに画像の説明を入力してください

この例は、あなたがやろうとしていることと同じですよね?(私のMVVMの実装は少し異なります。)

于 2013-01-22T18:18:42.727 に答える
-1

標準のWPFにはのDatePickerようなものはありませんIsReadOnly。ユーザー入力を防ぐ唯一の方法は、それを無効にすることです。

<DatePicker SelectedDate="{Binding SomeDate}" IsEnabled="{Binding AllowEditSomeDate}"/>

ViewModel:

public bool AllowEditSomeDate {get;set;} //Do not forget INotifyPropertyChanged
于 2013-01-22T15:36:55.127 に答える