I'm trying to implement a datepicker and bind it to a model I've created. I've made a global tournament object in App.xaml.cs:
private Tournament _tournament;
public Tournament tournament {
get { return _tournament; }
set { _tournament = value; OnPropertyChanged("tournament"); }
}
And I've made an OnStartup override to launch my windows:
protected override void OnStartup(StartupEventArgs e)
{
base.OnStartup(e);
//setup score
score = new Score();
// Tournament setup
tournament = new Tournament();
tournament.GamesToWin = 1;
tournament.Games = new List<Game>(1);
tournament.Players = new List<Player>(2) { new Player(), new Player() };
//tournament.TimeAndDate = new DateTime(2021, 11, 22);
tournament.Winner = null;
// Initializing the UserInput
UserInput userInput = new UserInput();
UserInputWindowViewModel userinputViewModel = new UserInputWindowViewModel();
userInput.DataContext = userinputViewModel;
// Opening the UserInput Window
bool? res = userInput.ShowDialog();
// If the UserInput Window is closed, open the next Window
if (res == true)
{
// Opening the MainWindow
MainWindow main = new MainWindow();
main.Show();
}
else
{
Shutdown();
}
}
Model.cs (Tournament.cs):
public class Tournament : INotifyPropertyChanged
{
private Player _winner;
private DateTime? _timeAndDate;
private List<Player> _players;
public List<Player> Players
{
get { return _players; }
set { _players = value; OnPropertyChanged("Players"); }
}
private List<Game> _games;
public List<Game> Games
{
get { return _games; }
set { _games = value; OnPropertyChanged("Games"); }
}
private int _gamesToWin;
public int GamesToWin
{
get { return _gamesToWin; }
set { _gamesToWin = value; OnPropertyChanged("GamesToWin"); }
}
public Player Winner
{
get { return _winner; }
set { _winner = value; OnPropertyChanged("Winner"); }
}
public DateTime? TimeAndDate
{
get { return _timeAndDate; }
set { _timeAndDate = value; OnPropertyChanged("TimeAndDate"); }
}
#region PropertyChanged Members
public event PropertyChangedEventHandler PropertyChanged;
private void OnPropertyChanged(string propertyName)
{
PropertyChangedEventHandler handler = PropertyChanged;
if (handler != null)
handler(this, new PropertyChangedEventArgs(propertyName));
}
#endregion
}
ViewModel.cs (UserInputWindowViewModel.cs):
public class UserInputWindowViewModel
{
// Calling the current app to access the tournament object globally
public App currentApp = Application.Current as App;
#region The players object
private List<Player> _players;
public List<Player> Players
{
get { return _players; }
set { _players = value; }
}
#endregion
#region The DateTime object
private DateTime? _dateTime;
public DateTime? TournamentDateTime
{
get { return _dateTime; }
set { _dateTime = value; }
}
#endregion
public UserInputWindowViewModel()
{
Tournament tournament = currentApp.tournament;
Players = tournament.Players;
TournamentDateTime = new DateTime(2021, 11, 22);
tournament.TimeAndDate = TournamentDateTime;
//TournamentDateTime = tournament.TimeAndDate;
}
#region ICommand Members
private ICommand mUpdater;
public ICommand UpdateCommand
{
get
{
if (mUpdater == null)
mUpdater = new Updater();
return mUpdater;
}
set
{
mUpdater = value;
}
}
private class Updater : ICommand
{
public bool CanExecute(object parameter) => true;
public event EventHandler CanExecuteChanged;
public void Execute(object parameter)
{
}
}
#endregion
}
Inside my window (UserInput.xaml) I have the following Datepicker:
<DatePicker SelectedDate="{Binding TournamentDateTime, Mode=TwoWay}"/>
I've set the date inside my viewmodel to 22-11-2021 as test, but when I change the date, it's not changing. What am I doing wrong?
EDIT: I also tried the OnPropertyChanged in the ViewModel, which didn't work
CodePudding user response:
You forgot to implement INotifyPropertyChanged
under UserInputWindowViewModel.cs
.
public class UserInputWindowViewModel : INotifyPropertyChanged
{
}
Also make sure you are triggering PropertyChanged
event in property setter, it's important for two-way binding
public DateTime? TournamentDateTime
{
get { return _dateTime; }
set
{
_dateTime = value;
OnPropertyChanged(nameof(TournamentDateTime);
}
}
I'd also would suggest not to access Application
directly from a view model, better pass tournament
object as a dependency to a view model as soon it would be better separation of concerns
CodePudding user response:
I managed to fix my problem: I made a small function to update my global model:
public void updateModel(DateTime? s)
{
currentApp.tournament.TimeAndDate = s;
}
I've added this small bit of code to my getter/setter inside my viewmodel (notice I used DateTime.Now to set it to the current date):
private DateTime? _dateTime = DateTime.Now;
public DateTime? TournamentDateTime
{
get { return _dateTime; }
set { _dateTime = value; updateModel(value); }
}
This fixed all my problems with the datepicker. And I didn't have to use INotifyPropertychanged inside my viewmodel because my model already had it implemented.