.NET MAUI中ViewModel传值后GraphicsView无法获取Path绘制图形
.NET MAUI完全支持跨ViewModel传参完成图形绘制,你遇到的Draw方法无法获取Path属性的问题,和传参逻辑无关,是Drawable绑定方式和绘制时机的问题。
核心问题点
- 你当前在XAML中为GraphicsView引用静态Drawable资源,该静态实例与GraphicViewModel实例完全独立,Draw方法执行时的上下文是静态资源实例,无法访问ViewModel中通过导航接收的动态参数。
- 导航参数是页面导航完成后才通过QueryProperty赋值给ViewModel的,GraphicsView首次触发Draw时Graphiclist属性还未完成赋值,且属性赋值后没有主动触发视图重绘,导致后续即使拿到了参数也不会重新执行绘制逻辑。
修复方案
1. 调整GraphicsView的Drawable绑定关系
移除静态Drawable资源引用,直接将Drawable绑定到当前页面的BindingContext(即GraphicViewModel实例,你直接让ViewModel实现IDrawable的写法是可行的,无需额外封装Drawable类)。
给GraphicPage.xaml中的GraphicsView添加名称并修改绑定:
<FlexLayout> <GraphicsView x:Name="DrawCanvas" Drawable="{Binding .}" HeightRequest="400" WidthRequest="400"/> </FlexLayout>
{Binding .}代表直接绑定当前上下文,也就是挂载到页面的GraphicViewModel实例,Draw方法执行时的this就是持有导航参数的ViewModel对象。
2. 增加参数赋值后的重绘触发逻辑
利用CommunityToolkit.Mvvm源生成器的属性变更回调,在Graphiclist接收到导航参数后,主动通知GraphicsView重绘。修改GraphicViewModel代码如下:
[QueryProperty(nameof(Graphiclist), "GRAPHICModel")] public partial class GraphicViewModel : ObservableObject, IDrawable { [ObservableProperty] private GRAPHICModel graphiclist; partial void OnGraphiclistChanged(GRAPHICModel value) { // 切到UI线程触发重绘 Application.Current?.Dispatcher.Dispatch(() => { if (Shell.Current.CurrentPage is GraphicPage currentPage) { var canvas = currentPage.FindByName<GraphicsView>("DrawCanvas"); canvas?.Invalidate(); } }); } public void Draw(ICanvas canvas, RectF dirtyRect) { // 首次加载参数为空时直接跳过,避免空引用 if (Graphiclist?.Path == null) { return; } // 配置绘制参数 canvas.StrokeSize = 2; canvas.StrokeColor = Colors.DarkSlateGray; // 正常读取Path属性完成绘制 canvas.DrawPath(Graphiclist.Path); } }
3. 可选校验项
你当前Label可以正常显示GraphicName,说明跨ViewModel传参、导航参数接收的逻辑本身是通顺的,无需调整MainPage和MainViewModel的代码。如果后续遇到复杂对象传值丢失,只需要确保GRAPHICModel是引用类型、无循环引用即可,同进程内Shell导航传递复杂对象默认是传引用,不会丢值。
内容的提问来源于stack exchange,提问作者ErengKo
相关产品推荐
相关产品推荐

