You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

基于MVVM模式实现DatePicker变更时刷新表单数据

实现MVVM模式下DatePicker日期变更刷新表单数据

看起来你想要用MVVM模式实现DatePicker日期变更时自动刷新表单数据的功能,我来帮你调整现有代码,让它完全符合MVVM的规范,同时去掉冗余的事件绑定:

第一步:调整XAML代码,移除代码后置事件

首先把XAML里的DateSelected事件去掉,改用ViewModel属性绑定,同时把日期范围也绑定到ViewModel的属性:

<DatePicker x:Name="EntryDate" 
            Date="{Binding SelectedDate, Mode=TwoWay}"
            MinimumDate="{Binding LowerLimitDate}"
            MaximumDate="{Binding HighLimitDate}">
</DatePicker>
<Slider x:Name="SliderSleep" 
        Value="{Binding MoodEntry.Sleep, Mode=TwoWay}" 
        Minimum="0" 
        Maximum="5">
</Slider>

第二步:完善ViewModel的实现

你的ViewModel已经实现了INotifyPropertyChanged,但需要补充属性的变更通知逻辑,并且通过SelectedDate属性来监听日期变化,触发数据加载:

public class RegisterViewModel : INotifyPropertyChanged
{
    private MoodEntry _moodEntry;
    private DateTime _selectedDate;
    private DateTime _lowerLimitDate;
    private DateTime _highLimitDate;

    public event PropertyChangedEventHandler PropertyChanged;

    // 绑定到表单控件的MoodEntry实例,变更时通知UI刷新
    public MoodEntry MoodEntry
    {
        get => _moodEntry;
        set
        {
            if (_moodEntry != value)
            {
                _moodEntry = value;
                OnPropertyChanged(nameof(MoodEntry));
            }
        }
    }

    // 绑定到DatePicker的选中日期,变更时加载对应数据
    public DateTime SelectedDate
    {
        get => _selectedDate;
        set
        {
            if (_selectedDate != value)
            {
                _selectedDate = value;
                OnPropertyChanged(nameof(SelectedDate));
                LoadMoodEntryForDate(value);
            }
        }
    }

    public DateTime LowerLimitDate
    {
        get => _lowerLimitDate;
        set
        {
            if (_lowerLimitDate != value)
            {
                _lowerLimitDate = value;
                OnPropertyChanged(nameof(LowerLimitDate));
            }
        }
    }

    public DateTime HighLimitDate
    {
        get => _highLimitDate;
        set
        {
            if (_highLimitDate != value)
            {
                _highLimitDate = value;
                OnPropertyChanged(nameof(HighLimitDate));
            }
        }
    }

    public RegisterViewModel()
    {
        LowerLimitDate = new DateTime(2018, 1, 1);
        HighLimitDate = DateTime.Today;
        SelectedDate = DateTime.Today; // 初始化加载今日数据
    }

    // 根据选中日期从数据库加载MoodEntry
    private void LoadMoodEntryForDate(DateTime date)
    {
        var entry = App.MoodDatabase.GetMoodEntry(date);
        // 如果没有对应日期的记录,创建新实例并设置日期
        MoodEntry = entry ?? new MoodEntry { EntryDate = date };
    }

    // 触发属性变更通知的通用方法
    protected void OnPropertyChanged(string propertyName)
    {
        PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
    }
}

第三步:完善MoodEntry模型(可选但推荐)

为了让MoodEntry的属性变更也能实时通知UI,建议让模型也实现INotifyPropertyChanged:

namespace myMood.Models
{
    [Table("MoodEntries")]
    public class MoodEntry : INotifyPropertyChanged
    {
        private int _moodEntryId;
        private DateTime _entryDate;
        private int _sleep;
        // 其他属性按需添加

        public event PropertyChangedEventHandler PropertyChanged;

        [PrimaryKey, AutoIncrement, Column("MoodEntryID")]
        public int MoodEntryId
        {
            get => _moodEntryId;
            set
            {
                if (_moodEntryId != value)
                {
                    _moodEntryId = value;
                    OnPropertyChanged(nameof(MoodEntryId));
                }
            }
        }

        public DateTime EntryDate
        {
            get => _entryDate;
            set
            {
                if (_entryDate != value)
                {
                    _entryDate = value;
                    OnPropertyChanged(nameof(EntryDate));
                }
            }
        }

        public int Sleep
        {
            get => _sleep;
            set
            {
                if (_sleep != value)
                {
                    _sleep = value;
                    OnPropertyChanged(nameof(Sleep));
                }
            }
        }

        protected void OnPropertyChanged(string propertyName)
        {
            PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
        }
    }
}

为什么这样做?

  • 完全遵循MVVM模式:所有业务逻辑都在ViewModel中处理,没有代码后置的事件绑定,UI和逻辑完全分离。
  • 自动刷新:当用户选择新日期时,SelectedDate的setter会触发数据加载,MoodEntry属性变更时会通知UI刷新所有绑定的控件(比如Slider的Sleep值)。
  • 可扩展性:后续如果需要添加更多日期相关的逻辑,只需要在ViewModel中修改,不需要改动XAML。

内容的提问来源于stack exchange,提问作者Lasse Edsvik

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.19 03:21:14