XAML Binding to dynamic nested objects - c#

I have a response from a JSON API and map it in my Code to an Object.
The Object Structure looks like this:
public class A {
public B b;
public C c;
public D d;
}
public class B{
public string a;
public string b;
}
...
public class D{
public F[] f;
}
public class F{
public string c;
public string d;
public string e;
}
I set up my Binding to an Observable Collection <A> aCollection and it's working fine. I have some Objects of A and can access all members like this.
<ListView ItemsSource="{Binding aCollection}">
<ListView.ItemTemplate>
<DataTemplate>
<ViewCell>
<StackLayout>
<Label Text="{Binding b.a, TargetNullValue='-'}"/>
<Label Text="{Binding c.a, TargetNullValue='-'}"/>
</StackLayout>
</ViewCell>
</DataTemplate>
</ListView.ItemTemplate>
</ListView>
But I don't know how I can access the Array F[] and the members of F. Also I don't know in advance how large the array will be.
What I want to achieve is to display every entry in the array in relation to the containing Object A.
Hope this question makes sense.

If you want to bind Array data into every cell in listview .According to your code you can modify like this:
<ListView ItemsSource="{Binding aCollection}">
<ListView.ItemTemplate>
<DataTemplate>
<ViewCell>
<StackLayout>
<Label Text="{Binding b.a, TargetNullValue='-'}"/>
<Label Text="{Binding c.a, TargetNullValue='-'}"/>
//***
<ListView ItemsSource="{Binding d.F}">
<ListView.ItemTemplate>
<DataTemplate>
<ViewCell>
<StackLayout>
<Entry Text="{Binding c}"/>
<Entry Text="{Binding d}"/>
<Entry Text="{Binding e}"/>
</StackLayout>
</ViewCell>
</DataTemplate>
</ListView.ItemTemplate>
</ListView>
//***
</StackLayout>
</ViewCell>
</DataTemplate>
</ListView.ItemTemplate>
</ListView>
use listview contain a listview to show data etc.And your class D change to
public class {
public List<F> f{ get; set; }
}
Not sure whether is you want,hope to be useful.

Related

How to fix binding issue in ListView

Im trying to bind my ListView to an observableCollection on my ViewModel. The other bindings on the same class are working but i dont see any data where my list is supposed to be.
Ive tried setting the rows uneven, instantiating a separate Collection, and using breakpoints to confirm there is data.
Here is the xaml code:
<StackLayout Spacing="10" Padding="7" Grid.Row="1" Grid.Column="0">
<Label Text="Name:" FontSize="Medium"/>
<Label Text="{Binding order.Name}" FontSize="Small"/>
<Label Text="Price:" FontSize="Medium"/>
<Label Text="{Binding order.Price}" FontSize="Small"/>
</StackLayout>
<ListView ItemsSource="{Binding order.foodItems}" Grid.Row="0" Grid.Column="0" HasUnevenRows="True">
<ListView.ItemTemplate>
<DataTemplate>
<ViewCell>
<StackLayout Padding="10" Orientation="Horizontal" HorizontalOptions="Fill">
<Label Text="{Binding Name}" FontSize="Medium"/>
<Label Text="{Binding Quantity}" FontSize="Medium" />
</StackLayout>
</ViewCell>
</DataTemplate>
</ListView.ItemTemplate>
</ListView>
Here is my ViewModel
Order _order;
public Order order
{
get { return _order; }
set { SetProperty<Order>(ref _order, value); }
}
public OrderDetailViewModel(Order value)
{
order = value;
}
The order class:
public class Order
{
public string Name { get; set; }
public ObservableCollection<IFoodItems> foodItems;
public double Price { get; set; }
public Order(string name)
{
Name = name;
foodItems = new ObservableCollection<IFoodItems>();
}
public void SetPrice(double value)
{
Price = value;
}
public void AddItem(IFoodItems food)
{
foodItems.Add(food);
}
}

Xamarin, Binding Enum to ListView

I have a list of Programs and I binding it to Xamarin forms ListView
public class Program
{
public string Text { get; set; }
public string Color { set; get; }
public LayoutAlignment LangDirection { set; get; }
}
Text and Color works fine but LangDirection of type LayoutAlignment not working!
<ListView x:Name="ItemsListView"
ItemsSource="{Binding Items}">
<ListView.ItemTemplate>
<DataTemplate>
<ViewCell>
<StackLayout Padding="10">
<Label TextColor="{Binding Color}"
Text="{Binding Text}"
FontSize="16"
HorizontalOptions="{Binding LangDirection}"
/>
</ViewCell>
</DataTemplate>
</ListView.ItemTemplate>
</ListView>
And no error occur

How to Bind a command of child class object declared in Main context ViewMOdel xamarin forms

I am having a page(MyPage) and Corresponding view Model(MypageViewModel). I have another view model called(listItemLogicVM) and its declared as observable collection in MypageViewModel.
MyPage XAML
<ListView x:Name="lstvwItemSelected" ItemsSource="{Binding
LstlistItemLogicVM}">
<ListView.ItemTemplate>
<DataTemplate>
<ViewCell >
<StackLayout>
<Entry Text="{Binding RequestingQty,Mode=TwoWay}"/>
<Image Source="ArrowUp.png"><Image.GestureRecognizers>
<TapGestureRecognizer Command="{Binding QtyDecrementCommand}"/>
</Image.GestureRecognizers>
</Image>
</StackLayout>
</ViewCell>
</DataTemplate>
</ListView.ItemTemplate>
</ListView>
MypageViewModel
public class MypageViewModel
{
ObservableCollection<listItemLogicVM> lstvwItemSelected = new ObservableCollection<listItemLogicVM>()
.
-- OtherLogics
.
}
listItemLogicVM
public class listItemLogicVM
{
public Command QtyDecrementCommand { get; set; }
public int RequestingQty
{
get { return _requestingQty; }
set { _requestingQty = value; OnPropertyChanged();}
}
}
Above Binding throws error. Can anyone help me to bind the command and property of listItemLogicVM to the list view in MyPage XAML
It looks to me like your listview XAML is incorrect. Try this (note the only changes are to the x:Name and ItemsSource attribute of your ListView):
<ListView x:Name="myUniqueListName" ItemsSource="{Binding
lstvwItemSelected}">
<ListView.ItemTemplate>
<DataTemplate>
<ViewCell >
<StackLayout>
<Entry Text="{Binding RequestingQty,Mode=TwoWay}"/>
<Image Source="ArrowUp.png"><Image.GestureRecognizers>
<TapGestureRecognizer Command="{Binding QtyDecrementCommand}"/>
</Image.GestureRecognizers>
</Image>
</StackLayout>
</ViewCell>
</DataTemplate>
</ListView.ItemTemplate>
</ListView>
That should call the QtyDecrementCommand on the item that is tapped in the list. This assumes that you've correctly assigned some code to that command for each item in the list.
You need to add command in your MypageViewModel and your xaml code look like :
<TapGestureRecognizer Command="{Binding Source={x:Reference lstvwItemSelected}, Path=BindingContext.QtyDecrementCommand}"/>
</Image.GestureRecognizers>

XAML ListView in Xamarin does not work

I started to learn Xamarin, and i am trying to create first test project. I created the ListView which displays the ObservableCollection from BindingContext. "Take" is a table that has three properties. The problem is, that when i run app on emulator the following eror dialog appears:"Process system isn't responding. Do you want to close it?"
But if i erase tag and all internal XAML code everything works well, but i want to dispalay values of properties of class "Take" in each element of ListView.
<?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="App1.Views.Page1">
<ContentPage.Content>
<StackLayout>
<Label Text="Welcome to my first project"></Label>
<Label Text="Why does it does not work?"></Label>
<ListView ItemsSource="{Binding GetList}">
<ListView.ItemTemplate>
<DataTemplate>
<TextCell Text="{Binding Word}"></TextCell>
<Button Text="SomeText"></Button>
</DataTemplate>
</ListView.ItemTemplate>
</ListView>
</StackLayout>
</ContentPage.Content>
</ContentPage>
And this is my C# BindingContext
public class SQLiteSamplePage
{
private readonly SQLiteConnection _sqLiteConnection;
private ObservableCollection<Take> list;
public SQLiteSamplePage()
{
_sqLiteConnection = DependencyService.Get<ISQLite>().GetConnection();
_sqLiteConnection.CreateTable<Take>();
_sqLiteConnection.Insert(new Take
{
Word = "SomeWord1",
Translation = "Some translation 1"
});
_sqLiteConnection.Insert(new Take
{
Word = "SomeWord",
Translation = "SomeTranslation"
});
list =new ObservableCollection<Take>( _sqLiteConnection.Table<Take>());
}
public ObservableCollection<Take> GetList
{
get { return list; }
}
}
And here is a code of a table
public class Table
{
[PrimaryKey, AutoIncrement]
public int ID { get; set; }
public string Word { get; set; }
public string Translation { get; set; }
}
Try to put the TextCell and the Button in a StackLayout or any kind of layout inside a <ViewCell> element:
<ListView ItemsSource="{Binding GetList}">
<ListView.ItemTemplate>
<DataTemplate>
<ViewCell>
<StackLayout>
<TextCell Text="{Binding Word}"></TextCell>
<Button Text="SomeText"></Button>
</StackLayout>
</ViewCell>
</DataTemplate>
</ListView.ItemTemplate>
</ListView>
The child of the DataTemplate element must be of or derive from type ViewCell.
You cannot combine a TextCell and something else, in your case a Button. If you want to show both Text and the Button you will need to use a custom cell.
This is done using the base class ViewCell and inside there you define the layout you want to show
<StackLayout>
<Label Text="Welcome to my first project"></Label>
<Label Text="Why does it does not work?"></Label>
<ListView ItemsSource="{Binding GetList}">
<ListView.ItemTemplate>
<DataTemplate>
<ViewCell>
<StackLayout>
<Label Text="{Binding Word}"></Label>
<Button Text="SomeText"></Button>
</StackLayout>
</ViewCell>
</DataTemplate>
</ListView.ItemTemplate>
</ListView>
</StackLayout>
Hope this helps.

not able to toggle Switch

At the moment I am programming an application based on Xamarin. My goal is to toggle the switch based on values in a table. Problem is, Xamarin is not noticing my x:Name toggle_true connected to my switch.
Here is my script in xaml:
<ListView x:Name="defineBuildingItems">
<ListView.ItemTemplate>
<DataTemplate>
<ViewCell>
<StackLayout Orientation="Horizontal">
<StackLayout Orientation="Vertical">
<Label Text="{Binding defineDescription}" x:Name="Current_item"/>
</StackLayout>
<Switch BindingContext ="{Binding defineId}" HorizontalOptions="EndAndExpand"
Toggled="Handle_Toggled" x:Name="toggled_true"/>
</StackLayout>
</ViewCell>
</DataTemplate>
</ListView.ItemTemplate>
</ListView>
Here is my c# code in code behind:
var currentQuestions = _define.Where(s => DefineId.Contains(s.defineId));
//Remember what building was defined like last time defineBuilding was proceeded.
foreach (DefineTable i in currentQuestions)
{
toggled_true.IsToggled = true;
}
defineBuildingItems.ItemsSource = posts;
base.OnAppearing();
}
Notice how it recognizes the x:Name defineBuildingItems. The error i get on toggled_true is: The name toggled_true does not exist in the current namespace. Is there something I am doing wrong or missing?
Access to control by name inside datatemplate not working. You must using binding. This is simply example:
Model:
public class Data
{
public bool IsToggled {get;set;}
....
}
Code behind:
public YourPage
{
BindingContext = this;
}
....
private List<Data> _items;
public List<Data> Items
{
get { return _items;}
set
{
_items = value;
OnPropertyChanged();
}
}
Your xaml:
<ListView x:Name="defineBuildingItems" ItemSources={Binding Items}>
<ListView.ItemTemplate>
<DataTemplate>
<ViewCell>
<StackLayout Orientation="Horizontal">
<StackLayout Orientation="Vertical">
<Label Text="{Binding defineDescription}" />
</StackLayout>
<Switch IsToggled ="{Binding IsToggled, Mode =TwoWay}" HorizontalOptions="EndAndExpand" />
</StackLayout>
</ViewCell>
</DataTemplate>
</ListView.ItemTemplate>
</ListView>

Categories

Resources