I have two pages that use the same form so I created a content view of form and apply bindable properties like this:
<ContentView xmlns="http://xamarin.com/schemas/2014/forms"
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
x:Class="ListContact.Extension.EditForm">
<StackLayout Padding="20">
<Label Text="Edit Contact Forms"
HorizontalOptions="Center"
FontSize="20"
TextColor="Blue"
VerticalOptions="Start"/>
<Label Text="Name"/>
<Entry x:Name="txtName" Text="{Binding NameText}" Placeholder="Name"/>
<Label Text="Phone number"/>
<Entry x:Name="txtPhoneNumber" Text="{Binding PhoneNumberText}" Placeholder="Phone number" Keyboard="Telephone"/>
<Label Text="Email"/>
<Entry x:Name="txtEmail" Text="{Binding EmailText}" Placeholder="Email" Keyboard="Email"/>
<Label Text="Description"/>
<Editor x:Name="txtDescription" Text="{Binding DescriptionText}" Placeholder="Description"
HeightRequest="70"/>
</StackLayout>
</ContentView>
This is the code behind:
using ListContact.ViewModel;
using Xamarin.Forms;
using Xamarin.Forms.Xaml;
namespace ListContact.Extension
{
[XamlCompilation(XamlCompilationOptions.Compile)]
public partial class EditForm : ContentView
{
private static readonly BindableProperty NameProperty = BindableProperty.Create("NameText", typeof(object), typeof(EditForm));
public string NameText { get => (string)GetValue(NameProperty); set => SetValue(NameProperty, value); }
private static readonly BindableProperty PhoneProperty = BindableProperty.Create("PhoneNumberText", typeof(string), typeof(EditForm));
public string PhoneNumberText { get => (string)GetValue(PhoneProperty); set => SetValue(PhoneProperty, value); }
private static readonly BindableProperty EmailProperty = BindableProperty.Create("EmailText", typeof(string), typeof(EditForm));
public string EmailText { get => (string)GetValue(EmailProperty); set => SetValue(EmailProperty, value); }
private static readonly BindableProperty DescriptionProperty = BindableProperty.Create("DescriptionText", typeof(string), typeof(EditForm));
public string DescriptionText { get => (string)GetValue(DescriptionProperty); set => SetValue(DescriptionProperty, value); }
public EditForm()
{
InitializeComponent();
BindingContext = this;
}
}
}
And in the view I call back this form that I created before and bind data to the bindable property like below:
This is the xaml file:
<ContentPage xmlns:local="clr-namespace:ListContact.Extension"
xmlns="http://xamarin.com/schemas/2014/forms"
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
x:Class="ListContact.View.ListContactAddingForm">
<local:EditForm NameText="{Binding Name, Mode=TwoWay}" PhoneNumberText="egwebwev" EmailText="ưewevefqwf" DescriptionText="ewebe"/>
<ContentPage.Content>
<Button Text="Save"
HorizontalOptions="Center"
TextColor="White"
Command="{Binding AddContactCommand}"
BackgroundColor="#0A7CFF"/>
</ContentPage.Content>
</ContentPage>
And this is the code behind:
namespace ListContact.View
{
[XamlCompilation(XamlCompilationOptions.Compile)]
public partial class ListContactAddingForm : ContentPage
{
private SQLiteAsyncConnection connection;
public ListContactAddingForm()
{
connection = new SQLiteAsyncConnection(BaseConnection.DatabasePath);
ViewModel = new ContactViewModel(new PageService());
InitializeComponent();
}
private ContactViewModel ViewModel
{
get => BindingContext as ContactViewModel;
set => BindingContext = value;
}
}
}
`
This is my view model:
namespace ListContact.ViewModel
{
public class ContactViewModel : BaseViewModel
{
public int Id { get; set; }
private string name;
public string Name
{
get => name;
set
{
SetValue(ref name, value);
}
}
private string description;
public string Description
{
get => description;
set
{
SetValue(ref description, value);
}
}
private string phoneNumber;
public string PhoneNumber
{
get => phoneNumber;
set
{
SetValue(ref phoneNumber, value);
}
}
private string email;
public string Email
{
get => email;
set
{
SetValue(ref email, value);
}
}
public ICommand AddContactCommand { get; private set; }
private IPageService pageService;
public object Alert { get; private set; }
public ContactViewModel(IPageService pageService)
{
this.pageService = pageService;
AddContactCommand = new Command(async () => await AddContacts());
}
private async Task AddContacts()
{
var newContact = new Contact()
{
Name = Name,
PhoneNumber = PhoneNumber,
Email = Email,
Description = Description
};
var result = await connection.InsertAsync(newContact);
if (result == 1)
await App.Current.MainPage.DisplayAlert("Successfully", "", "OK");
await pageService.PopAsycn();
}
}
}
But when I run this code I got the error:
No property, bindable property, or event found for "NameText", or mismatching type between value and property
My code was okay before I separated the form into another content view and call it back from the view and got this problem
So my questions are that: Is the way that I create form and bindable property correct? Could I bind data to the bindable property in the form? How to do it if it could?. And how to fix the above error?
I use MVVM to build this code
Btw, sorry for my bad English
2条答案
按热度按时间qzwqbdag1#
From Xamarin.Forms Bindable Properties , a bindable property can be created by declaring a public static readonly property of type BindableProperty.
Then you need take care of BindableProperty Name, for example, PropertyNameProperty
Finally, you don't need to use Binding in EditForm, just using propertyChanged event to notify property value has changed.
Do one sample that you can take a look:
EditForm xaml.
The ViewModelBase implementing INotifyPropertyChanged
The screenshot:
piztneat2#
When we want to extend any
Control
s properties we useBindable Properties
. For example forLabel
Control
we needBorder
andPadding
. InXamarin 4.+
we do not have it. So we can go withBindable Properties
.I will show you this with
Padding
. Create a classExLabel
in Shared project.In
android
level project implementCustom renderer
to useExLabel class
.In
xaml
usepadding
like thisDONE.
Similarly we can add other
Bindable Properties
, say along withpadding
you wantborder
also forLabel
and needborder
for fewLabels
, not for all theExLabel
. Then we can haveBindable Properties
likeFrom
xaml
we can passIsBorder
true false
andShowBorder
Color
. Incustom renderer
file we can check ifIsBorder
istrue
then setColor
forborder
otherwise skip it.