2017-03-03 232 views
1

我的應用程序有問題,特別是WPF MVVM中的綁定。 我創建了模型,視圖模型和視圖,這是我的代碼的一部分(只有這與我的問題有關)當我點擊按鈕nemed:PointUp我想看看Team1點的數量。任何人都可以告訴我我做錯了什麼?WPF - MVVM綁定

查看

<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(); } 
    } 
} 

回答

1

你必須更新你的綁定這樣。

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

當您綁定到Team1.TeamPoints你不會得到OnPropertyChanged通知哪個是你的TeamPoints物業內。

+0

是的它的真實,我的錯誤:)它的工作原理,但只在開始時,點的數量仍然是相同的0。綁定不會刷新 – Arkady

+0

啊,好吧,我看到了問題。 您在AddTeamPoints方法中更新Team1.Teampoints,NotifyPropertyChanged將不會再次觸發。 當你寫OnPropertyChanged(「TeamPoints」);在Team1.TeamPoints ++之後;它會沒事的。 –

+0

謝謝!我沒有注意到。 – Arkady

2

的問題是在這裏:

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

裏面你TeamPoints財產ViewModel返回,並從ViewModel設置相同屬性TeamPoints但你應該從ModelTeam1)設置。您應該返回並設置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"); 
} 
+0

好的,謝謝但我仍然沒有看到我的觀點 – Arkady

0

我認爲這是因爲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)); 
     } 
    } 
} 
+0

P.S:RelayCommand類保持不變。 – Ankit