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

Xamarin中XAML与XAML.cs绑定失效,如何正确配置DataContext?

Xamarin数据绑定问题:无法识别绑定变量,如何正确设置DataContext?

我是Xamarin新手,尝试将.xaml.cs中的数据绑定到.xaml文件,但应用无法识别绑定的变量。请问应如何正确使用DataContext来建立绑定连接?

以下是我的代码:

MainPage.xaml.cs

using System;
using System.Windows;

using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.ComponentModel;
using System.Linq;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
using System.Windows.Input;
using Plugin.BLE;
using Plugin.BLE.Abstractions.Contracts;
using Plugin.BLE.Abstractions.Exceptions;
using Xamarin.Forms;

namespace BT
{
    public partial class MainPage : ContentPage
    {
        
        #region MAINPAGE CONSTRUCTOR
        public MainPage()
        {
            InitializeComponent();
            initializeBluetooh();

        }
        #endregion
    
    
        #region BT constructor
        
        #endregion
        #region BT VARIABLES
        // bluetooth
        IBluetoothLE _handler;
        IAdapter _adapter;


        ObservableCollection<IDevice> _devicelist;
        ObservableCollection<IDevice> _devicelistAux;
        IDevice _connectedDevice;

        String _deviceName;
        String _bt_state;

        IReadOnlyList<IService> _services;
        Task<IReadOnlyList<ICharacteristic>> _characteristics;
        ICharacteristic _characteristic;
        IService _service;

        String _stringBuff;



        private Guid guid;

        IDevice deviceConn;

        #endregion
        #region BT OBJECTS
        public ObservableCollection<IDevice> devicelist
        {
            get { return _devicelist; }
            set { _devicelist = value; }
        }

        public IDevice connectedDevice
        {
            get { return _connectedDevice; }
            set { _connectedDevice = value; }
        }
        public IBluetoothLE handler
        {
            get { return _handler; }
            set { _handler = value; }
        }
        public IAdapter adapter
        {
            get { return _adapter; }
            set { _adapter = value; }
        }

        public IReadOnlyList<IService> services
        {
            get { return _services; }
            set { _services = value; }
        }
        public Task<IReadOnlyList<ICharacteristic>> characteristics
        {
            get { return _characteristics; }
            set { _characteristics = value; }
        }
        public IService service
        {
            get { return _service; }
            set { _service = value; }
        }
        public ICharacteristic characteristic
        {
            get { return _characteristic; }
            set { _characteristic = value; }
        }
        public String bt_state
        {
            get { return _bt_state; }
            set { _bt_state = value; }
        }



        #endregion
        #region BT FUNCTIONS
        public async void initializeBluetooh()
        {
            handler = CrossBluetoothLE.Current;
            adapter = CrossBluetoothLE.Current.Adapter;
            adapter.ScanMode = ScanMode.LowPower;

            adapter.ScanTimeout = 5000;

            devicelist = new ObservableCollection<IDevice>();


            bt_state = "BLUETOOTH INFO:\n";
            Console.WriteLine(bt_state);
                

        }
        public async void InitScanDevices(object sender, EventArgs e)
        {


            bt_state = "BLUETOOTH INFO:\n" +
                "\nBluetooth state: Scanning...";
            Console.WriteLine(bt_state);


            devicelist.Clear();
            adapter.DeviceDiscovered += (s, args) =>
            {

               IDevice dispositivoDescubierto = args.Device;
               devicelist.Add(dispositivoDescubierto);
               Console.WriteLine(dispositivoDescubierto.Name);

             };
            if (!handler.Adapter.IsScanning)
            {
                await adapter.StartScanningForDevicesAsync();

                bt_state = "BLUETOOTH INFO:\n" +
                "\nBluetooth state: Stopped Scanning";
                Console.WriteLine(bt_state);

            }
        }
        public async void OnCollectionViewSelectionChanged(object sender, SelectedItemChangedEventArgs e)
        {
            if (adapter.IsScanning)
            {
                await adapter.StopScanningForDevicesAsync();
            }
            var selectedDevice = (IDevice)e.SelectedItem;

            Console.WriteLine(selectedDevice.Name);
            try
            {
                Device.BeginInvokeOnMainThread(() =>
                {
                    adapter.ConnectToDeviceAsync(selectedDevice);
                    deviceConn = selectedDevice;

                });

            }
            catch (DeviceConnectionException)
            {
                //DisplayAlert("Error", "Could not connect to device", "Dismiss");
            }


        }

        #endregion
        #region BT COMMANDS
        
        #endregion
    }
}

MainPage.xaml

<?xml version="1.0" encoding="utf-8" ?>
<ContentPage xmlns="http://xamarin.com/schemas/2014/forms"
             xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
             x:Class="BT.MainPage">

    <StackLayout>
        <Label
            Margin="0,50,0,0"/>
        <Frame OutlineColor="White">
             <Label
            Text="BLUETOOTH CONNECTION"
            TextColor="Coral"
            />

        </Frame>
        <Frame OutlineColor="DarkBlue">
            <Label Text="{Binding bt_state}"/>
        </Frame>
       <Button
            Clicked="InitScanDevices"
            Text="Scan for devices"/>
        <ListView
            SelectionMode="Single"
            ItemSelected="OnCollectionViewSelectionChanged"
            ItemsSource="{Binding devicelist}"
            BackgroundColor="Aqua">
        <ListView.ItemTemplate>
            <DataTemplate>
                    
                       <TextCell Text="{Binding Name}" TextColor="Black"/>
                        
            </DataTemplate>
        </ListView.ItemTemplate>
           </ListView>

    </StackLayout>

</ContentPage>

解决步骤

1. 设置页面的DataContext

XAML绑定需要明确数据源,在页面构造函数中把DataContext设置为当前页面实例,让XAML知道要绑定的数据来自哪里:

public MainPage()
{
    InitializeComponent();
    // 设置数据源为当前页面
    DataContext = this;
    initializeBluetooh();
}

2. 实现INotifyPropertyChanged接口更新UI

当前代码中bt_state属性变化时,UI不会自动刷新,因为缺少属性变更通知机制。需要让MainPage实现INotifyPropertyChanged接口:

首先修改类定义:

public partial class MainPage : ContentPage, INotifyPropertyChanged
{
    // 声明属性变更事件
    public event PropertyChangedEventHandler PropertyChanged;

    // 触发事件的辅助方法
    protected virtual void OnPropertyChanged(string propertyName)
    {
        PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
    }

然后修改bt_state的setter,在赋值后触发通知:

public String bt_state
{
    get { return _bt_state; }
    set 
    { 
        _bt_state = value;
        // 通知UI属性已更新
        OnPropertyChanged(nameof(bt_state));
    }
}

3. 优化ObservableCollection的绑定

devicelist是ObservableCollection<IDevice>,本身支持集合元素变更通知,但如果直接重新赋值集合,也需要触发属性变更通知:

public ObservableCollection<IDevice> devicelist
{
    get { return _devicelist; }
    set 
    { 
        _devicelist = value;
        OnPropertyChanged(nameof(devicelist));
    }
}

4. 确保UI操作在主线程

在InitScanDevices中更新bt_state时,建议显式切换到主线程(Xamarin.Forms会自动处理,但显式操作更稳妥):

Device.BeginInvokeOnMainThread(() => 
{
    bt_state = "BLUETOOTH INFO:\n" + "\nBluetooth state: Stopped Scanning";
});

内容的提问来源于stack exchange,提问作者Raul

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.13 13:55:20