Datepicker仅在键入日期时双重SelectedDateChanged事件

时间:2013-10-11 20:50:34

标签: c# wpf mvvm triggers datepicker

我有一些代码具有意外行为,具体取决于您使用DatePicker控件的方式。如果您通过鼠标选择日期来使用DatePicker,则会触发一次事件并且代码正常工作。虽然如果您输入事件被触发两次的日期。 这是我的xaml代码。

<DatePicker Margin="0,-1,0,0" Height="23" VerticalAlignment="Top"    HorizontalAlignment="Right" Width="190" SelectedDate="{Binding DaDate}">
    <i:Interaction.Triggers>
        <i:EventTrigger EventName="SelectedDateChanged">
            <i:InvokeCommandAction Command="{Binding SelectedDaDateChangedCommand}" />
        </i:EventTrigger>
    </i:Interaction.Triggers>
</DatePicker>

和c#位。

public ICommand SelectedDaDateChangedCommand { get; set; }
private DateTime? daDate;
public DateTime? DaDate
{
    get { return daDate; }
    set
    {
        daDate = value;
        NotifyOfPropertyChange(() => DaDate);
    }
}

public MisoConstraintsViewModel(IView v) : base(v)
{
    //This is where DoStuff() gets called twice from the SelectedDateChanged
    SelectedDaDateChangedCommand = new RelayCommand(p => DoStuff());
}

感谢任何帮助。感谢。

2 个答案:

答案 0 :(得分:1)

这是一种被动的方法,如果您不希望使用被动反应,则可以将相同的概念用于事件。从文本框中修改DatePicker时将触发两次,因为它在文本框中提交编辑时触发SelectedDateChanged,并在日历设置所选日期时再触发。我扩展了类,以便能够订阅我有更多控制权的东西。

我知道这是一个旧帖子,希望这有助于某人仍在寻找答案。

class CustomDatePicker : DatePicker
{

    private DateTime comparer;
    private Subject<DateTime> dateChangedSubject = new Subject<DateTime>();

    static CustomDatePicker()
    {
        // Override property changed callback for SelectedDate
        DatePicker.SelectedDateProperty.OverrideMetadata(typeof(CustomDatePicker), new FrameworkPropertyMetadata(SelectedDate_PropertyChanged));
    }

    /// <summary>
    /// Subscribe to this observable instead of SelectedDateChanged event
    /// It will only fire once when the selected date changes
    /// </summary>
    public IObservable<DateTime> DateChanged
    {
        get { return this.dateChangedSubject.AsObservable(); }
    }

    /// <summary>
    /// Checks if the comparer is equal to the new value
    /// If it is not, store the new value and fire changed subject
    /// </summary>
    /// <param name="d"></param>
    /// <param name="e"></param>
    private static void SelectedDate_PropertyChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
    {
        CustomDatePicker datePicker = d as CustomDatePicker;

        if(datePicker.comparer != (DateTime)e.NewValue)
        {
            datePicker.comparer = (DateTime)e.NewValue;
            datePicker.dateChangedSubject.OnNext((DateTime)e.NewValue);
        }
    }
}

可以像:

一样使用
customDatePicker.DateChanged.Subscribe(_ =>
{
    Console.WriteLine("DateChanged fired");
});

// use the passed DateTime value to do something
customDatePicker.DateChanged.Subscribe(dt =>
{
    //... do something with dt
});

答案 1 :(得分:0)

如果我说得对,DaDate属性连续设置两次。我建议检查以前的值

public DateTime? DaDate
{
 get { return daDate; }
 set
 {
    if(value != daDate)
    {
     daDate = value;
     NotifyOfPropertyChange(() => DaDate);
    }
 }
}

这无助于找出原因,但可能可以解决您的问题