简体   繁体   English

WPF - MVVM绑定

[英]WPF - MVVM Bindings

I have problem with my application, especially with Bindings in WPF MVVM. 我的应用程序有问题,尤其是WPF MVVM中的Bindings。 I created Model, ViewModel and View, this is part of my code (only this connected with my problem) When I click the button nemed : PointUp i want to see the amount of Team1 points. 我创建了Model,ViewModel和View,这是我的代码的一部分(只有这与我的问题相关)当我点击按钮nemed:PointUp我想看到Team1积分的数量。 Can anyone tell me what i'm doing wrong? 谁能告诉我我做错了什么?

View 视图

    <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>

Model 模型

'

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; }
    }
}
'

ViewModel 视图模型

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

The problem is here: 问题出在这里:

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

Inside your TeamPoints property in ViewModel you return and set the same property TeamPoints from ViewModel but you should set from Model ( Team1 ). ViewModelTeamPoints属性中,您返回并从ViewModel设置相同的属性TeamPoints ,但您应该从ModelTeam1 )进行设置。 You should return and set Team1.TeamPoints . 您应该返回并设置Team1.TeamPoints

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

And Add_Points() : Add_Points()

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

You have to update your Binding like this. 你必须像这样更新你的Binding。

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

When you bind to Team1.TeamPoints you will not get the Notification from OnPropertyChanged which is inside your TeamPoints property. 绑定到Team1.TeamPoints时,您将无法从TeamPoints属性中的OnPropertyChanged获取通知。

I reckon it is because of AddPoints (the command binding). 我认为这是因为AddPoints(命令绑定)。 Since this command is binded & you are creating an instance of RelayCommand & returning each time it might be breaking the binding. 由于此命令是绑定的,并且您正在创建RelayCommand的实例并在每次可能违反绑定时返回。

A better alternative with CommandBindings are to declare the property and initialize them in the Constructor of the view model. 使用CommandBindings的更好的替代方法是声明属性并在视图模型的构造函数中初始化它们。

Ex: 例如:

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

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM