英文:
Why cant my code behind page acces variables in View Model
问题
IntelliSense 表示这些变量不存在。我无法确定它们为何无法互相识别。以下是你的 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>
在 XAML 中,你绑定了 Email
和 Password
到 ViewModel 的属性,但是在 ViewModel 中,这些属性的名称应该与 XAML 中的绑定一致,应该分别为 email
和 password
,而不是 Email
和 Password
。请确保它们的大小写一致以解决问题。
英文:
Why doesnt my View recognize email and password strings from View Model.
It says that email and password dont exist in current context. Can someone tell me why doesnt this code work and explain solution?
this is code in 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);
};
}
}
}
And this is ViewModel code:
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();
}
}
}
}
IntelliSense says that these variables dont exist. I cant figure out why they cant see each other.
This is xaml code
<?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
得分: 1
Update
我注意到你在代码中使用以下代码来将Completed事件添加到Entry:
email.Completed += (object sender, EventArgs e) =>
{
Password.Focus();
};
但是在你的XAML中,你设置了x:Name="Email"
:
<Entry x:Name="Email" Text="{Binding Email}"
所以你知道它是区分大小写的。代码中的email指的是在XAML中设置的Entry(带有x:Name="email"
),而不是ViewModel中的email属性。这就是为什么你会收到“email在当前上下文中不存在”的错误消息。
顺便说一句,如果你想从代码中访问ViewModel变量,你可以使用:
var password = vm.Password;
============Origin answer======
你已经完成了大部分工作。但是应该更注意大小写规范和一些细节,就像ToolmakerSteve提到的那样。
在ViewModel中,你以这种方式定义了Email属性:
private string Email;
public string email
{
get { return Email; }
set
{
Email = value;
PropertyChanged(this, new PropertyChangedEventArgs("Email"));
}
}
这意味着Email字符串是一个私有变量,只有在同一类中才能访问它。
如果外部类想要访问它,可以通过属性来实现。这就是你代码中的email属性。因此,其他类只能通过email属性来访问Email字符串,明确说一下,通过email属性的getter。
另一个问题是大小写规范。通常情况下,我们将私有字段设为小写,而属性名称设为大写。
总之,你可以将email属性更改为以下内容:
private string email;
public string Email
{
get { return email; }
set
{
email = value;
PropertyChanged(this, new PropertyChangedEventArgs(nameof(Email)));
}
}
希望这对你有所帮助。
英文:
Update
I notice that you use the following code in code behind to add a Completed event to an Entry,
email.Completed += (object sender, EventArgs e) =>
{
Password.Focus();
};
But in your xaml, you set x:Name="Email"
<Entry x:Name="Email" Text="{Binding Email}"
So you know it's case sensitive. The email in code behind refers to the Entry (with x:Name="email") set in xaml instead of email property in ViewModel. That's why you got "email does not exist in the current context".
By the way, if you want to access the ViewModel variables from code behind, you could use:
var password = vm.Password;
============Origin answer======
You have done most of the work. But capitalization conventions and some details should be paid more attention to, as ToolmakerSteve mentioned.
In the ViewModel, you define the Email property in this way:
private string Email;
public string email
{
get { return Email; }
set
{
Email = value;
PropertyChanged(this, new PropertyChangedEventArgs("Email"));
}
}
That means Email string is a private variable and only in the same class can access it.
If an outside class want to access it, it can be done with properties. That's email property in your code. So other class can only access the Email string through email property, to be explicit, through
getter in email property.
Another is capitalization conventions. Usually we set the private field to lower case while the property name to upper case.
To conclude, you may change email property to this:
private string email;
public string Email
{
get { return email; }
set
{
email = value;
PropertyChanged(this, new PropertyChangedEventArgs(nameof(Email)));
}
}
Hope it works.
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论