C# MAUI中逐回合更新动物地图图像的问题求助
解决MAUI每回合更新图像显示问题
核心问题总结
MAUI实验项目中,地图动物逻辑验证正常,但图像矩阵仅显示首张或全部回合结束后才更新,需实现每回合实时刷新对应图像。
具体修改方案
1. 修复Simulation类的线程阻塞问题
将Thread.Sleep替换为await Task.Delay,避免阻塞UI线程,同时修正异步方法签名:
class Simulation { // 保留原有字段和构造函数 // 把async void改为async Task,避免异步陷阱 public async Task Start(Visualisation visualisation) { while (_statistics.TurnsCount < MaxTurns) { Update?.Invoke(); Move?.Invoke(_map); await Task.Delay(_delay); // 替换Thread.Sleep,不阻塞UI线程 await visualisation.GenerateImageArrayAsync(); } } }
同时修改GamePage的调用逻辑:
private async void StartGame(object sender, EventArgs e) { var gameModel = new GameModel(); var simulation = new Simulation(gameModel.map); var visualisation = new Visualisation(gameModel.map, this); await visualisation.AddImagesToPage(); await simulation.Start(visualisation); // 加上await确保异步流程正确 }
2. 修改图像绑定逻辑,保留绑定关系
图像控件的BindingContext应指向MyString实例,而非其属性,确保绑定能响应属性变更:
async public Task AddImagesToPage() { var horisontalStackLayout = new StackLayout { Orientation = StackOrientation.Horizontal, BackgroundColor = new Color(255, 255, 255), }; foreach (var row in _priorityMap) { var verticalStackLayout = new StackLayout { Orientation = StackOrientation.Vertical }; foreach (var item in row) { var image = new Image { HeightRequest = 25, WidthRequest = 25, BindingContext = item // 绑定到MyString实例 }; // 明确绑定到ValueString属性 image.SetBinding(Image.SourceProperty, nameof(MyString.ValueString)); verticalStackLayout.Children.Add(image); } horisontalStackLayout.Children.Add(verticalStackLayout); } _gamePage.Content = horisontalStackLayout; await GenerateImageArrayAsync(); }
3. 优化图像源更新逻辑,触发绑定刷新
不要直接替换MyString实例,而是修改现有实例的ValueString属性,利用INotifyPropertyChanged触发界面更新,同时确保在UI线程执行:
public async Task GenerateImageArrayAsync() { // 后台计算所有需要更新的图像源,避免阻塞UI var updateList = new List<(int i, int j, string source)>(); for (int i = 0; i < _gameModelMap.GetLength(0); i++) { for (int j = 0; j < _gameModelMap.GetLength(1); j++) { var source = EasyVisualisation(_gameModelMap[i, j]) ?? "square.png"; updateList.Add((i, j, source)); } } // 回到UI线程更新绑定属性 await MainThread.InvokeOnMainThreadAsync(() => { foreach (var update in updateList) { _priorityMap[update.i][update.j].ValueString = update.source; } }); }
同时可以删除原有的UpdatePriorityMap方法,因为上述代码已包含更新逻辑。
修改后效果
每回合动物移动逻辑执行后,会异步等待指定延迟,然后在UI线程更新所有图像的绑定源,触发界面实时刷新,实现每回合显示对应图像的需求。
内容的提问来源于stack exchange,提问作者yungazzz
相关产品推荐
相关产品推荐

