Xamarin.Forms多页面共享C#变量问题求助
跨页面共享数据的可行方案
1. 静态类存储共享数据
直接创建静态类封装共享变量,所有页面可直接访问。由于BLE操作多涉及异步回调,必须加线程锁保证线程安全,避免竞态问题。
示例代码:
public static class BLESharedData { private static readonly object _lockObj = new object(); private static string _connectedDeviceId; private static int _latestBLEValue; public static string ConnectedDeviceId { get { lock(_lockObj) return _connectedDeviceId; } set { lock(_lockObj) _connectedDeviceId = value; } } public static int LatestBLEValue { get { lock(_lockObj) return _latestBLEValue; } set { lock(_lockObj) _latestBLEValue = value; } } }
页面中直接调用:
// 设置数据 BLESharedData.ConnectedDeviceId = "Device_123"; // 读取数据 var currentDevice = BLESharedData.ConnectedDeviceId;
2. 依赖注入(DI)单例服务
用Xamarin.Forms内置的DI框架注册单例服务,将共享数据封装在服务类中,注入到需要的页面。这种方式比静态类更灵活,便于后续单元测试。
步骤:
- 创建共享服务接口与实现类:
public interface IBLEDataService { string CurrentDeviceName { get; set; } int ReceivedBLEData { get; set; } } public class BLEDataService : IBLEDataService { public string CurrentDeviceName { get; set; } public int ReceivedBLEData { get; set; } }
- 在
App.xaml.cs中注册单例:
public App() { InitializeComponent(); var services = new ServiceCollection(); services.AddSingleton<IBLEDataService, BLEDataService>(); ServiceProvider = services.BuildServiceProvider(); MainPage = new CustomFlyoutPage(); // 你的飞侧栏主页面 } public static IServiceProvider ServiceProvider { get; private set; }
- 在页面中获取服务实例:
var bleService = (IBLEDataService)App.ServiceProvider.GetService(typeof(IBLEDataService)); // 设置数据 bleService.CurrentDeviceName = "测试蓝牙设备"; // 读取数据 var data = bleService.ReceivedBLEData;
3. MessagingCenter消息传递(适合通知场景)
如果需要在数据更新时主动通知其他页面,可使用MessagingCenter实现页面间的解耦通信,无需直接引用页面实例。
示例:
- 发送数据的页面(BLE回调中触发):
// 发送设备连接成功的消息,携带设备ID MessagingCenter.Send<object, string>(this, "DeviceConnected", "Device_456");
- 接收数据的页面:
protected override void OnAppearing() { base.OnAppearing(); // 订阅消息 MessagingCenter.Subscribe<object, string>(this, "DeviceConnected", (sender, deviceId) => { // 处理接收到的设备ID Console.WriteLine($"已连接设备:{deviceId}"); }); } protected override void OnDisappearing() { base.OnDisappearing(); // 取消订阅,避免内存泄漏 MessagingCenter.Unsubscribe<object, string>(this, "DeviceConnected"); }
注意事项
- 静态类必须加锁,因为BLE回调多在后台线程执行,直接读写会引发线程安全问题。
- 依赖注入时必须注册为单例,否则每个页面会获取不同实例,无法共享数据。
- 使用MessagingCenter务必在页面消失时取消订阅,防止内存泄漏。
内容的提问来源于stack exchange,提问作者ste1n12
相关产品推荐
相关产品推荐

