简体   繁体   English

TwoWay绑定不适用于Datepicker MVVM

[英]TwoWay binding not working with datepicker MVVM

I've finally managed to get started with MVVM and implementing INotifyPropertyChanged and I am facing the following problem: Even though I pass the month from my datepicker as a parameter to my query, the result of my query doesn't change if I choose a different month. 我终于设法开始使用MVVM并实现了INotifyPropertyChanged,并且面临以下问题:即使我将datepicker的月份作为参数传递给查询,但是如果我选择了一个,就不会改变查询的结果不同的月份。

I was hoping INotifyPropertyChanged would take care of that. 我希望INotifyPropertyChanged会解决这个问题。 How do I make sure that my Efficiency changes when picking a different month from the datepicker? 与日期选择器选择不同的月份时,如何确保效率发生变化?

Thank you 谢谢

ViewModel 视图模型

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using Location.Model;
using System.Windows.Controls;

namespace Location.ViewModel
{
    public class LocationViewModel: INotifyPropertyChanged
    {


        public LocationViewModel()
        {
            var month = 0;
            int.TryParse(MDate.ToString("MM"), out month);
            var db = new DailyEntities();
            Efficiency = Convert.ToDecimal(db.LocationKPI.Where(a => a.sMonth == month).Select(a => a.Efficiency).FirstOrDefault());
        }

        private DateTime _mDate = DateTime.Now;

        public DateTime MDate
        {
            get { return _mDate; }
            set { _mDate = value; OnPropertyChanged("MDate"); }
        }

        decimal efficiency;

        public decimal Efficiency
        {
            get { return efficiency; }
            set
            {
                efficiency = value;
                OnPropertyChanged("Efficiency");
            }
        }


        public event PropertyChangedEventHandler PropertyChanged;

        protected virtual void OnPropertyChanged(string propertyName = null)
        {
            if (PropertyChanged != null) PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
        }
    }
}

View 视图

public partial class MainWindow : Window
{
    public MainWindow()
    {
        InitializeComponent();
        DataContext = new LocationViewModel();
    }
}

XAML XAML

<DatePicker x:Name="vDatePick" SelectedDateChanged="vDatePick_SelectedDateChanged" SelectedDate="{Binding MDate, Mode=TwoWay}" Text="Pick date"/>

You need state that Efficiency must be updated when MDate is 您需要声明必须在MDate时更新Efficiency

public DateTime MDate
{
   get { return _mDate; }
   set 
   { 
       _mDate = value; 
       OnPropertyChanged("MDate"); 
       OnPropertyChanged("Efficiency"); 
   }
}

I would also put the query for Efficiency in the getter and remove the setter. 我还将把Efficiency查询放在getter中,然后删除setter。 Which in turn would mean you no longer need the private variable efficiency and you would remove the query in the constructor. 反过来,这意味着您不再需要私有变量efficiency并且可以在构造函数中删除查询。

public decimal Efficiency
{
    get 
    {
        var month = 0;
        int.TryParse(MDate.ToString("MM"), out month);
        return Convert.ToDecimal(
            db.LocationKPI
                .Where(a => a.sMonth == month)
                .Select(a => a.Efficiency)
                .FirstOrDefault());
    }
}

EDIT: Updated Efficiency getter and setter 编辑:更新了Efficiency器和设置器

EDIT: Wanted to note you should probably set MDate to a default value in your constructor as well if you wanted to see results when the page loads. 编辑:要注意的是,如果您想在页面加载时看到结果,也应该在构造函数中将MDate设置为默认值。

The reason it isn't working is because in your ViewModel, you are only executing the code to set the efficiency in the constructor. 它不起作用的原因是因为在ViewModel中,您仅执行代码以在构造函数中设置效率。 You need to create a method and then call it from the constructor and the set of MDate, so Efficiency will be updated each time MDate changes: 您需要创建一个方法,然后从构造函数和MDate集中调用它,因此,每次MDate更改时,效率都会更新:

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using Location.Model;
using System.Windows.Controls;

namespace Location.ViewModel
{
    public class LocationViewModel: INotifyPropertyChanged
    {
        public LocationViewModel()
        {
            SetEfficiency();
        }

        private DateTime _mDate = DateTime.Now;

        public DateTime MDate
        {
            get { return _mDate; }
            set 
            {
                _mDate = value;
                OnPropertyChanged("MDate");
                SetEfficiency();
            }
        }

        decimal efficiency;

        public decimal Efficiency
        {
            get { return efficiency; }
            set
            {
                efficiency = value;
                OnPropertyChanged("Efficiency");
            }
        }

        DailyEntities db = new DailyEntities();

        private void SetEfficiency()
        {
            var month;
            int.TryParse(MDate.ToString("MM"), out month);
            Efficiency = Convert.ToDecimal(db.LocationKPI.Where(a => a.sMonth == month).Select(a => a.Efficiency).FirstOrDefault());
        }

        public event PropertyChangedEventHandler PropertyChanged;

        protected virtual void OnPropertyChanged(string propertyName = null)
        {
            if (PropertyChanged != null) PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
        }
    }
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM