I am making a ListView
inside my C# file. But instead of that I want to add the data I get from sqlite too the xaml file with data binding so I can still edit the layout with xaml. So every response from sqlite needs to be added as label(<TextCell Text="{Binding Name}" />
).
My question: How can I bind the response from GetCategoryByMenuID
to TextCell Text="{Binding Name}"
?
xaml page (CategoriePage.xaml):
<?xml version="1.0" encoding="utf-8" ?>
<ContentPage xmlns="http://xamarin.com/schemas/2014/forms"
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
x:Class="AmsterdamTheMapV3.CategoriePage">
<ListView x:Name="listView">
<ListView.ItemTemplate>
<DataTemplate>
<TextCell Text="{Binding Name}" />
</DataTemplate>
</ListView.ItemTemplate>
</ListView>
</ContentPage>
Back-end / C# (CategoriePage.xaml.cs) :
namespace AmsterdamTheMapV3
{
public partial class CategoriePage : ContentPage
{
public CategoriePage(String txt)
{
InitializeComponent();
var layout = new StackLayout { Padding = new Thickness(5, 10) };
int page = Int32.Parse(txt);
this.Content = layout;
var categories = App.Database.GetCategoryByMenuID(page);
var datatemplate = new DataTemplate(() =>
{
var nameLabel = new Label();
nameLabel.SetBinding(Label.TextProperty, "Name");
//nameLabel.SetBinding(Label.idProperty, "Name");
return new ViewCell { View = nameLabel };
});
var listView = new ListView
{
ItemsSource = categories,
ItemTemplate = datatemplate
};
layout.Children.Add(listView);
}
}
}
GetCategoryPage function:
public List<Categories> GetCategoryByMenuID(int menuID)
{
lock (locker)
{
return db.Table<Categories>().Where(x => x.Menu_ID == menuID).ToList();
}
}
Given
<?xml version="1.0" encoding="utf-8" ?>
<ContentPage xmlns="http://xamarin.com/schemas/2014/forms"
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
x:Class="AmsterdamTheMapV3.CategoriePage">
<ListView x:Name="listView">
<ListView.ItemTemplate>
<DataTemplate>
<ViewCell>
<ViewCell.View>
<StackLayout>
<Label Text="{Binding Name}" />
</StackLayout>
</ViewCell.View>
</ViewCell>
</DataTemplate>
</ListView.ItemTemplate>
</ListView>
</ContentPage>
Update code behind
namespace AmsterdamTheMapV3 {
public partial class CategoriePage : ContentPage {
public CategoriePage(string txt) {
InitializeComponent();
this.Appearing += (s,e) => {
if(NotInDesignMode) {
int page = 0;
if(int.TryParse(txt, out page)){
var categories = App.Database.GetCategoryByMenuID(page);
this.listView.ItemsSource = categories;
}
}
};
}
bool NotInDesignMode {
get { return Application.Current != null; }
}
}
}
You could do it the ugly and fast-to-implement way (in your GetCategoryByMenuID method, Run an update name by id, which will run on categories).
Or by making a collection that'd be menuID based instead of index based as a regular list.
public class CategoriesCollection<T> : KeyedCollection<int, T>
{
protected override int GetKeyForItem(T item)
{
return (item as Category).Id;
}
/// <summary>
/// Method to get the index into the List{} in the base collection for an item that may or may
/// not be in the collection. Returns -1 if not found.
/// </summary>
protected override int GetItemIndex(T itemToFind)
{
int keyToFind = GetKeyForItem(itemToFind);
return BaseList.FindIndex((T existingItem) =>
GetKeyForItem(existingItem).Equals(keyToFind));
}
}
sql should be OK storing/retrieving anything that's icollection, so while you couldn't use a dictionary, this should work. At least it has worked for me in sqlite (before I've moved away from sqliteAPI to entityframework)
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With