Easily Manage Contacts in Your .NET MAUI App with SQLite and Perform CRUD Actions
Detailed Blog page Skeleton loader
Easily Manage Contacts in Your .NET MAUI App with SQLite and Perform CRUD Actions

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.

Register the handler for Syncfusion core

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();
 }

Create SQLite connection and data table

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.

Step 1: Install the required package

First, install the sqlite-net-pcl package to connect the SQLite database.Install the sqlite-net-pcl package to connect with SQLite database

Step 2: Create the SQLite connection

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;
     }
 }

Step 3: Create the contact data form model

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>();

Step 4: Populate contacts with the SQLite database

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(); }

Display and manage the contacts in the ListView

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.

Displaying the contacts using the Syncfusion .NET MAUI ListView
Displaying the contacts using the Syncfusion .NET MAUI ListView

Creating a contact data form

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.

Edit contact data form
Edit the contact data form

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);
}
Add a new contact data form
Add a new contact data form

Perform CRUD operations with SQLite database and update changes in .NET MAUI ListView

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.

Editing and saving a contact

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”; } }
Validating data while saving contact details
Validating data while saving contact details

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);
  }
Editing and saving a contact in the ListView and SQLite database
Editing and saving a contact in the ListView and SQLite database

Creating a new contact

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); }
Add a new contact in the ListView and SQLite database
Add a new contact in the ListView and SQLite database

Deleting a contact

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.

Updating the contacts in the ListView from the SQLite database
Updating the contacts in the ListView from the SQLite database

GitHub reference

For more details, refer to the GitHub demo.

Conclusion

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 forumsupport portal, or feedback portal. We are always happy to assist you!

Related blogs

Be the first to get updates

Jeyasri Murugan

Meet the Author

Jeyasri Murugan

I'm Jeyasri Murugan, a Product Manager at Syncfusion. I have experience in developing custom controls for various .NET frameworks, including .NET MAUI, Xamarin, WPF, WinUI, and UWP.