iCosmin iCosmin - 3 years ago 211
C# Question

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.

I was hoping INotifyPropertyChanged would take care of that. 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

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

Answer Source

The reason it isn't working is because in your ViewModel, you are only executing the code to set the efficiency in the constructor. 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:

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));
        }
    }
}
Recommended from our users: Dynamic Network Monitoring from WhatsUp Gold from IPSwitch. Free Download