How to get the value from Listview Xamarin.form - c#

I want to get the value from my clubid that I web service and pass it down to the next page so I would have a dynamic club detail. However, when I tried to do it, it shows me some errors. This are my codes.
ListClubs.xaml.cs
ClubApiClient service = new ClubApiClient();
public ListClubs ()
{
InitializeComponent();
}
protected async override void OnAppearing()
{
base.OnAppearing();
await setClubs(Clublistview);
}
private async Task setClubs(ListView listview)
{
var clublist = await service.getClubList(2);
listview.ItemsSource = clublist.ToList();
}
async void OnListClubsClicked(object sender, EventArgs e)
{
int clubid = int.Parse(lbId.Text); //Error msg: The name 'lbId' does not exist in the context
await Navigation.PushAsync(new DetailedClub());
}
ListClubs.xaml
<ListView x:Name="Clublistview">
<ListView.ItemTemplate>
<DataTemplate>
<ViewCell>
<StackLayout BackgroundColor="White"
Orientation="Vertical">
<StackLayout Orientation="Horizontal">
<Image Source="{Binding Logo}" IsVisible="true" WidthRequest="42" HeightRequest="42"/>
<Button Text="{Binding Name}" x:Name="BtnClub" AbsoluteLayout.LayoutBounds="100, 25, 100, 25" Clicked="OnListClubsClicked" TextColor="Black" VerticalOptions="FillAndExpand"/>
<Label Text="{Binding Id}" x:Name="lbId" IsVisible="false"/>
</StackLayout>
</StackLayout>
</ViewCell>
</DataTemplate>
</ListView.ItemTemplate>
</ListView>

using the name "lbId" isn't useful because every item in your list has a Label named "lbId".
You can use CommandParameter to add the Id to your Button
<Button Text="{Binding Name}" x:Name="BtnClub" AbsoluteLayout.LayoutBounds="100, 25, 100, 25" Clicked="OnListClubsClicked" TextColor="Black" VerticalOptions="FillAndExpand" CommandParameter="{Binding Id}" />
async void OnListClubsClicked(object sender, EventArgs e)
{
Button btn = (Button) sender;
int clubid = (int) btn.CommandParameter;
// pass the clubid to your Detail page
await Navigation.PushAsync(new DetailedClub(clubid));
}

Related

Swipeitem doesnt work when open the app and press the button

The swipeview doesnt work when I open the app and press accept button but it works after when I open and close the detail page.
xaml shows list of events from sql and show swipeitem
<CollectionView x:Name="eventview"
BackgroundColor="Transparent"
ItemSizingStrategy="MeasureAllItems"
SelectionMode="Single"
SelectionChanged="eventview_SelectionChanged"
EmptyView="No Pending events">
<SwipeView.RightItems>
<SwipeItems SwipeBehaviorOnInvoked="Close">
<SwipeItem Text="Decline" BackgroundColor="red"/>
<SwipeItem Text="Accept" BackgroundColor="Green" Invoked="SwipeItem_Invoked"/>
</SwipeItems>
</SwipeView.RightItems>
<Grid Padding="10">
<StackLayout>
<Label Text="{Binding Name}" VerticalOptions="Center" FontSize="Small"/>
<Label Text="{Binding Date}" VerticalOptions="Center" FontSize="Small"/>
<Label Text="{Binding stats}" VerticalOptions="Center" FontSize="Small"/>
</StackLayout>
</Grid>
</SwipeView>
</DataTemplate>
</CollectionView.ItemTemplate>
cs shows click on the item that will open detail page and when click on the swipeitem
private async void eventview_SelectionChanged(object sender, SelectionChangedEventArgs e)
{
lastSelection = e.CurrentSelection[0] as Event;
var eventss = e.CurrentSelection.FirstOrDefault() as Event;
var eventpage = new Eventdetailpage();
eventpage.BindingContext = eventss;
await Navigation.PushAsync(eventpage);
}
private async void SwipeItem_Invoked(object sender, EventArgs e)
{
if (lastSelection != null)
{
lastSelection.stats = "Accepted";
await App.Database.UpdateventAysnc(lastSelection);
eventview.ItemsSource = await App.Database.querypendingevent();
accpetedevents.ItemsSource = await App.Database.queryacceptevent();
}
}
if lastSelection is null, then your if won't execute and nothing will happen
you should be able to get the current item from the sender's BindingContext
var item = (SwipeItem)sender;
lastSelection = (Event)item.BindingContext;

Xamarin - pass data from CollectionView in one page to another page

I want to know how do I pass data from one CollectionView which is in my MainPage.xaml to another page called DetailsPage when user clicks on a frame that is inside a CollectionView, I hope you know what I meant.
This is my MainPage.xaml:
<CollectionView x:Name="CVSubjects" Margin="0,-50,0,0" ItemsLayout="HorizontalList">
<CollectionView.ItemTemplate>
<DataTemplate>
<StackLayout Margin="20,0,0,0">
<Frame BackgroundColor="{Binding BackgroundColor}" WidthRequest="250" HeightRequest="180" HorizontalOptions="Center" CornerRadius="30">
<Frame.GestureRecognizers>
<TapGestureRecognizer Tapped="TapGestureRecognizer_Tapped"/>
</Frame.GestureRecognizers>
<StackLayout>
<Frame BackgroundColor="white" HasShadow="False" WidthRequest="30" HorizontalOptions="Start" CornerRadius="50" HeightRequest="10">
<StackLayout Orientation="Horizontal" HeightRequest="10">
<Image Source="redstaricon.png" WidthRequest="14" Margin="-10,-2,0,0"></Image>
<Label Text="{Binding Rating}" VerticalOptions="Center" Margin="0,-5,0,0" FontAttributes="Bold" TextColor="Black"></Label>
</StackLayout>
</Frame>
<Label Text="{Binding Name}" FontSize="21" TextColor="White" FontAttributes="Bold" Padding="0,10,0,0" WidthRequest="250"></Label>
<StackLayout Orientation="Horizontal">
<Frame CornerRadius="100"
HeightRequest="55"
WidthRequest="60"
HorizontalOptions="Center"
Padding="0"
IsClippedToBounds="True"
Margin="0,20,0,0"
>
<Image Source="{Binding ImageUrl}"
HorizontalOptions="Center"
VerticalOptions="Center"
Aspect="Fill"></Image>
</Frame>
<Label Text="Teacher" TextColor="White" WidthRequest="100" Margin="0,25,0,0">
</Label>
<Label Text="{Binding Teacher}" VerticalOptions="Center" TextColor="White" WidthRequest="200" FontAttributes="Bold" Margin="-100,45,0,0" FontSize="17">
</Label>
</StackLayout>
</StackLayout>
</Frame>
</StackLayout>
</DataTemplate>
</CollectionView.ItemTemplate>
</CollectionView>
and this is MainPage.xaml.cs:
public partial class MainPage : ContentPage
{
ObservableCollection<Subjects> subjects;
public MainPage()
{
InitializeComponent();
subjects = new ObservableCollection<Subjects>() { new Subjects { Id = 1, Name = "UX - UI Design", Teacher = "Gustavo Kenter", Rating = "4.9", BackgroundColor = "#FE2E47", ImageUrl="teacher1.png", TeacherTitle="Designer" },
new Subjects{Id = 2, Name = "Animation in After Effects", Teacher = "Tiana Mango", Rating = "4.3", BackgroundColor = "#FDB2C0", ImageUrl="teacher2.png", TeacherTitle="Animator" },
new Subjects{Id = 3, Name = "Mobile App Design", Teacher = "Dulce Bator", Rating = "4.1", BackgroundColor = "#D0BCD0", ImageUrl="teacher3.png", TeacherTitle="Designer" },
new Subjects {Id = 4, Name = "3D Design", Teacher = "Lincoln Bator", Rating = "4.6", BackgroundColor = "#88B5FC", ImageUrl="teacher4.png", TeacherTitle="3D Designer" },
new Subjects{ Id = 5, Name = "Mobile App Development", Teacher = "Livia Lubin", Rating = "4.7", BackgroundColor = "#FDB2C0", ImageUrl="teacher5.png", TeacherTitle="Developer" } };
GetSubjects();
}
private void GetSubjects()
{
CVSubjects.ItemsSource = subjects;
CVGridSubjects.ItemsSource = subjects;
}
private void TapGestureRecognizer_Tapped(object sender, EventArgs e)
{
Navigation.PushModalAsync(new DetailsPage());
}
}
How do I know pass the data from my CollectionView, I have tried to pass the data through parameters but for some reason when I add a name to for example a lable that contains the name of the subject, I cannot access it inisde c# code, anyone knows how to fix this?
CollectionView has built in events for handling selection, it is not neccesary to use a GestureRecognizer
<CollectionView SelectionMode="Single"
SelectionChanged="OnCollectionViewSelectionChanged" ... >
then you can pass the selected item to the next page via it's constructor
void OnCollectionViewSelectionChanged(object sender, SelectionChangedEventArgs e)
{
var current = (e.CurrentSelection.FirstOrDefault() as Subjects);
Navigation.PushModalAsync(new DetailsPage(current));
}

How to add ItemTapped on ListView with аutomatic assignment of ID from SQLite using xamarin

I have a field to enter ID and a line read button.
When you write the ID and click the button, a message appears with the information on the corresponding line.
I want to remove the button "Read" аnd the input field so that when the user clicks the corresponding line, a message with the information from the line will be displayed ?
My xaml.cs code is:
async void ReadCity()
{
if (!string.IsNullOrEmpty(txtPersonId.Text))
{
//Get Person
var person = await App.SQLiteDb.GetItemAsync(Convert.ToInt32(txtPersonId.Text));
if (person != null)
{
await DisplayAlert("Success", "Person Name: " + person.Name, "OK");
}
}
else
{
await DisplayAlert("Required", "Please Enter PersonID", "OK");
}
}
void BtnRead_Clicked(System.Object sender, System.EventArgs e)
{
ReadCity();
}
My xaml code is:
<StackLayout HorizontalOptions="Center" VerticalOptions="Start">
<Label Margin="0,0,0,10" Text="FAVORITES" FontAttributes="Bold" FontSize="Large" TextColor="Gray" HorizontalTextAlignment="Center" ></Label>
<Entry x:Name="txtPersonId" Placeholder="City ID for Delete"></Entry>
<StackLayout HorizontalOptions="CenterAndExpand" Orientation="Horizontal">
<Button x:Name="btnDelete" WidthRequest="200" Text="Delete" Clicked="BtnDelete_Clicked" />
<Button x:Name="btnRead" WidthRequest="200" Text="Read" Clicked="BtnRead_Clicked" />
</StackLayout>
<ListView x:Name="lstPersons">
<ListView.ItemTemplate>
<DataTemplate>
<TextCell Text="{Binding Name}" Detail="{Binding PersonID}"></TextCell>
</DataTemplate>
</ListView.ItemTemplate>
</ListView>
</StackLayout>
Is there a way to remove the read button and get the ID relative to the pressed line ?
Use the ListView "SelectionChanged" Event :
<ListView SelectionMode="Single"
ItemsSource="{Binding PersonCollection}"
SelectedItem="{Binding SelectedPerson}"
SelectionChanged="ListView_SelectionChanged">
in your code behind :
private void ListView_SelectionChanged(object sender, SelectionChangedEventArgs e)
{
if (e.CurrentSelection.Count != 0)
{
var bc = this.BindingContext as YourViewModelName;
// now you have bc.SelectedPerson and you can access it's properties
// Display what ever you want
collection.SelectedItem = null; // if you want to clear selection
}
}
There are two event will be triggered, "ItemTapped" and "ItemSelected", when user tap an item. The difference between them is that "ItemSelected" will only be triggered when the selection changed. If you want to click on the item to display the item info, "ItemTapped" is a better choice.
XAML:
<ListView ItemsSource="{Binding People}"
SelectionMode="Single"
ItemSelected="ListView_ItemSelected"
ItemTapped="ListView_ItemTapped">
xaml.cs:
private async void ListView_ItemTapped(object sender, ItemTappedEventArgs e)
{
await DisplayAlert("Tapped", "Person Name: " + (e.Item as Person).Name, "OK");
}
private async void ListView_ItemSelected(object sender, SelectedItemChangedEventArgs e)
{
await DisplayAlert("Selected", "Person Name: " + (e.SelectedItem as Person).Name, "OK");
}

Xamarin.Forms - Binding on ContextMenu

I have a list with songs as items. A long press on the element should display a context menu.
AllSongsViewModel.xaml:
<DataTemplate x:Key="SongTemplate">
<ViewCell>
<ViewCell.ContextActions>
<MenuItem Text="Edit" />
<MenuItem Text="Delete"/>
</ViewCell.ContextActions>
<StackLayout Padding="15,5" VerticalOptions="Center">
<Label Text="{Binding Title}"
FontSize="16"/>
<Label Text="{Binding Performer}"
FontSize="12"/>
</StackLayout>
</ViewCell>
</DataTemplate>
This works well, but I need to bind now so that the context menu opens depending on bool IsAdmin, which lies in AllSongsViewModel
AllSongsViewModel.cs:
public bool IsAdmin => _authService.LoggedUser.Role == "Admin";
But I don’t know how to bind this property to the context menu
Unfortunately you can't do this on your ViewModel. But you can set a BindingContextChange event on your View Cell and change it there like this:
XAML:
<DataTemplate x:Key="SongTemplate">
<ViewCell BindingContextChanged="OnBindingContextChanged">
<StackLayout Padding="15,5" VerticalOptions="Center">
<Label Text="{Binding Title}"
FontSize="16"/>
<Label Text="{Binding Performer}"
FontSize="12"/>
</StackLayout>
</ViewCell>
In your code behind:
private void OnBindingContextChanged(object sender, EventArgs e)
{
base.OnBindingContextChanged();
if (BindingContext == null)
return;
ViewCell theViewCell = ((ViewCell)sender);
var viewModel = this.BindingContext.DataContext as AllSongsViewModel;
theViewCell.ContextActions.Clear();
if (viewModel.IsAdmin)
{
theViewCell.ContextActions.Add(new MenuItem()
{
Text = "Delete",
});
theViewCell.ContextActions.Add(new MenuItem()
{
Text = "Edit",
});
}
}

Xamarin.Forms.Xaml.XamlParseException: Position 16:13. No Property of name Cliked found

I'm following a tutorial to make an app that receives and sends data to a web service.
But the time to create a button on the MainPage to bring the registration screen of the Visual Studio this error
Xamarin.Forms.Xaml.XamlParseException:. Position 16:13 In the Property of name Cliked found
and I lost because my this code like the tutorial.
Xaml:
<StackLayout Orientation="Vertical">
<Button Clicked="Btn_Clicked" Text = "test button" />
<ListView ItemsSource="{Binding ContactList}"
HasUnevenRows="True">
<ListView.ItemTemplate>
<DataTemplate>
<ViewCell>
<StackLayout Orientation="Vertical" Padding="12,6">
<Label Text="{Binding Name}" FontSize="24"/>
<Label Text="{Binding Email}" FontSize="24"/>
<Label Text="{Binding City}" FontSize="24"/>
<Label Text="{Binding State}" FontSize="24"/>
<Label Text="{Binding Zip}" FontSize="24"/>
</StackLayout>
</ViewCell>
</DataTemplate>
</ListView.ItemTemplate>
</ListView>
</StackLayout>
Xaml.cs
using System;
using Xamarin.Forms;
namespace ContactManagerApp.Views
{
public partial class MainPage : ContentPage
{
public MainPage()
{
InitializeComponent();
}
private async void Btn_Clicked(object sender, EventArgs e)
{
await Navigation.PushAsync(new NewContactPage());
}
}
}
Clicked is an event not a property so you cannot bind it. You should Bind Command property of Button. You should add a method into page.xaml.cs if you want to use Clicked event.
Xaml:
< Button Clicked="Btn_Clicked" Text = "test button" />
Xaml.cs
private void Btn_Clicked(object sender, EventArgs e)
{
//Do stuff
}

Categories