How to load the picker editor ItemsSource from SQLite offline database in Xamarin.Forms DataForm?
DataForm allows you to load the picker editor ItemsSource from local database using SQLite. To achieve this, follow the steps:
- Add the database to the cross-platform projects Resource folder.
Refer to the following link to know how to create SQLite connection:
https://docs.microsoft.com/en-us/xamarin/xamarin-forms/app-fundamentals/databases
- Create a connection with the database using interface in cross platform projects and create an interface in PCL project.
public interface ISQLite { SQLiteConnection GetConnection(); }
- Create a class inherited from the ISQLite interface in cross-platform project and get connection with the offline database.
In Android cross-platform project,
public class SQLite_Android : ISQLite { public SQLite_Android() { } public SQLite.SQLiteConnection GetConnection() { var sqliteFilename = "SampleSQLites.db3"; string documentsPath = System.Environment.GetFolderPath(System.Environment.SpecialFolder.Personal); // Documents folder var path = Path.Combine(documentsPath, sqliteFilename); // This is where we copy in the prepopulated database Console.WriteLine(path); if (!File.Exists(path)) { var s = Forms.Context.Resources.OpenRawResource(Resource.Raw.SampleSQLites); // RESOURCE NAME ### // create a write stream FileStream writeStream = new FileStream(path, FileMode.OpenOrCreate, FileAccess.Write); // write to the stream ReadWriteStream(s, writeStream); } var conn = new SQLite.SQLiteConnection(path); // Return the database connection return conn; } /// <summary> /// helper method to get the database out of /raw/ and into the user filesystem /// </summary> void ReadWriteStream(Stream readStream, Stream writeStream) { int Length = 256; Byte[] buffer = new Byte[Length]; int bytesRead = readStream.Read(buffer, 0, Length); // write the required bytes while (bytesRead > 0) { writeStream.Write(buffer, 0, bytesRead); bytesRead = readStream.Read(buffer, 0, Length); } readStream.Close(); writeStream.Close(); } }
In iOS cross-platform project,
public class SQLite_iOS : ISQLite { public SQLite_iOS () { } public SQLite.SQLiteConnection GetConnection () { var sqliteFilename = "SampleSQLites.db3"; string documentsPath = Environment.GetFolderPath (Environment.SpecialFolder.Personal); // Documents folder string libraryPath = Path.Combine (documentsPath, "..", "Library"); // Library folder var path = Path.Combine(libraryPath, sqliteFilename); // This is where we copy in the prepopulated database Console.WriteLine (path); if (!File.Exists (path)) { File.Copy (sqliteFilename, path); } var conn = new SQLite.SQLiteConnection(path); // Return the database connection return conn; } }
In UWP cross-platform project,
class SQLite_UWP : ISQLite { public SQLite_UWP() { } public SQLiteConnection GetConnection() { var databasename = "SampleSQLites.db3"; var path = Path.Combine(ApplicationData.Current.LocalFolder.Path, databasename); var conn = new SQLite.SQLiteConnection(path); // Return the database connection return conn; } }
- Create a model of DataForm. Here, the City property is used as picker editor.
ContactInfo.cs: public class ContactInfo { [PrimaryKey, AutoIncrement] public int ID { get; set; } public string Name { get; set; } public string City { get; set; } } public class PickerItem { public string CityName { get; set; } }
Refer to the following code example for binding the DataObject and register the editor as Picker for the property City using RegisterEditor in DataForm.
https://help.syncfusion.com/xamarin/sfdataform/editors#customizing-itemssource-of-picker
if(Device.RuntimePlatform != Device.UWP) dataForm.RegisterEditor("City", "Picker");
- Initialize a database using SQLiteConnection to create table for storing data form items (other than picker) and insert the data form items (other than picker) and values in database table.
public class ViewModel { SQLiteConnection database; ObservableCollection<ContactInfo> orderItemCollection; ObservableCollection<ContactInfo> OrderList; public ObservableCollection<ContactInfo> OrderItemCollection { get { if (orderItemCollection == null) { GetItems(); orderItemCollection = OrderList; } return orderItemCollection; } } public ViewModel() { database = DependencyService.Get<ISQLite>().GetConnection(); // Create the table database.CreateTable<OrderItem>(); database.CreateTable<ContactInfo>(); database.Query<ContactInfo>("INSERT INTO ContactInfo (ID,Name)values (1002,'Blake')"); database.Query<ContactInfo>("INSERT INTO ContactInfo (ID,Name)values (1003,'Catherine')"); database.Query<ContactInfo>("INSERT INTO ContactInfo (ID,Name)values (1004,'Jude')"); }
Get the database table data in DataForm when setting the DataObject.
dataForm.DataObject = ViewModel.OrderItemCollection[0]; public ObservableCollection<ContactInfo> OrderItemCollection { get { if (orderItemCollection == null) { GetItems(); orderItemCollection = OrderList; } return orderItemCollection; } } public async void GetItems() { // Changing the database table items as ObservableCollection var table = (from i in database.Table<ContactInfo>() select i); OrderList = new ObservableCollection<ContactInfo>(); foreach (var order in table) { OrderList.Add(new ContactInfo() { ID = order.ID, Name = order.Name }); } await Task.Delay(2000); }
Create a class to get the picker item in database.
public class PickerItem { public string CityName { get; set; } }
- Initialize a separate database using SQLiteConnection to create a table for storing the data form picker items and insert the picker item value in table.
public class ViewModel { SQLiteConnection pickerData; List<PickerItem> pickerList; public ViewModel() { //create the table for picker data. pickerData = DependencyService.Get<ISQLite>().GetConnection(); pickerData.CreateTable<PickerItem>(); // Insert items into table. pickerData.Query<PickerItem>("INSERT INTO PickerItem (CityName)values ('Chennai')"); pickerData.Query<PickerItem>("INSERT INTO PickerItem (CityName)values ('Vatican')"); pickerData.Query<PickerItem>("INSERT INTO PickerItem (CityName)values ('Paris')"); } }
- Get the picker database table items as IEnumerable for picker editor in data form by setting the ItemSource of DataFormPickerItem in the AutoGeneratingDataFormItem event.
To display complex type property as picker (other than enum data type), refer to the user guide documentation.
dataForm.AutoGeneratingDataFormItem += DataForm_AutoGeneratingDataFormItem; private void DataForm_AutoGeneratingDataFormItem(object sender, AutoGeneratingDataFormItemEventArgs e) { if(Device.RuntimePlatform != Device.UWP) { if (e.DataFormItem != null && e.DataFormItem.Name == "City") { var itemSource = ViewModel.GetPickerItems(); (e.DataFormItem as DataFormPickerItem).DisplayMemberPath ="CityName"; (e.DataFormItem as DataFormPickerItem).ValueMemberPath ="CityName"; (e.DataFormItem as DataFormPickerItem).ItemsSource = itemSource; } } } public IEnumerable<PickerItem> GetPickerItems() { var table = (from i in pickerData.Table<PickerItem>() select i); pickerList = new List<PickerItem>(); foreach (var order in table) { pickerList.Add(new PickerItem() { CityName = order.CityName }); } return pickerList; } }
Note:
Picker editor is not supported in Xamarin.Forms.UWP platform.
You can refer to the DataForm user guide documentation to learn more about picker:
https://help.syncfusion.com/xamarin/sfdataform/editors#picker-editor
To download sample click PickerItemsFromSQLite.