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

Xamarin.Forms视图无法识别ViewModel中email与password的问题求助

Xamarin.Forms视图无法识别ViewModel变量问题排查与解决

问题描述

在Xamarin.Forms项目中,LoginUI视图的后台代码提示email和Password变量在当前上下文不存在,同时ViewModel与View的数据绑定也存在异常。相关代码如下:

原View后台代码

using System;
using Xamarin.Forms;
using Xamarin.Forms.Xaml;
using Papucometar.ViewModel;
using Xamarin.Essentials;
namespace Papucometar.View
{
    [XamlCompilation(XamlCompilationOptions.Compile)]
    public partial class LoginUI : ContentPage
    {
        public LoginUI()
        {
            var vm = new LoginViewModel();
            this.BindingContext = vm;
            vm.DisplayInvalidLoginPrompt += () => DisplayAlert("Error", "Invalid Login, try again", "OK");
            InitializeComponent();

            email.Completed += (object sender, EventArgs e) =>
            {
                Password.Focus();
            };

            Password.Completed += (object sender, EventArgs e) =>
            {
                vm.SubmitCommand.Execute(null);
            };
        }
    }
}

原ViewModel代码

using System.ComponentModel;
using System.Text;
using System.Windows.Input;
using Xamarin.Essentials;
using Xamarin.Forms;

namespace Papucometar.ViewModel
{
    public class LoginViewModel : INotifyPropertyChanged
    {
        public Action DisplayInvalidLoginPrompt;
        public event PropertyChangedEventHandler PropertyChanged = delegate { };
        private string Email;
        public string email
        {
            get { return Email; }
            set
            {
                Email = value;
                PropertyChanged(this, new PropertyChangedEventArgs("Email"));
            }
        }
        private string password;
        public string Password
        {
            get { return password; }
            set
            {
                password = value;
                PropertyChanged(this, new PropertyChangedEventArgs("Password"));
            }
        }
        public ICommand SubmitCommand { protected set; get; }
        public LoginViewModel()
        {
            SubmitCommand = new Command(OnSubmit);
        }
        public void OnSubmit()
        {
            if (email != "macoratti@yahoo.com" || password != "secret")
            {
                DisplayInvalidLoginPrompt();
            }
        }
    }
}

原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="Papucometar.View.LoginUI"
             xmlns:local="clr-namespace:Papucometar.ViewModel"
             x:DataType="local:LoginViewModel"
             BackgroundColor="#112B47">
    <ContentPage.Content>  
    <StackLayout Orientation="Vertical" Padding="30" Spacing="40">  
        <BoxView HeightRequest="10"/>  
        <Image HorizontalOptions="Center" WidthRequest="300" Source="maco.jpg"/>  
        <Frame BackgroundColor="#BF043055" HasShadow="False">  
            <StackLayout Orientation="Vertical" Spacing="10">  
                <Entry x:Name="Email" Text="{Binding Email}" Placeholder="Email"   
                       PlaceholderColor="White" HeightRequest="40"   
                       Keyboard="Email"  
                       TextColor="White"/>  
                <Entry x:Name="Password" Text="{Binding Password}" Placeholder="Senha"   
                       PlaceholderColor="White" HeightRequest="40"   
                       IsPassword="True"  
                       TextColor="White"/>  
            </StackLayout>  
        </Frame>  
        <Button Command="{Binding SubmitCommand}" Text="Login" TextColor="White"  
                FontAttributes="Bold" FontSize="Large" HorizontalOptions="FillAndExpand"  
                BackgroundColor="#088da5" />  
    </StackLayout>  
</ContentPage.Content>  
</ContentPage>

问题原因

  1. 控件名称大小写不匹配:View后台代码中引用的email是小写,但XAML里Entry控件的x:Name是Email(首字母大写),C#是大小写敏感语言,因此无法找到对应控件。
  2. ViewModel属性命名与通知不一致:
    • ViewModel的公共属性email是小写,但PropertyChanged触发的是大写的"Email",导致数据绑定无法正确更新。
    • OnSubmit方法中直接使用私有字段password,而非公共属性Password,逻辑判断会读取未通过绑定更新的私有字段值。
  3. 绑定属性大小写不匹配:XAML中绑定的是Email和Password,但ViewModel的对应公共属性一个是小写email,绑定逻辑因大小写不匹配失效。

解决方案

1. 修正View后台代码

将控件引用的大小写与XAML中的x:Name保持一致:

using System;
using Xamarin.Forms;
using Xamarin.Forms.Xaml;
using Papucometar.ViewModel;
using Xamarin.Essentials;
namespace Papucometar.View
{
    [XamlCompilation(XamlCompilationOptions.Compile)]
    public partial class LoginUI : ContentPage
    {
        public LoginUI()
        {
            var vm = new LoginViewModel();
            this.BindingContext = vm;
            vm.DisplayInvalidLoginPrompt += () => DisplayAlert("Error", "Invalid Login, try again", "OK");
            InitializeComponent();

            // 修正为大写的Email,与XAML的x:Name一致
            Email.Completed += (object sender, EventArgs e) =>
            {
                Password.Focus();
            };

            Password.Completed += (object sender, EventArgs e) =>
            {
                vm.SubmitCommand.Execute(null);
            };
        }
    }
}

2. 修正ViewModel代码

统一遵循C# PascalCase命名规范,确保属性名与通知名称一致,使用公共属性进行逻辑判断:

using System.ComponentModel;
using System.Windows.Input;
using Xamarin.Forms;

namespace Papucometar.ViewModel
{
    public class LoginViewModel : INotifyPropertyChanged
    {
        public Action DisplayInvalidLoginPrompt;
        public event PropertyChangedEventHandler PropertyChanged = delegate { };

        // 私有字段用camelCase,公共属性用PascalCase
        private string _email;
        public string Email
        {
            get { return _email; }
            set
            {
                _email = value;
                // 使用nameof避免硬编码属性名
                PropertyChanged(this, new PropertyChangedEventArgs(nameof(Email)));
            }
        }

        private string _password;
        public string Password
        {
            get { return _password; }
            set
            {
                _password = value;
                PropertyChanged(this, new PropertyChangedEventArgs(nameof(Password)));
            }
        }

        public ICommand SubmitCommand { protected set; get; }

        public LoginViewModel()
        {
            SubmitCommand = new Command(OnSubmit);
        }

        public void OnSubmit()
        {
            // 使用公共属性而非私有字段进行判断,同时加空引用保护
            if (Email != "macoratti@yahoo.com" || Password != "secret")
            {
                DisplayInvalidLoginPrompt?.Invoke();
            }
        }
    }
}

3. XAML代码无需修改

XAML中的绑定路径Email和Password与修正后的ViewModel公共属性名一致,可直接使用。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.25 00:05:04