Xamarin.Forms Shell如何在不同ViewModel之间传递对象
Xamarin.Forms Shell ViewModel间传对象方案说明
可行性结论
方案1和方案3均为可行方案,具体实现步骤如下:
方案1:序列化JSON字符串传递
适合小体积对象传递,无需依赖高版本Xamarin.Forms
- 依赖准备:在共享项目中安装Newtonsoft.Json或System.Text.Json对应的NuGet包
- 发送端逻辑:将对象序列化后做URL编码,作为字符串参数拼接在跳转路由后
代码示例:// 待传递的自定义对象 var product = new Product { Id = 1001, Name = "测试商品", Price = 29.9 }; // 序列化并编码 string json = JsonConvert.SerializeObject(product); string encodedParam = Uri.EscapeDataString(json); // 执行跳转 await Shell.Current.GoToAsync($"ProductDetailPage?productData={encodedParam}"); - 接收端逻辑:实现
IQueryAttributable接口,解码后反序列化得到对象
代码示例:public class ProductDetailViewModel : IQueryAttributable { public Product CurrentProduct { get; set; } public void ApplyQueryAttributes(IDictionary<string, object> query) { if (query.ContainsKey("productData")) { string encodedJson = query["productData"].ToString(); string rawJson = Uri.UnescapeDataString(encodedJson); CurrentProduct = JsonConvert.DeserializeObject<Product>(rawJson); } } } - 限制:序列化后的字符串长度如果过大,可能出现系统截断问题,不适合传递嵌套层级深、字段多的大体积对象。
方案3:直接传递对象
为最优方案,仅支持Xamarin.Forms 4.4及以上版本,无序列化性能损耗
- 发送端逻辑:将对象直接存入参数字典,作为
GoToAsync方法的第二个参数传入
代码示例:var order = new Order { Id = 2024001, TotalAmount = 199.9, Address = "测试地址" }; var param = new Dictionary<string, object> { { "OrderInfo", order } }; // 带参数跳转 await Shell.Current.GoToAsync("OrderDetailPage", param); - 接收端逻辑:实现
IQueryAttributable接口,直接从参数中取出对应类型的对象
代码示例:public class OrderDetailViewModel : IQueryAttributable { public Order CurrentOrder { get; set; } public void ApplyQueryAttributes(IDictionary<string, object> query) { if (query.TryGetValue("OrderInfo", out var orderObj) && orderObj is Order order) { CurrentOrder = order; } } } - 注意:该方案传递的是对象的引用,接收端修改对象属性会同步影响发送端的原始对象,如果需要隔离修改,传递前需对对象做深拷贝处理。
内容的提问来源于stack exchange,提问作者Jesse Liberty
相关产品推荐
相关产品推荐

