我正在用Xamarin Forms做一个智力竞赛游戏,对于分数函数,如果用户得到了正确的答案,我希望分数加1。但在我的情况下,即使答案正确,分数也不会增加。
我也试图绑定到";得分;变量转换为标签。我想知道我是否使用了正确的代码。
按钮
private void submit_Clicked(object sender, EventArgs e)
{
string answer = this.answer.Text;
string canswer = "correct";
if (answer != null)
{
string ranswer = answer.Replace(" ", string.Empty);
if (ranswer.ToLower() == canswer)
{
DisplayAlert("GoodJob", "You got the correct answer", "OK");
bindingModel b = new bindingModel();
b.score++;
(sender as Button).IsEnabled = false;
}
else
{
DisplayAlert("Unfortunately", "Your answer is wrong", "OK");
(sender as Button).IsEnabled = false;
}
}
}
ViewModel
public class bindingModel : INotifyPropertyChanged
{
public event PropertyChangedEventHandler PropertyChanged;
public int displayScore => Score;
public int score = 0;
void OnPropertyChanged(int score)
{
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(score.ToString()));
}
public int Score
{
get => score;
set
{
if (score != value)
{
score = value;
OnPropertyChanged(score);
}
}
}
}
型号
<Label Text="{Binding Score}"/>
在页面构造函数中,保留对VM 的引用
bindingModel VM;
// this is your constructor, the name will match your page name
public MyPage()
{
InitializeComponent();
this.BindingContext = VM = new bindingModel();
...
}
然后在事件处理程序中,不需要创建新的bindingModel
// update the Count on the VM
VM.Count++;
答案
这里有两样东西坏了:
- 您正在重新初始化ViewModel,而不是引用同一个实例
- 您将错误的值传递到
PropertyChangedEventArgs
1.引用视图模型
您每次都通过调用bindingModel b = new bindingModel();
来重新初始化ViewModel
让我们初始化ViewModel一次,将其存储为字段,将其设置为ContentPage
的BindingContext
,并在submit_Clicked
中引用该字段
public partial class QuizPage : ContentPage
{
readonly bindingModel _bindingModel;
public QuizPage()
{
_bindingModel = new bindingModel();
BindingContext = _bindingModel;
}
private async void submit_Clicked(object sender, EventArgs e)
{
string answer = this.answer.Text;
string canswer = "correct";
Button button = (Button)sender;
if (answer != null)
{
string ranswer = answer.Replace(" ", string.Empty);
if (ranswer.ToLower() == canswer)
{
await DisplayAlert("GoodJob", "You got the correct answer", "OK");
_bindingModel.score++;
button.IsEnabled = false;
}
else
{
await DisplayAlert("Unfortunately", "Your answer is wrong", "OK");
button.IsEnabled = false;
}
}
}
}
2.PropertyChangedEventArgs
您需要将属性的名称传递给PropertyChangedEventArgs
。
PropertyChanged
的工作方式是公布已更改的属性的名称。在这种情况下,它需要广播Score
属性已更改。
让我们使用nameof(Score)
将字符串"Score"
传递给PropertyChangedEventArgs
:
void OnScorePropertyChanged()
{
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(nameof(displayScore)));
}
public int Score
{
get => score;
set
{
if (score != value)
{
score = value;
OnScorePropertyChanged();
}
}
}