I am trying to create a layout where there is repetitive list of custom entry and when on change of any text List appears, SuggestedText
, which is just an string observation collection that is initialized during the viewmodal is constructed.
<StackLayout BindableLayout.ItemsSource="{Binding MyObjectLists.ListofLicensePlates}" VerticalOptions="FillAndExpand">
<BindableLayout.ItemTemplate>
<DataTemplate>
<Frame Margin="0,10,0,10" Padding="0" HasShadow="False" BackgroundColor="Transparent">
<Grid Margin="20">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="*" ></ColumnDefinition>
<ColumnDefinition Width="*"></ColumnDefinition>
</Grid.ColumnDefinitions>
<StackLayout Orientation="Vertical" Grid.Column="0" Grid.Row="0" >
<Label Text="Text1" TextColor="Black" FontAttributes="Bold" Grid.Column="0" Grid.Row="0" />
<AbsoluteLayout>
<Frame Grid.Column="0" Grid.Row="1" Padding="5" HasShadow="False" BorderColor="{StaticResource GrayBorderColor}" CornerRadius="30" HeightRequest="55" HorizontalOptions="FillAndExpand">
<controls:BorderlessEntry
TextTransform="Uppercase" Text="{Binding LicensePlate}"
Index = "{Binding Index}"
TextChanged ="ShowListView" Completed="ShowListView"
MaxLength="50" x:Name="Text1" Keyboard="Text"
Placeholder="Text1"
AbsoluteLayout.LayoutBounds="15,70,285,38" AbsoluteLayout.LayoutFlags="None"
FontFamily="OpenSansRegular" />
</Frame>
<ListView BindableLayout.ItemsSource="{Binding Path=BindingContext.SuggestedText, Source={x:Reference thispage}}"
x:Name="LicensePlateListView" IsVisible="{Binding IsVisible}" CachingStrategy="RecycleElement"
BackgroundColor="White" ItemTapped="OnItemTapped" AbsoluteLayout.LayoutBounds="20,110,269,160"
AbsoluteLayout.LayoutFlags="None">
<BindableLayout.ItemTemplate>
<DataTemplate>
<StackLayout BackgroundColor="White">
<Label Text="{Binding .}" FontSize="16" TextColor="#FF464859"/>
</StackLayout>
</DataTemplate>
</BindableLayout.ItemTemplate>
</ListView>
</AbsoluteLayout>
</Grid>
</Frame>
</DataTemplate>
</BindableLayout.ItemTemplate>
</StackLayout>
This is how suggested text was created:
public class MyViewModel : BaseViewModel
{
public LicensePlateListViewModel()
{
}
public MyViewModel (MyObject parameters, INavigation navigation)
{
MyObjectLists = parameters;
Device.BeginInvokeOnMainThread(() => {
try
{
FillSuggestText();
}
catch (Exception ex)
{
IsBusy = false;
Helper.GlobalErrorTrashing(ex);
}
});
}
private MyObject myObjectLists;
public MyObject MyObjectLists
{
get { return myObjectLists; }
set { myObjectLists= value; OnPropertyChanged(); }
}
private ObservableCollection<string> suggestedText;
public ObservableCollection<string> SuggestedText
{
get { return suggestedText; }
set { suggestedText= value; OnPropertyChanged(); }
}
public void FillSuggestText()
{
if (PaidGuestParking.GuestZoneParking.Parkings != null)
{
var texts = MyObjectLists.TextList.Select(p => p.Text).ToList();
foreach(var text in texts ) {
SuggestedText.Add(text);
}
}
}
...
...
...
}
And MyObject is something like this:
public class MyObject
{
public List<TextObject> TextList { get; set; }
public ObservableCollection<string> ListofLicensePlates { get; set; }
}
And show list view is a simple function that changes IsVisible
for that particular listview under the entry. It works fine if I statically list all the list view source but whenever I try to do it dynamically adding the content from SuggestedText, I get error before navigating to this page.
ex = {System.InvalidCastException: Specified cast is not valid.
at Xamarin.Forms.BindableLayout <>c.<.cctor>b__19_4 (Xamarin.Forms.BindableObject b) [0x00000] in D:\a\1\s\Xamarin.Forms.Core\BindableLayout.cs:24
at Xamarin.Forms.BindableObject.CreateAndAddCo...
I am really stuck at this place please suggest me something, I am also willing to change such that the suggesttext is in MyObjectLists itself so that the suggesttext may be different for different inputs but doing so also prompted same error.
CodePudding user response:
From the code you posted,I found that you set MyObjectLists
as the BindableLayout.ItemsSource
of StackLayout
, so the variable MyObjectLists
should be a collection of IEnumerable items
.
<StackLayout BindableLayout.ItemsSource="{Binding MyObjectLists}" >
But from code below included in MyViewModel.cs
, we can find it looks like a simple Object (MyObject
).Please recheck it.
private MyObject myObjectLists;
public MyObject MyObjectLists
{
get { return myObjectLists; }
set { myObjectLists= value; OnPropertyChanged(); }
}
In addition,if you want to bind the parent's variable SuggestedText
to the inner ListView
, you can try to replace BindableLayout.ItemsSource
with ItemsSource
and replace BindableLayout.ItemTemplate
with ListView.ItemTemplate
.
Please refer to the following code:
<ListView ItemsSource="{Binding Path=BindingContext.SuggestedText, Source={x:Reference thispage}}"
x:Name="LicensePlateListView" CachingStrategy="RecycleElement"
BackgroundColor="White" >
<ListView.ItemTemplate>
<DataTemplate>
<ViewCell>
<StackLayout BackgroundColor="White">
<Label Text="{Binding .}" FontSize="16" TextColor="#FF464859"/>
</StackLayout>
</ViewCell>
</DataTemplate>
</ListView.ItemTemplate>
</ListView>
Or you can also use StackLayout BindableLayout
instead:
<StackLayout BindableLayout.ItemsSource="{Binding Path=BindingContext.SuggestedText, Source={x:Reference thispage}}" Orientation="Horizontal" >
<BindableLayout.ItemTemplate>
<DataTemplate>
<StackLayout BackgroundColor="White">
<Label Text="{Binding .}" FontSize="16" TextColor="#FF464859"/>
</StackLayout>
</DataTemplate>
</BindableLayout.ItemTemplate>
</StackLayout>
Note:
If you use ListView
, remember to add tag <ViewCell> </ViewCell>
.