WPF / MVVM:带有命令禁用的wpf按钮的奇怪行为

时间:2010-07-27 21:08:06

标签: mvvm button command

只是一些代码...:问题在底部。

XAML

 <StackPanel Orientation="Horizontal">
            <Button Content="Start" Command="{Binding FirstDateCommand}" />
            <Button Content="Back" Command="{Binding PreviousDateCommand}" />
            <DatePicker SelectedDate="{Binding SelectedDate}" DisplayDateStart="{Binding MinDate}" DisplayDateEnd="{Binding MaxDate}" />
            <Button Content="Forward" Command="{Binding NextDateCommand}"  />
            <Button Content="End" Command="{Binding LastDateCommand}" />
        </StackPanel>

视图模型

public class LessonPlannerViewModel : ViewModelBase
    {    
        private ILessonPlannerRepository _lessonplannerRepo;    

        private ObservableCollection<LessonDay> _lessons;

        private RelayCommand _firstDateCommand;
        private RelayCommand _lastDateCommand;
        private RelayCommand _nextDateCommand;
        private RelayCommand _previousDateCommand;

        public LessonPlannerViewModel()
        {
            _lessonplannerRepo = new LessonPlannerRepository();

            MinDate = DateTime.Now.AddDays(-2);
            MaxDate = DateTime.Now.AddDays(2);

            SelectedDate = DateTime.Now;                   
        }

        public RelayCommand FirstDateCommand
        {
            get { return _firstDateCommand ?? (_firstDateCommand = new RelayCommand(() => MoveFirstDate(), () => CanMoveFirstDate())); }
        }

        public RelayCommand LastDateCommand
        {
            get { return _lastDateCommand ?? (_lastDateCommand = new RelayCommand(() => MoveLastDate(), () => CanMoveLastDate())); }
        }

        public RelayCommand PreviousDateCommand
        {
            get { return _previousDateCommand ?? (_previousDateCommand = new RelayCommand(() => MovePreviousDate(), () => CanMovePreviousDate())); }
        }

        public RelayCommand NextDateCommand
        {
            get { return _nextDateCommand ?? (_nextDateCommand = new RelayCommand(() => MoveNextDate(), () => CanMoveNextDate())); }
        }

        private void MoveFirstDate()
        {
            SelectedDate = MinDate;
            Lessons = _lessonplannerRepo.GetLessonDayByDate(SelectedDate);
        }

        private void MoveLastDate()
        {
            SelectedDate = MaxDate;
            Lessons = _lessonplannerRepo.GetLessonDayByDate(SelectedDate);
        }

        private void MoveNextDate()
        {
            SelectedDate = SelectedDate.AddDays(1);
            Lessons = _lessonplannerRepo.GetLessonDayByDate(SelectedDate);
        }

        private void MovePreviousDate()
        {
            SelectedDate = SelectedDate.AddDays(-1);
            Lessons = _lessonplannerRepo.GetLessonDayByDate(SelectedDate);
        }

        private bool CanMoveFirstDate()
        {
            return SelectedDate != MinDate;
        }

        private bool CanMoveLastDate()
        {
            return SelectedDate != MaxDate;
        }

        private bool CanMoveNextDate()
        {
            return SelectedDate < MaxDate;
        }

        private bool CanMovePreviousDate()
        {
            return SelectedDate > MinDate;
        }   

        private DateTime _selectedDate;
        public DateTime SelectedDate
        {
            get { return _selectedDate; }
            set
            {
                if (_selectedDate == value)
                    return;

                _selectedDate = value;
                this.RaisePropertyChanged("SelectedDate");
                //Lessons = _lessonplannerRepo.GetLessonDayByDate(SelectedDate);
            }
        }

        public DateTime MinDate { get; set; }

        public DateTime MaxDate { get; set; }        

        public ObservableCollection<LessonDay> Lessons
        {
            get { return _lessons; }
            set
            {
                _lessons = value;
                this.RaisePropertyChanged("Lessons");
            }
        }
...

当我在DatePicker中选择一个等于MinDate的日期时,PreviousDateCommand返回CanExecute = false; t 帽子好并按预期工作

但为什么LastDateCommand 也没有返回CanExecute = false?

当我按 PreviousDateButton 代替通过 datepicker 选择日期时,我的CanExecute逻辑按预期工作。

我错了什么?

更新

我没有怀疑我的逻辑是错的但是...我尝试了一些事情和这段代码

这真的很奇怪。我现在更改了LastDate和PreviousDate CanExecute方法的逻辑,两个按钮现在都可以更改datepicker。

private bool CanMoveFirstDate()
{
    Debug.WriteLine("SelectedDate FirstDate: " + SelectedDate);
    return SelectedDate > MinDate;
}

private bool CanMovePreviousDate()
{
    Debug.WriteLine("SelectedDate PreviousDate: " + SelectedDate);
    return SelectedDate > MinDate;
}

有人知道如何使NextDate + LastDate按钮正常工作获得解决方案! :P

更新2:

绑定很强大但可能很难控制......

我再次做了一些疯狂的逻辑,现在似乎有效:

        private bool CanMoveNextDate()
        {
            Debug.WriteLine("SelectedDate NextDate: " + SelectedDate);
            return SelectedDate.AddDays(1) < MaxDate;
        }

        private bool CanMoveLastDate()
        {
            Debug.WriteLine("SelectedDate LastDate: " + SelectedDate);
            return SelectedDate.AddDays(1) < MaxDate;
        }  

如果有人可以解释那个奇怪的逻辑,那就太好了,我认为原因在于datepicker和命令的绑定以及哪个绑定首先更新或被调用等等...

1 个答案:

答案 0 :(得分:2)

tststs ...这对我来说真的是一个教训:

而不是把它放在viewmodel构造函数中:

MinDate = DateTime.Now.AddDays(-2);
MaxDate = DateTime.Now.AddDays(2);

把这个:

MinDate = DateTime.Parse("28.07.2010 00:00:00");
MaxDate = DateTime.Parse("01.08.2010 00:00:00");

因为SelectedDate总是这样格式化:

dd.MM.yyyy 00:00:00

我想说微软感谢你在VS 2010中的出色调试工具=&gt;

http://img833.imageshack.us/img833/5912/cryforariver.png

而且我已经诅咒了wpf绑定系统:P一个该死的用户错误现在去打我了

值得拥有!但要点是我的:P