You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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框架注册单例服务,将共享数据封装在服务类中,注入到需要的页面。这种方式比静态类更灵活,便于后续单元测试。

步骤:

  1. 创建共享服务接口与实现类:
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; }
}
  1. 在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; }
  1. 在页面中获取服务实例:
var bleService = (IBLEDataService)App.ServiceProvider.GetService(typeof(IBLEDataService));
// 设置数据
bleService.CurrentDeviceName = "测试蓝牙设备";
// 读取数据
var data = bleService.ReceivedBLEData;

3. MessagingCenter消息传递(适合通知场景)

如果需要在数据更新时主动通知其他页面,可使用MessagingCenter实现页面间的解耦通信,无需直接引用页面实例。

示例:

  1. 发送数据的页面(BLE回调中触发):
// 发送设备连接成功的消息,携带设备ID
MessagingCenter.Send<object, string>(this, "DeviceConnected", "Device_456");
  1. 接收数据的页面:
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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.12 00:35:25