0

我有一些代码具有意外行为,具体取决于您使用 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());
}

任何帮助表示赞赏。谢谢。

4

2 回答 2

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
});
于 2016-02-17T23:18:34.997 回答
0

如果我没听错,DaDate属性会连续设置两次。我建议检查以前的值

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

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

于 2013-10-12T00:02:19.380 回答