Xamarin.Forms Grid子元素错误触发TapGestureRecognizer事件问题求解
问题根源
该问题核心原因是:所有Hexagon.Shape元素未设置位置偏移,全部堆叠在Grid的默认单元格(第0行第0列)的左上角,最后添加的元素位于所有元素最上层,点击任意位置实际触发的都是最上层元素的手势事件。StackLayout会自动排列元素不存在堆叠,所以手势触发正常。
可行修复方案(保留Grid布局)
- 第一步:为每个Shape设置位置偏移,避免元素重叠
创建Hexagon时已经传入了x、y坐标,直接给Shape设置对应位移即可,代码修改如下:var hex = new Hexagon(id, x, y, 40); // 新增:设置Shape的偏移量,让元素显示到对应坐标 hex.Shape.TranslationX = x; hex.Shape.TranslationY = y; - 第二步:优化手势绑定逻辑,避免闭包捕获隐患
改用带参数的Command直接传递当前hex实例,规避C#闭包可能带来的变量捕获问题:void Tapped(Hexagon h) { h.SetHexaState(HexagonState.Tapped); } hex.Shape.GestureRecognizers.Add(new TapGestureRecognizer() { Command = new Command<Hexagon>(Tapped), CommandParameter = hex }); - 第三步:可选适配,保证手势响应正常
如果你的Shape默认是无背景的透明状态,主动设置透明背景色保证手势可以正常捕获:hex.Shape.BackgroundColor = Color.Transparent; - 第四步:Grid初始化适配(可选)
给Grid设置单个自适应行和列,保证所有元素可以在整个Grid区域内自由布局:var grid = new Grid() { RowDefinitions = new RowDefinitionCollection { new RowDefinition { Height = GridLength.Star } }, ColumnDefinitions = new ColumnDefinitionCollection { new ColumnDefinition { Width = GridLength.Star } } };
按上述修改后既可以保留Grid布局,也可以正常触发每个元素的点击事件。
内容的提问来源于stack exchange,提问作者Qhori
相关产品推荐
相关产品推荐

