【问题标题】:WPF - MVVM BindingsWPF - MVVM 绑定
【发布时间】:2017-03-03 12:35:19
【问题描述】:

我的应用程序有问题,尤其是 WPF MVVM 中的绑定。 我创建了模型、视图模型和视图,这是我的代码的一部分(仅与我的问题有关)当我单击按钮 nemed : PointUp 我想查看 Team1 点的数量。谁能告诉我我做错了什么?

查看

    <Window x:Class="Tabu.Game
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
        xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
        xmlns:local="clr-namespace:Tabu"
        xmlns:vm="clr-namespace:Tabu.ViewModel"
        mc:Ignorable="d"
        Title="Game"  Height="600" Width="900" Background="Beige">
    <Window.DataContext>
        <vm:TeamStatistic />
    </Window.DataContext>
    <Grid>
        <Button x:Name="PointUp" Command="{Binding AddPoints }" Content="+"/>
        <Label x:Name="PointsTeam1_label" Content="{Binding Team1.TeamPoints, UpdateSourceTrigger=PropertyChanged }"/>
</Grid>

型号

'

namespace Tabu.Model
{
    public class Team
    {
        public bool IsTeamActive { get;  set; }
        public int TeamMiss { get;  set; }
        public int TeamPoints { get;  set; }
        public int TeamMistake { get;  set; }
    }
}
'

视图模型

namespace Tabu.ViewModel
{
    class TeamStatistic : INotifyPropertyChanged

    {
        public Team Team1 = new Team();

        public int TeamPoints
        {
            get { return TeamPoints; }
            set { TeamPoints = value; OnPropertyChanged("TeamPoints"); }
        }

        public ICommand AddPoints
        {
            get { return new RelayCommand(() => Add_Points()); }
        }

        public void Add_Points()
        {
            Team1.TeamPoints++;
        }

        public event PropertyChangedEventHandler PropertyChanged;

        private void OnPropertyChanged(params string[] propsName)
        {
            if (PropertyChanged!=null)
            {
                foreach(string propName in propsName)
                PropertyChanged(this, new PropertyChangedEventArgs(propName));
            }
        }
    }

public class RelayCommand : ICommand
    {
        private readonly Func<bool> canExecute;
        private readonly Action execute;

        public RelayCommand(Action execute)
            : this(execute, null) { }

        public RelayCommand(Action execute, Func<bool> canExecute)
        {
            if (execute == null) throw new ArgumentNullException("execute");
            this.execute = execute;
            this.canExecute = canExecute;
        }

        public event EventHandler CanExecuteChanged
        {
            add { if (this.canExecute != null) CommandManager.RequerySuggested += value; }
            remove { if (this.canExecute != null) CommandManager.RequerySuggested -= value; }
        }

        public Boolean CanExecute(object parameter) { return this.canExecute == null ? true : this.canExecute(); }
        public void Execute(object parameter) { this.execute(); }
    }
}

【问题讨论】:

    标签: c# wpf mvvm


    【解决方案1】:

    问题出在这里:

    public int TeamPoints
    {
        get { return TeamPoints; } //should be Team1.TeamPoints
        set { TeamPoints = value; OnPropertyChanged("TeamPoints"); } //should be Team1.TeamPoints
    }
    

    ViewModel 中的TeamPoints 属性中,您返回并从ViewModel 设置相同的属性TeamPoints,但您应该从Model (Team1) 设置。你应该返回并设置Team1.TeamPoints

    public int TeamPoints
    {
        get { return Team1.TeamPoints; }  
        set { Team1.TeamPoints = value; OnPropertyChanged("TeamPoints"); }
    }
    

    还有Add_Points()

    public void Add_Points()
    {
        Team1.TeamPoints++;
        OnPropertyChanged("TeamPoints");
    }
    

    【讨论】:

      【解决方案2】:

      你必须像这样更新你的绑定。

      <Label x:Name="PointsTeam1_label" Content="{Binding TeamPoints, UpdateSourceTrigger=PropertyChanged }"/>
      

      当您绑定到 Team1.TeamPoints 时,您将不会从 TeamPoints 属性内的 OnPropertyChanged 获得通知。

      【讨论】:

      • 是的,这是真的,我的错误 :) 它有效,但只是在开始时,点数仍然是相同的 exual 0。绑定不刷新
      • 啊,好的,我明白了。您在 AddTeamPoints 方法中更新 Team1.Teampoints,NotifyPropertyChanged 将不会再次触发。当你写 OnPropertyChanged("TeamPoints"); Team1.TeamPoints++ 之后;会好的。
      • 谢谢!我没注意到。
      【解决方案3】:

      我认为这是因为 AddPoints(命令绑定)。由于此命令已绑定并且您正在创建 RelayCommand 的实例并在每次它可能破坏绑定时返回。

      CommandBindings 的更好替代方法是声明属性并在视图模型的构造函数中初始化它们。

      例如:

      namespace Tabu.ViewModel
      {
        class TeamStatistic : INotifyPropertyChanged
      
        {
          public Team Team1 = new Team();
      
          public int TeamPoints
          {
              get { return Team1.TeamPoints; }
              set { Team1.TeamPoints = value; OnPropertyChanged("TeamPoints"); }
          }
      
          private ICommand _AddPoints;
      
          public ICommand AddPoints
          {
              get { return _AddPoints; }
              set { _AddPoints = value; }
          }
      
          public void Add_Points()
          {
              Team1.TeamPoints++;
          }
      
          public TeamStatistic ()
          {
              _AddPoinss = new RelayCommand(Add_Points);
          }
      
          public event PropertyChangedEventHandler PropertyChanged;
      
          private void OnPropertyChanged(params string[] propsName)
          {
              if (PropertyChanged!=null)
              {
                  foreach(string propName in propsName)
                  PropertyChanged(this, new PropertyChangedEventArgs(propName));
              }
          }
      }
      

      【讨论】:

        猜你喜欢
        • 2021-03-01
        • 2017-05-01
        • 1970-01-01
        • 2015-05-24
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2019-06-23
        相关资源
        最近更新 更多