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

发布于 2024-09-11 15:24:40 字数 5558 浏览 9 评论 0原文

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

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>

ViewModel

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; 没问题,并且按预期工作

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

当我按下 PreviousDateButton 而不是选择日期时,我的 CanExecute 逻辑按预期工作通过日期选择器

我有什么错吗?

更新

我没有任何怀疑我的逻辑是错误的,但是......我尝试了一些东西,对于这段代码,

这真的很奇怪。我现在更改了 LastDate 和 PreviousDate CanExecute 方法的逻辑,并且两个按钮现在都可以更改日期选择器。

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

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

just some code...: Question is at bottom.

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>

ViewModel:

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");
            }
        }
...

When I choose in the DatePicker a date which is equal to MinDate then the PreviousDateCommand returns CanExecute = false; thats ok and works as expected.

But why is the LastDateCommand not returning CanExecute = false too?

My CanExecute logic works as expected, when I press the PreviousDateButton instead of selecting the date via datepicker.

What do I wrong?

UPDATE:

I have not had any doubts that my logic is wrong but... I tried some things and with this code

this is really weird. I changed now the logic of the LastDate and PreviousDate CanExecute method and both buttons work now changing the datepicker.

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

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

Is someone knows how to make the NextDate + LastDate button working gets the solution! :P

UPDATE 2:

Bindings are powerfull but maybe hard to control...

I did some crazy logic shit again and now it seems to work:

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

If someone can explain that weird logic, that would be nice , I think the cause lays in the binding of the datepicker and the commands and which binding gets updated first or is called etc...

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

云淡月浅 2024-09-18 15:24:40

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

我想说 Microsoft 感谢他们在 VS 2010 中提供的出色的调试工具 =>

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

我已经诅咒了 wpf 绑定系统 :P 一个该死的用户错误,现在去扇我一巴掌,我

活该!但积分是我的:P

tststs... this is really a lesson to me:

Instead of putting this is the viewmodel constructor:

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

put this:

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

because SelectedDate is always formatted like this:

dd.MM.yyyy 00:00:00

I want to say Microsoft thank you for their great debugging tools in VS 2010 =>

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

and I already cursed the wpf binding system :P a god damn user error now go and slap me I

deserve it! but the points are mine :P

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文