我第一次尝试实现 ViewModel 绑定,发现绑定到视图模型中的属性的标签没有更新以反映该值 我认为我正在做的事情很愚蠢,但希望有人看看并提供帮助。
视图模型:
public class MainPageViewModel : INotifyPropertyChanged
{
public MainPageViewModel()
{
}
public MainPageViewModel(List<Player> _players, GameType _selectedGame)
{
this.Players = _players;
this.SelectedGame = _selectedGame;
//Device.BeginInvokeOnMainThread(() =>
//{
// Players = _players;
// SelectedGame = _selectedGame;
//});
}
private List<Player> players;
public List<Player> Players
{
get { return players; }
set
{
players = value;
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs("Players")); //might need collectionchanged here
}
}
private GameType selectedGame;
public GameType SelectedGame
{
get { return selectedGame; }
set
{
selectedGame = value;
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs("SelectedGame"));
}
}
public event PropertyChangedEventHandler PropertyChanged;
}
游戏类型:
public class GameType : INotifyPropertyChanged
{
private string _name = "";
public string Name
{
get { return _name; }
set { _name = value;
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs("Name"));
}
}
public event PropertyChangedEventHandler PropertyChanged;
//will have scoring and rules
}
主页控制:
<StackLayout x:Name="stackLayoutScoring" Grid.Column="3" Grid.RowSpan="4">
<Label x:Name="labelGameType" Text="{Binding SelectedGame.Name}" HorizontalTextAlignment="Center" />
MainPageViewModel(有一些我尝试过的东西):
public class MainPageViewModel : INotifyPropertyChanged
{
public MainPageViewModel()
{
}
public MainPageViewModel(List<Player> _players, GameType _selectedGame)
{
this.Players = _players;
this.SelectedGame = _selectedGame;
//Device.BeginInvokeOnMainThread(() =>
//{
// Players = _players;
// SelectedGame = _selectedGame;
//});
}
private List<Player> players;
public List<Player> Players
{
get { return players; }
set
{
players = value;
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs("Players"));
}
}
private GameType selectedGame;
public GameType SelectedGame
{
get { return selectedGame; }
set
{
selectedGame = value;
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs("SelectedGame"));
}
}
public event PropertyChangedEventHandler PropertyChanged;
}
}
游戏开始事件参数:
public class GameStartedEventArgs : EventArgs, INotifyPropertyChanged
{
public GameStartedEventArgs(Game game)
{
_Game = game;
}
private Game _game;
public Game _Game
{
get { return _game; }
set { _game = value; PropertyChanged?.Invoke(this, new PropertyChangedEventArgs("_Game")); }
}
public event PropertyChangedEventHandler PropertyChanged; //PropertyChanged?.Invoke(this, new PropertyChangedEventArgs("Name"));
}
主页代码:
public void InitGame(Game game)
{
//initialize points and setup first player
stackLayoutScoring.BindingContext = viewModel;
viewModel.Players = game.Players;
viewModel.SelectedGame = game.SelectedGame;
//stackLayoutScoring.BindingContext = viewModel;
}
现在 viewModel 在 MainPage.cs 中接收到正确的值,但 labelGameType.Text 永远不会更新。 我不确定从异步方法调用 InitGame() 是否会导致问题:
async void GameStartedAlert(object sender, GameStartedEventArgs e)
{
await DisplayAlert("Success!", Statics.CurrentGame.SelectedGame.Name + ": Game Started!", "OK");
InitGame(e._Game);
}
我正在努力找出问题所在。我希望这是愚蠢的事情。
谢谢,
迈克
我的问题是由于页面之间导航不正确而引起的。
我正在使用
async void NavigateToMainPage(object sender, EventArgs e)
{
await Navigation.PushAsync(new MainPage());
}
它创建 MainPage 的新实例,与具有数据绑定的实例并行。我用以下方法修复了它:
public void NavigateToMainPage()
{
App.Current.MainPage.Navigation.PopAsync();
}
感谢 Jason 发现我的代码的另一个问题。