How to bind different properties in listview - c#

I want to use just 1 list view for my ContentPage. The problem is that I need to bind two different types of data from an object list.
I tried to set the bind from code but is working for just 1 list elements
The first ItemSource is the one that is binding the elements.
The second one contains different data but I want to use the same XAML code to display it.
In the xaml part, lets say I can/want reuse: {Binding sRFC} and {Binding sNombre}
PickLista.ItemsSource = lst; // Bound list correctly - this is in code
PickLista.ItemsSource = ls; // List 2 with other object elements - this is in code
<ListView x:Name="myLista" HasUnevenRows="true" Margin="5" SelectionMode="None">
<ListView.ItemTemplate>
<DataTemplate>
<ViewCell>
<StackLayout Orientation="Horizontal" Spacing="5" HeightRequest="40" >
<Label Text="{Binding iId}" VerticalTextAlignment="Start" HorizontalTextAlignment="Start" TextColor="Black" FontSize="15"/>
<Label Text="{Binding sRFC}" VerticalTextAlignment="Start" HorizontalTextAlignment="Start" TextColor="Black" FontSize="15"/>
<Label Text="{Binding sNombre}" VerticalTextAlignment="Start" HorizontalTextAlignment="Start" TextColor="Black" FontSize="15"/>
</StackLayout>
</ViewCell>
</DataTemplate>
</ListView.ItemTemplate>
</ListView>
I want to be able to display both object elements in the same list view, or if i can use another listview in the same position over the other (via XAML).

If those properties are named the same in both classes and satisfy everything required for binding it will work. So either you have different name or properties in some class are not public or don't have getters...

Related

Xamarin Form Add Multiple Binding

Please I need help.
I have my Xamarin Form app that works very well with DataBinding to its View Model named OrderDetailViewModel.
But today I have to add another DataBinding field in line 10 Binding OrderStatusMessage that is bind to its Xaml.cs file (code behind) but out of curiosity this field doesn't work I mean it is not changing the Label Text dynamically after binding the label text to a property located in its xaml.cs file (code behind file).
In line 4 you can find the data binding to MVVM file called OrderDetailViewModel which works well.
But the issue is in line 10 Binding OrderStatusMessage which is a DataBinding to its own xaml.cs file doesn't change the Label text to new message.
I tested the same code Binding OrderStatusMessage outside of the CollectionView.ItemTemplate tag and it's working properly, so only when I put inside CollectionView.ItemTemplate tag that's is not pulling the updated text.
In the below code there's only one property that is bind to its xaml.cs file (code behind) which is in line 10 {Binding OrderStatusMessage} that doesn't get the updated text, the rest are bind to the MVVM which works well.
PS : I would like to add Multiple Binding to this below code in line 4 :
filename : OrderDetailViewPage.xaml
<CollectionView.ItemTemplate >
<DataTemplate >
<StackLayout
xct:TouchEffect.LongPressCommand="{Binding LongPressCommand, Source={RelativeSource AncestorType={x:Type local:OrderDetailViewModel}}}"
xct:TouchEffect.LongPressCommandParameter="{Binding .}"
xct:TouchEffect.PressedScale="1.2"
xct:TouchEffect.NativeAnimation="True">
<StackLayout>
<Label Text="{Binding OrderStatusMessage}" HorizontalOptions="CenterAndExpand" FontFamily="fasolid" FontSize="18" FontAttributes="Bold" TextColor="Black"/>
</StackLayout>
<Label Text="{Binding Id}"
FontSize="Medium"/>
<Label Text="Order number" HorizontalOptions="CenterAndExpand"/>
<Label Text="{Binding OrderId}"
TextColor="Purple" FontAttributes="Bold"
FontSize="Large" HorizontalOptions="CenterAndExpand"/>
<Label Text="{Binding OrderDetail}"
TextColor="Purple"
FontSize="Small" />
<Label Text="{Binding OrderDate}"
TextColor="Purple"
FontSize="Small" />
<Label Text="{Binding IsOrderComplete}"
TextColor="Purple"
FontSize="Small" />
</StackLayout>
</DataTemplate>
</CollectionView.ItemTemplate>
Have you tried bind your Label inside CollectionView.ItemTemplate using Path property?
Like this : <Label Text = "{Binding Path=OrderStatusMessage, Source = {x:Reference pageName}}"/>

Change a button's image on tap of other button inside a list view, view cell

I have a listview. This list view has 5 rows with two buttons namely A & B. When I tap on button A on a row, I want to change the image on A as well as B on the same row and vice-versa. I am able to individually tap and change the image on the same button but don't know how to change the image on the other button. Here is my listview:
<ListView x:Name="GroupedView" SeparatorColor="Transparent" GroupDisplayBinding="{Binding Title}" IsGroupingEnabled="true" HasUnevenRows="true" >
<ListView.GroupHeaderTemplate>
<DataTemplate>
<ViewCell>
<StackLayout Orientation="Horizontal" Padding="5" BackgroundColor="#E2F5F9">
<Label Text="{Binding Title}" TextColor="{StaticResource NavyBlue}" />
</StackLayout>
</ViewCell>
</DataTemplate>
</ListView.GroupHeaderTemplate>
<ListView.ItemTemplate>
<DataTemplate>
<ViewCell>
<StackLayout Orientation="Horizontal" Spacing="2" Padding="5">
<StackLayout VerticalOptions="FillAndExpand">
<Label Text="{Binding QuestionName}" />
</StackLayout>
<StackLayout IsVisible="{Binding ShowYesNo}" Spacing="15" Orientation="Horizontal" HorizontalOptions="End">
<Button ClassId="Yes" Clicked="ChoiceSelected" CommandParameter="{Binding question_id}" Image="{Binding YesChoiceImg}" />
<Button ClassId="No" Clicked="ChoiceSelected" CommandParameter="{Binding question_id}" Image="{Binding NoChoiceImg}" />
</StackLayout>
</StackLayout>
</ViewCell>
</DataTemplate>
</ListView.ItemTemplate>
</ListView>
I am then using the sender to identify the class ID and change the image of the button.
Should I be using a command? Should I be doing something else? Please help. Thanks
If you want to use the CommandParameter you should be using a Command. At the moment you're mixing 2 different ways to handle the click.
One thing to note though is that if you use a command you usually want to bind it to a Command that is defined on your ViewModel but since inside the DataTemplate your BindingContext is the ListView item instead of the ViewModel so you have to reference around that. Something like this should work:
<DataTemplate>
<ViewCell>
<StackLayout Orientation="Horizontal" Spacing="2" Padding="5">
<StackLayout VerticalOptions="FillAndExpand">
<Label Text="{Binding QuestionName}" />
</StackLayout>
<StackLayout IsVisible="{Binding ShowYesNo}" Spacing="15" Orientation="Horizontal" HorizontalOptions="End">
<Button ClassId="Yes" Command="{Binding Path=BindingContext.ButtonCommand, Source={x:Reference MyQuestionPage}}" CommandParameter="{Binding .} Image="{Binding YesChoiceImg}" />
<Button ClassId="No" Clicked="ChoiceSelected" CommandParameter="{Binding question_id}" Image="{Binding NoChoiceImg}" />
</StackLayout>
</StackLayout>
</ViewCell>
</DataTemplate>
Note here that you have to give your ContentPage an x:Name (so you can reference it and call the BindingContext on it). And the "{Binding .}" binds to the current list item. So no need to search for it on id you can just plug it into the command directly!

How to data bind a ListView item to an item in a structured list with multiple indexes?

I'm attempting to data bind a list of information to a ListView in Xamarin.forms, but I'm having issues because of how it is indexed. I need to get the string of information found in sortedList[0].Info[multiple indexes].CoverLink to display on my Image element inside of my Xamarin app, but I'm not sure how to go about it. My Xaml file is as follows:
<ListView RowHeight="100" x:Name="PinnedListView">
<ListView.ItemTemplate>
<DataTemplate>
<ViewCell>
<StackLayout Orientation="Horizontal" HorizontalOptions="Start">
<Image Source="{Binding CoverLink}" HeightRequest="100"/>
<StackLayout Orientation="Vertical">
<Label Text="{Binding ID}"/>
<Label Text="{Binding SomeOtherBinding}"/>
</StackLayout>
</StackLayout>
</ViewCell>
</DataTemplate>
</ListView.ItemTemplate>
</ListView>
and I'm assigning the ItemSource via c# by stating:
PinnedListView.ItemsSource = sortedList;
Here is a screenshot of my list architecture:
How to data bind it? Thanks.
you need to specify which element of the Info array you want to use
<Image Source="{Binding Info[0].CoverLink}" HeightRequest="100"/>
As you can see, the CoverLink is in the Infonested array, so, in order to access to it try this:
<Image Source="{Binding Info[0].CoverLink}" HeightRequest="100"/>

What is Causing this Exception in Xamarin xaml?

I've been working on a UWP app for quite some time. We recently decided to transition over to Xamarin so that we can easily support Android alongside UWP. I've had no issues setting up a PCL to use for our code base. Now I'm running into some nightmares when trying to rewrite our UI for Xamarin.Forms. I'm trying to accomplish something relatively simple and I must be doing something hilariously wrong, but, I cannot figure out what.
I want to display a listView. Here's the XAML:
<ContentPage.Content>
<StackLayout>
<Label Text="This is the bill page."
VerticalOptions="CenterAndExpand"
HorizontalOptions="CenterAndExpand" />
<ListView x:Name="lvBills"
ItemsSource="{Binding Bills}"
SelectedItem="{Binding SelectedBill}">
<ListView.ItemTemplate>
<DataTemplate>
<StackLayout Orientation="Horizontal">
<Label Text="{Binding Amount}"
TextColor="White"
VerticalOptions="CenterAndExpand"
HorizontalOptions="CenterAndExpand"/>
<Label Text="{Binding DueDate}"
VerticalOptions="CenterAndExpand"
HorizontalOptions="CenterAndExpand"
TextColor="White"/>
</StackLayout>
</DataTemplate>
</ListView.ItemTemplate>
</ListView>
</StackLayout>
</ContentPage.Content>
When I run it, the listView populates with each item in my observable collection. However, no text is actually displayed..even if I remove the bindings and use some placeholder text. Additionally, if I click on any item in the listView, this exception crashes the program.
System.InvalidCastException: Unable to cast object of type
'Xamarin.Forms.StackLayout' to type 'Xamarin.Forms.Cell'.
at Xamarin.Forms.Internals.TemplatedItemsList`2.ActivateContent(Int32 index,
Object item)
at Xamarin.Forms.Internals.TemplatedItemsList`2.CreateContent(Int32 index, O
Object item, Boolean insert)
at Xamarin.Forms.Internals.TemplatedItemsList`2.GetOrCreateContent(Int32
index, Object item)
at Xamarin.Forms.Internals.TemplatedItemsList`2.get_Item(Int32 index)
at Xamarin.Forms.L
I can't figure out any search that yields any meaningful results. I've tried some other things: Adding a binding for ItemSelected in the xaml. I've tried to wire up delegates in the xaml.cs But I cannot make any progress. So, what am I doing wrong?
You need a ViewCell inside a DataTemplate:
<ContentPage.Content>
<StackLayout>
<Label Text="This is the bill page."
VerticalOptions="CenterAndExpand"
HorizontalOptions="CenterAndExpand" />
<ListView x:Name="lvBills"
ItemsSource="{Binding Bills}"
SelectedItem="{Binding SelectedBill}">
<ListView.ItemTemplate>
<DataTemplate>
<ViewCell> <!-- <----- Add this -->
<StackLayout Orientation="Horizontal">
<Label Text="{Binding Amount}"
TextColor="White"
VerticalOptions="CenterAndExpand"
HorizontalOptions="CenterAndExpand"/>
<Label Text="{Binding DueDate}"
VerticalOptions="CenterAndExpand"
HorizontalOptions="CenterAndExpand"
TextColor="White"/>
</StackLayout>
</ViewCell>
</DataTemplate>
</ListView.ItemTemplate>
</ListView>
</StackLayout>
</ContentPage.Content>

List within List in Xamarin.forms xaml

I have a ditcionary with values as lists of string. In my xaml I bind the dictionary to a list and within that list I print out the key. I then want to print out a list of value for each key. What should I bind to the Value list and what should I bind to the Value label?
Here is my xaml:
<ListView x:Name ="QuoteListView" ItemsSource ="{Binding dict}" HasUnevenRows="True">
<ListView.ItemTemplate>
<DataTemplate >
<ViewCell >
<ViewCell.View >
<StackLayout>
<StackLayout Orientation="Horizontal" Padding="10">
<Label Text ="{Binding Key}" FontSize="10" FontAttributes="Bold" TextColor="White" />
</StackLayout>
<StackLayout Orientation="Horizontal" Padding="10">
<ListView x:Name ="QuoteTextListView" ItemsSource ="{Binding }" HasUnevenRows="True">
<Label Text ="{Binding }" FontSize="10" TextColor="White"/>
</ListView>
</StackLayout>
</StackLayout>
</ViewCell.View>
</ViewCell>
</DataTemplate>
</ListView.ItemTemplate>
</ListView>
This is what I want to achieve:
Name 1
"Quote 1 text"
"Quote 2 text"
Name 2
"Quote 1 text"
"Quote 2 text"
...
I would suggest using ListView Grouping. You can turn your dictionary into 2 lists. ListView Grouping info can be found here.
Basically you will create an object to store the list of Quote strings. Then you take that object and put it into another object representing the list of Names. Let me know if you have any issues.

Categories