I have tried using the guide on using local databases and reading the working application (Tasky) source code to get an idea of how i could achieve this but my listview is still empty. Also i would like to know if it is fine to resolve the issue like this or should i create a viewmodel that with an observable collection filled with the results obtained from the database? This is my code:
This is my model:
public class AppUser
{
[PrimaryKey, AutoIncrement]
public long AppUserId { get; set; }
[MaxLength(255)]
public string Name { get; set; }
[MaxLength(255)]
public string ContactName { get; set; }
public string Password { get; set; }
public string MedicalNumber { get; set; }
public string PoliceNumber { get; set; }
public string FireNumber { get; set; }
public string FamilyNumber { get; set; }
public string CustomTextMessage { get; set; }
}
This is my data access layer
public class AppUserDbConnect
{
static SQLiteAsyncConnection _database;
public AppUserDbConnect(string dbPath)
{
_database = new SQLiteAsyncConnection(dbPath);
_database.CreateTableAsync<AppUser>().Wait();
}
public Task<List<AppUser>> GetItemsAsync()
{
return _database.Table<AppUser>().ToListAsync();
}
public Task<List<AppUser>> GetItemsNotDoneAsync()
{
return _database.QueryAsync<AppUser>("SELECT * FROM [AppUser] WHERE [Done] = 0");
}
public Task<AppUser> GetItemAsync(int id)
{
return _database.Table<AppUser>().Where(i => i.AppUserId == id).FirstOrDefaultAsync();
}
public Task<int> SaveItemAsync(AppUser item)
{
if (item.AppUserId != 0)
{
return _database.UpdateAsync(item);
}
else
{
return _database.InsertAsync(item);
}
}
public Task<int> DeleteItemAsync(AppUser item)
{
return _database.DeleteAsync(item);
}
}
}
This is my view:
<StackLayout>
<Label Text="SETTINGS/MY Numbers" FontSize="30" FontAttributes="Bold"/>
<ListView x:Name="ListOfNumbers" >
<ListView.ItemTemplate>
<DataTemplate>
<ViewCell>
<ViewCell.View>
<Label Text="{Binding MedicalNumber}" />
</ViewCell.View>
</ViewCell>
</DataTemplate>
</ListView.ItemTemplate>
</ListView>
</StackLayout>
</ContentPage>
And finally the code behind:
[XamlCompilation(XamlCompilationOptions.Compile)]
public partial class MyNumbersPage : ContentPage
{
public MyNumbersPage ()
{
InitializeComponent( );
BindingContext = new AppUser();
}
protected async override void OnAppearing()
{
base.OnAppearing();
ListOfNumbers.ItemsSource = await App.AppUserDatabase.GetItemsAsync();
}
}
This is the add contacts page:
<StackLayout>
<Picker x:Name="picker" Title="Select a Country Code">
<Picker.ItemsSource>
<x:Array Type="{x:Type x:String}">
<x:String>+234</x:String>
<x:String>+264</x:String>
<x:String>+27</x:String>
<x:String>+266</x:String>
<x:String>+263</x:String>
<x:String>+218</x:String>
<x:String>+211</x:String>
</x:Array>
</Picker.ItemsSource>
</Picker>
<Entry Placeholder="Enter the Contact Name" x:Name="Name"/>
<Entry Keyboard="Numeric" Placeholder="Enter your Number" x:Name="Number"/>
<Button Text="Cancel" Clicked="Cancel" />
<Button Text="Save" Clicked="AddNewContact"/>
</StackLayout>
and also the code-behind:
public partial class AddContactForFamily : ContentPage
{
public string pickerValue;
public AddContactForFamily ()
{
InitializeComponent ();
}
async void AddNewContact(object sender, EventArgs e)
{
var picker = (Picker)sender;
int selectedIndex = picker.SelectedIndex;
if (selectedIndex != -1)
{
pickerValue = (string)picker.ItemsSource[selectedIndex];
}
var contact = new AppUser {ContactName = Name.Text, FamilyNumber = pickerValue +Number.Text };
if (App.AppUserDatabase.SaveItemAsync(contact) != null)
{
await DisplayAlert("Alert", "You have added a contact successful", "OK");
await Navigation.PopAsync();
}
}
async void Cancel(object sender, EventArgs e)
{
await Navigation.PopAsync();
}
}