【问题标题】:Unable to bind my DatePicker to my ViewModel无法将我的 DatePicker 绑定到我的 ViewModel
【发布时间】:2021-10-21 20:58:54
【问题描述】:

我正在尝试实现一个日期选择器并将其绑定到我创建的模型。 我在 App.xaml.cs 中创建了一个全球锦标赛对象:

private Tournament _tournament;
public Tournament tournament { 
    get { return _tournament; } 
    set { _tournament = value; OnPropertyChanged("tournament"); }  
}

我已经做了一个 OnStartup 覆盖来启动我的窗口:

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
}

在我的窗口 (UserInput.xaml) 中,我有以下 Datepicker:

<DatePicker SelectedDate="{Binding TournamentDateTime, Mode=TwoWay}"/>

我已将视图模型中的日期设置为 22-11-2021 作为测试,但是当我更改日期时,它并没有改变。我做错了什么?

编辑:我还尝试了 ViewModel 中的 OnPropertyChanged,但没有成功

【问题讨论】:

    标签: c# wpf data-binding


    【解决方案1】:

    你忘了在UserInputWindowViewModel.cs下实现INotifyPropertyChanged

    public class UserInputWindowViewModel : INotifyPropertyChanged
    {
    }
    

    还要确保在属性设置器中触发PropertyChanged 事件,这对于双向绑定很重要

    public DateTime? TournamentDateTime
    {
        get { return _dateTime; }
        set 
        {
             _dateTime = value; 
             OnPropertyChanged(nameof(TournamentDateTime);
         }
    }
    

    我还建议不要直接从视图模型访问 Application,最好将 tournament 对象作为依赖项传递给视图模型,因为这样可以更好地分离关注点

    【讨论】:

    • 我试过你的建议,但没有奏效。现在我的模型和视图模型中都有一个 propertychangedevent
    • 你能分享更新的代码吗?
    • gist.github.com/Jartim00/44b7976b4856ef939fd5a1ce48f082e7 我试过同时使用 DateTime 和 DateTime?测试代码的对象
    • @hoekrand 你实际上并没有从INotifyPropertyChanged 继承。看看我更新的答案
    • 哦!你是对的。我再试一次。编辑:我从 INotifyPropertychanged 继承了,但仍然一无所有...
    【解决方案2】:

    我设法解决了我的问题: 我做了一个小函数来更新我的全局模型:

    public void updateModel(DateTime? s)
    {
        currentApp.tournament.TimeAndDate = s;
    }
    

    我已将一小段代码添加到我的视图模型中的 getter/setter 中(注意我使用 DateTime.Now 将其设置为当前日期):

    private DateTime? _dateTime = DateTime.Now;
    public DateTime? TournamentDateTime
    {
        get { return _dateTime; }
        set { _dateTime = value; updateModel(value); }
    }
    

    这解决了我使用日期选择器的所有问题。而且我不必在我的视图模型中使用 INotifyPropertychanged,因为我的模型已经实现了它。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2012-03-18
      • 1970-01-01
      • 1970-01-01
      • 2020-03-06
      • 1970-01-01
      • 2018-05-10
      相关资源
      最近更新 更多