Contact management systematically stores and organizes contact details, including names, phone numbers, email addresses, and physical addresses. This process ensures easy access to these details and smooth communication. This blog post will explore creating and editing contacts using the Syncfusion .NET MAUI DataForm. We will also discuss how these contacts can be displayed in the .NET MAUI ListView. Last, we will see how to perform CRUD (create, read, update, and delete) operations on the SQLite database, allowing us to keep the contacts updated.
SQLite is a lightweight, open-source, self-contained RDBMS (relational database management system). It is renowned for its ease of use and efficiency, making it a popular choice in embedded systems, mobile apps, and desktop software.
Note: Before we proceed, you should familiarize yourself with the introductory documentation for the Syncfusion .NET MAUI DataForm and ListView.
First, we need to set up the Syncfusion core handler. To utilize the Syncfusion core, we must register the handler within the MauiProgram.cs file. This registration process ensures the functionality of the Syncfusion core.
public static MauiApp CreateMauiApp() { var builder = MauiApp.CreateBuilder(); builder.ConfigureSyncfusionCore(); }
This section will delve into loading contacts from an SQLite database using the Syncfusion .NET MAUI DataForm and ListView controls. This involves connecting with the SQLite database and creating a data table to store and manage the contact information.
First, install the sqlite-net-pcl package to connect the SQLite database.
Define the SQLite connection using the SQLiteConnection API and the database path property. This connection will serve as the bridge between our app and the SQLite database.
DatabaseConstants.cs
public static class DatabaseConstants { public const string DatabaseFilename = "DataFormSQLiteDB.db"; public const SQLite.SQLiteOpenFlags Flags = SQLite.SQLiteOpenFlags.ReadWrite | SQLite.SQLiteOpenFlags.Create | SQLite.SQLiteOpenFlags.SharedCache; public static string DatabasePath => Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.LocalApplicationData), DatabaseFile-name); }
SQLiteDatabase.cs
readonly SQLiteConnection _database; public SQLiteDatabase() { _database = new SQLiteConnection(DatabaseConstants.DatabasePath, DatabaseConstants.Flags); }
Next, create an instance for the SQLite connection with the database path property and initialize it in the App.xaml.cs file. This step allows us to use the database in our app.
App.xaml.cs
static SQLiteDatabase database; // Create the database connection as a singleton. public static SQLiteDatabase Database { get { if (database == null) { database = new SQLiteDatabase(); } return database; } }
Define a model class named ContactFormModel. This class will serve as a container for contact information such as names, phone numbers, email addresses, and physical addresses. The data stored in this model will be displayed in the contact data form and stored in the SQLite database.
ContactFormModel.cs
public class ContactFormModel : INotifyPropertyChanged
{ [PrimaryKey, AutoIncrement] [Display(AutoGenerateField = false)] public int ID { get; set; } [DataFormDisplayOptions(ColumnSpan = 2, ShowLabel = false)] public string ProfileImage { get; set; } [Display(ShortName = "“First name"”)] [Required(ErrorMessage = "“Name should not be empty"”)] public string Name { get; set; } [Display(ShortName = "“Last name"”)] public string LastName { get; set; } private string mobile; [DataType(DataType.PhoneNumber)] [Required] [RegularExpression(@"”^\(\d{3}\) \d{3}-\d{4}$"”, ErrorMessage = "“Invalid phone number"”)] public string Mobile { get { return mobile; } set { mobile = value; if (!string.IsNullOrEmpty(mobile)) { char[] specialCharacters = { '‘('‘, '‘)'’, '‘-'‘, '‘ '‘ }; if (mobile[0] == specialCharacters[0]) { mobile = new string(value.Where(c => Char.IsLetterOrDigit(c)©).ToArray()); } if (mobile.Length == 10) this.MaskedMobileText = string.Forma“t("({0}) {1}-{”2}", mobile.Substring(0, 3), mobile.Substring(3, 3), mobile.Substring(6)); RaisePropertyChanged(nameof(Mobile)); } } } [DataType(DataType.PhoneNumber)] public string Landline { get; set; } [DataFormDisplayOptions(ColumnSpan = 2)] public string Address { get; set; } [DataFormDisplayOptions(ColumnSpan = 2)] public string City { get; set; } public string State { get; set; } [Display(ShortName “= "Zip co”de")] public string ZipCode { get; set; } public string Email { get; set; } private string maskedMobileText; [Display(AutoGenerateField = false)] public string MaskedMobileText { get { return maskedMobileText; } set { this.maskedMobileText = value; } } public event PropertyChangedEventHandler PropertyChanged; private void RaisePropertyChanged(string name) { if (PropertyChanged != null) this.PropertyChanged(this, new PropertyChangedEventArgs(name)); } }
Then, create a table within the SQLite database and name it ContactFormModel. This table is used to store the contact information.
SQLiteDatabase.cs
_database.CreateTable<ContactFormModel>();
Populate the contacts into the SQLite database. This will be done within the ContactsViewModel class, as demonstrated in the following code example.
ContactsViewModel.cs
private void GenerateContacts()
{ ContactsInfo = new ContactsInfoRepository().GetContactDetails(20); PopulateDB(); } private void PopulateDB() { foreach (ContactFormModel contact in ContactsInfo) { var item = App.Database.GetContact(contact); if (item == null) App.Database.AddContact(contact); } }
ContactsInfoRepository.cs
internal ObservableCollection<ContactFormModel> GetContactDetails(int count)
{ ObservableCollection<ContactFormModel> customerDetails = new ObservableCollec-tion<ContactFormModel>(); Random random = new Random(); int girlsCount = 0, boysCount = 0; for (int i = 0; i < count; i++) { var details = new ContactFormModel() { ID = i + 1, Mobile = random.Next(100, 400).ToString() + random.Next(500, 800).ToString() + random.Next(1000, 2000).ToString(), ProfileImage = "People_Circle" + (i % 19) + ".png", }; if (imagePosition.Contains(i % 19)) details.Name = CustomerNames_Boys[boysCount++ % 32]; else details.Name = CustomerNames_Girls[girlsCount++ % 93]; customerDetails.Add(details); } return customerDetails; }
Then, retrieve contacts from the SQLite database in the SQLiteDatabase.cs file.
public List<ContactFormModel> GetContacts()
{ List<ContactFormModel> contacts = _database.Table<ContactFormModel>().ToList(); return contacts.OrderBy(x => x.Name[0]).ToList(); }
We’ll use the Syncfusion .NET MAUI ListView control to display and manage contact details.
Refer to the following code example to initialize the SfListView and customize its template to display the name and phone number details.
MainPage.xaml
xmlns:listView="clr-namespace:Syncfusion.Maui.ListView;assembly=Syncfusion.Maui.ListView" <listView:SfListView x:Name="listView" TapCommand="{Binding EditContactsCommand}" ScrollBarVisibility="Always" ItemSize="60"> <listView:SfListView.ItemTemplate> <DataTemplate> <ViewCell> <ViewCell.View> <Grid x:Name="grid" RowSpacing="0" RowDefinitions="*,1" > <Grid ColumnDefinitions="70,*,auto"> <Image Source="{Binding ProfileImage}" VerticalOptions="Center" HorizontalOptions="Center" HeightRequest="50" WidthRequest="50"/> <Grid Grid.Column="1" RowDefinitions="*,*" RowSpacing="1" Padding="10,0,0,0" VerticalOptions="Center"> <Label LineBreakMode="NoWrap" TextColor="#474747" Text="{Binding Name}" FontSize="{OnPlatform Android={OnIdiom Phone=16, Tablet=18}, iOS={OnIdiom Phone=16, Tablet=18}, MacCatalyst=18, WinUI={OnIdiom Phone=18, Tablet=20, Desktop=20}}" /> <Label Grid.Row="1" Grid.Column="0" TextColor="#474747" LineBreakMode="NoWrap" Text="{Binding MaskedMobileText}" FontSize="{OnPlatform Android={OnIdiom Phone=12, Tablet=14}, iOS={OnIdiom Phone=12, Tablet=14}, MacCatalyst=14, WinUI={OnIdiom Phone=12, Tablet=12, Desktop=12}}" /> </Grid> </Grid> <Border Grid.Row="1" BackgroundColor="#E4E4E4" HeightRequest="1"/> </Grid> </ViewCell.View> </ViewCell> </DataTemplate> </listView:SfListView.ItemTemplate> </listView:SfListView>
Use the following code example to load the contacts in the list view.
MainPage.xaml.cs
listView.ItemsSource = App.Database.GetContacts();
Refer to the following output image.
Let’s design a contact data form using the Syncfusion .NET MAUI DataForm that enables users to add, modify, and delete contacts.
EditPage.xaml
xmlns:dataForm="clr-namespace:Syncfusion.Maui.DataForm;assembly=Syncfusion.Maui.DataForm" <dataForm:SfDataForm x:Name="contactForm" DataObject="{Binding SelectedItem}" LayoutType="TextInputLayout" AutoGenerateItems="False" ValidationMode="PropertyChanged"> <dataForm:SfDataForm.TextInputLayoutSettings> <dataForm:TextInputLayoutSettings ShowHelperText="True" FocusedStroke="{StaticResource Primary}"/> </dataForm:SfDataForm.TextInputLayoutSettings> <dataForm:SfDataForm.Items> <dataForm:DataFormCustomItem FieldName="ProfileImage" LayoutType="Default"> <dataForm:DataFormCustomItem.EditorView> <Image Source="{Binding SelectedItem.ProfileImage}" HeightRequest="100"/> </dataForm:DataFormCustomItem.EditorView> </dataForm:DataFormCustomItem> <dataForm:DataFormGroupItem Name="Name"> <dataForm:DataFormGroupItem.Items> <dataForm:DataFormTextItem FieldName="Name" ShowLeadingView="True" > <dataForm:DataFormTextItem.LeadingView> <Label Text="F" FontSize="18" TextColor="Gray" FontFamily="InputLayoutIcons" HeightRequest="24" VerticalTextAlignment="End" /> </dataForm:DataFormTextItem.LeadingView> </dataForm:DataFormTextItem> <dataForm:DataFormTextItem FieldName="LastName" ShowLeadingView="True"> <dataForm:DataFormTextItem.LeadingView> <Label/> </dataForm:DataFormTextItem.LeadingView> </dataForm:DataFormTextItem> </dataForm:DataFormGroupItem.Items> </dataForm:DataFormGroupItem> <dataForm:DataFormGroupItem Name="Mobile"> <dataForm:DataFormGroupItem.Items> <dataForm:DataFormMaskedTextItem FieldName="Mobile" Mask="(###) ###-####" Keyboard="Numeric"> <dataForm:DataFormMaskedTextItem.LeadingView> <Label Text="E" FontSize="18" TextColor="Gray" FontFamily="InputLayoutIcons" HeightRequest="24" VerticalTextAlignment="End" /> </dataForm:DataFormMaskedTextItem.LeadingView> </dataForm:DataFormMaskedTextItem> <dataForm:DataFormMaskedTextItem FieldName="Landline" Mask="+1 ### ###-####" Keyboard="Numeric"> <dataForm:DataFormMaskedTextItem.LeadingView> <Label/> </dataForm:DataFormMaskedTextItem.LeadingView> </dataForm:DataFormMaskedTextItem> </dataForm:DataFormGroupItem.Items> </dataForm:DataFormGroupItem> <dataForm:DataFormGroupItem Name="Address" ColumnCount="2" IsExpanded="False"> <dataForm:DataFormGroupItem.Items> <dataForm:DataFormMultilineItem FieldName="Address" RowSpan="2"> <dataForm:DataFormMultilineItem.LeadingView> <Label Text="C" FontSize="18" TextColor="Gray" FontFamily="InputLayoutIcons" HeightRequest="24" VerticalTextAlignment="End" /> </dataForm:DataFormMultilineItem.LeadingView> </dataForm:DataFormMultilineItem> <dataForm:DataFormTextItem FieldName="City" > <dataForm:DataFormTextItem.LeadingView> <Label/> </dataForm:DataFormTextItem.LeadingView> </dataForm:DataFormTextItem> <dataForm:DataFormTextItem FieldName="State"> <dataForm:DataFormTextItem.LeadingView> <Label/> </dataForm:DataFormTextItem.LeadingView> </dataForm:DataFormTextItem> <dataForm:DataFormMaskedTextItem FieldName="ZipCode" Mask="#####-####" Keyboard="Numeric"/> </dataForm:DataFormGroupItem.Items> </dataForm:DataFormGroupItem> <dataForm:DataFormTextItem FieldName="Email" Keyboard="Email"> <dataForm:DataFormTextItem.LeadingView> <Label Text="G" FontSize="18" TextColor="Gray" FontFamily="InputLayoutIcons" HeightRequest="24" VerticalTextAlignment="End" /> </dataForm:DataFormTextItem.LeadingView> </dataForm:DataFormTextItem> </dataForm:SfDataForm.Items> </dataForm:SfDataForm>
The contact data form will be displayed upon tapping the ListView or tapping on the new icon (+) button.
Refer to the following code example to design a data form to edit a contact.
MainPage.xaml
<listView:SfListView x:Name="listView" TapCommand="{Binding EditContactsCommand}" </listView:SfListView>
…..
ContactsViewModel.cs
public Command<object> EditContactsCommand { get; set; } EditContactsCommand = new Command<object>(OnEditContacts); private void OnEditContacts(object obj) { SelectedItem = (obj as Syncfusion.Maui.ListView.ItemTappedEventArgs).DataItem as ContactFormModel; var editPage = new EditPage() { BindingContext = this}; App.Current.MainPage.Navigation.PushAsync(editPage); }
Refer to the following image.
To design a data form to add a new contact, refer to the following code.
MainPage.xaml
<ImageButton Margin="20" CornerRadius="20" HeightRequest="40" WidthRequest="40" Back-ground="{StaticResource Primary}" VerticalOptions="End" HorizontalOptions="End" Command="{Binding CreateContactsCommand}" Source="add.png"/>
ContactsViewModel.cs
public Command CreateContactsCommand { get; set; } CreateContactsCommand = new Command(OnCreateContacts); private void OnCreateContacts() { SelectedItem = new ContactFormModel() { Name = "", Mobile = "", ProfileImage = "newcontact.png" }; var editPage = new EditPage() { BindingContext = this }; App.Current.MainPage.Navigation.PushAsync(editPage); }
Let’s see how to perform CRUD (create, read, update, delete) operations on the SQLite database and update the changes to the .NET MAUI ListView control.
When we select the Save button in the contact data form, the details entered will be updated in the SQLite database. Data form validation is essential to ensure the accuracy and validity of these details.
Refer to the following code example to add the data form validation.
ContactFormBehavior.cs
private async void OnSaveButtonClicked(object? Sender, EventArgs e)
{ this.dataForm?.Validate(); if(isValid) { await Task.Delay(500); await App.Current.MainPage.Navigation.PopAsync(); await App.Current.MainPage.DisplayAlert(“”, “Contact saved”, “OK”); } } dataForm.ValidateProperty += this.OnDataFormValidateProperty; private void OnDataFormValidateProperty(object? Sender, DataFormValidatePropertyEventArgs e) { if (e.PropertyName == nameof(ContactFormModel.Mobile) && !e.IsValid) { e.ErrorMessage = e.NewValue == null || string.IsNullOrEmpty(e.NewValue.ToString()) ? “Please enter the mobile number” : “Invalid mobile number”; } }
Refer to the following code example to update the contact details in the SQLite database.
EditPage.xaml.cs
(this.contactForm.DataObject as ContactFormModel).PropertyChanged += ContactFormBehav-ior_PropertyChanged; private void ContactFormBehavior_PropertyChanged(object sender, Sys-tem.ComponentModel.PropertyChangedEventArgs e) { App.Database.UpdateContact(this.contactForm.DataObject as ContactFormModel); }
Public int UpdateContact(ContactFormModel item) { if (item.ID != 0) return _database.Update(item); else return _database. Insert(item); }
Refer to the following code example to create a new contact and update it on the SQLite database.
SQLiteDatabase.cs
public int AddContact(ContactFormModel item)
{ return _database. Insert(item); }
When clicking the Delete button, the contact must be deleted from the SQLite database.
Refer to the following code example to add a command associated with the Delete button in the contact data form and perform the delete operation in the SQLite database.
ContactsViewModel.cs
public Command DeleteItemCommand { get; set; } DeleteItemCommand = new Command(OnDeleteItem); private async void OnDeleteItem() { App.Database.DeleteContact(SelectedItem); ContactsInfo.Remove(SelectedItem); await App.Current.MainPage.Navigation.PopAsync(); }
Refer to the following code example to delete the content in the SQLite database.
SQLiteDatabase.cs
//Delete a contact in the database. public int DeleteContact(ContactFormModel item) { return _database. Delete(item); }
Upon rerunning the app, the ListView will fetch the updated contacts from the SQLite database, and the output will be as follows.
For more details, refer to the GitHub demo.
Thanks for reading! In this blog, we’ve seen how to manage contacts using the .NET MAUI DataForm and ListView controls with SQLite and performs seamless CRUD actions. Try the steps outlined in the post and leave your thoughts in the comments below.
You can also contact us through our support forum, support portal, or feedback portal. We are always happy to assist you!