I have a button inside a listview, but clicking the button returns the error:
Exception thrown: 'System.InvalidCastException'. **
**In line: ((ContentPage)((ListView)((StackLayout)((StackLayout)b.Parent).Parent).Parent).Parent).DisplayAlert("Clicked", item.Title.ToString() + " button was clicked", "OK");
What is wrong?
public class ListViewButton : ContentPage { public class ListItem { public string Source { get; set; } public string Title { get; set; } public string Description { get; set; } public string Price { get; set; } } public ListViewButton() { var listView = new ListView(); listView.ItemsSource = new ListItem[] { new ListItem {Title = "First", Description="1st item", Price="$100.00"}, new ListItem {Title = "Second", Description="2nd item", Price="$200.00"}, new ListItem {Title = "Third", Description="3rd item", Price="$300.00"} }; listView.RowHeight = 100; listView.BackgroundColor = Color.Black; listView.HasUnevenRows = true; listView.ItemTemplate = new DataTemplate(typeof(ListItemCell)); Content = listView; listView.ItemTapped += async (sender, e) => { ListItem item = (ListItem)e.Item; await DisplayAlert("Tapped", item.Title.ToString() + " was selected.", "OK"); ((ListView)sender).SelectedItem = null; }; this.Padding = new Thickness(0, Device.OnPlatform(20, 0, 0), 0, 0); } class ListItemCell : ViewCell { public ListItemCell() { Label titleLabel = new Label { HorizontalOptions = LayoutOptions.Start, FontSize = 20, FontAttributes = Xamarin.Forms.FontAttributes.Bold, TextColor = Color.White }; titleLabel.SetBinding(Label.TextProperty, "Title"); Label descLabel = new Label { HorizontalOptions = LayoutOptions.Start, FontSize = 12, TextColor = Color.White }; descLabel.SetBinding(Label.TextProperty, "Description"); StackLayout viewLayoutItem = new StackLayout() { HorizontalOptions = LayoutOptions.Start, Orientation = StackOrientation.Vertical, WidthRequest = 120, Children = { titleLabel, descLabel } }; Label priceLabel = new Label { HorizontalOptions = LayoutOptions.Center, FontSize = 25, TextColor = Color.Aqua }; priceLabel.SetBinding(Label.TextProperty, "Price"); var button = new Button //ListButton // Android workaround { Text = "Buy Now", BackgroundColor = Color.Teal, HorizontalOptions = LayoutOptions.EndAndExpand }; string titulo; button.SetBinding(Button.CommandParameterProperty, new Binding(".")); button.Clicked += (sender, e) => { var b = (Button)sender; var item = (ListItem)b.CommandParameter; ((ContentPage)((ListView)((StackLayout)((StackLayout)b.Parent).Parent).Parent).Parent).DisplayAlert("Clicked", item.Title.ToString() + " button was clicked", "OK"); }; StackLayout viewButton = new StackLayout() { HorizontalOptions = LayoutOptions.EndAndExpand, Orientation = StackOrientation.Horizontal, WidthRequest = 260, Children = { priceLabel, button } }; StackLayout viewLayout = new StackLayout() { HorizontalOptions = LayoutOptions.StartAndExpand, Orientation = StackOrientation.Horizontal, Padding = new Thickness(5, 10, 5, 15), Children = { viewLayoutItem, viewButton } }; View = viewLayout; } } }
Posts
@antoniojr - In this line
((ContentPage)((ListView)((StackLayout)((StackLayout)b.Parent).Parent).Parent).Parent).DisplayAlert("Clicked", item.Title.ToString() + " button was clicked", "OK");
One of your casts is not correct. Its a bit hard to tell without debugging, but if you breakpoint this line, then check each parent.
However this is generally not the best way to achieve what you want.
Instead put this in your ContentPage
Then do
ListViewButton.Main.DisplayAlert("Clicked", item.Title.ToString() + " button was clicked", "OK");
Ideally if you have a navigation page or something above you would static the NavigationPage or hold a reference and call that directly, rather than the ContentPage.
You can try with Application.Current.MainPage.DisplayAlert
Alessandro and Adam, thank you for your help. The two worked!
Yes, but mine is better ahahah
hahahahahahaha
Now the error by clicking the button
file: App.g.i.cs
if DEBUG && !DISABLE_XAML_GENERATED_BREAK_ON_UNHANDLED_EXCEPTION
endif
Message: "Access is denied. (Exception from HRESULT: 0x80070005 (E_ACCESSDENIED))"
Native View: Unable to evaluation the expression.Operation not suported. Unkdown erro0x80070057
Stacktrace:
" at Windows.UI.Popups.MessageDialog.ShowAsync()\r\n at Xamarin.Forms.Platform.WinRT.Platform.d__55.MoveNext()\r\n--- End of stack trace from previous location where exception was thrown ---\r\n at System.Runtime.CompilerServices.AsyncMethodBuilderCore.b__3(Object state)\r\n at System.Threading.WinRTSynchronizationContext.Invoker.InvokeCore()"
What is going on?
@antoniojr - DisplayAlert needs to be called on the Main UI Thread (WinRT/UWP especially) but a button is called on the UI Thread so I am not seeing how this error is occurring, unless you moved the code elsewhere.
Try
@AdamP
OK thank you!
the displayalert would be to see if you are returning the button event properly. At the debug item.Title receives the value correctly in clicked, but would like to assign this value to a line label in my ContentPage.
How would I do?