I have a ListView which is bound to some data I have in the viewmodel. In the ListView, each row is a check box and the name of a symptom (e.g. coughing). At the end of the ListView, in the footer, I have a button to submit all of the checkboxes the user has checked.
<ListView x:Name="SymptomsListView" ItemsSource="{Binding SymptomList}" HasUnevenRows="True" SelectionMode="None" Footer="">
<ListView.ItemTemplate>
<DataTemplate>
<ViewCell>
<StackLayout Orientation="Horizontal" Padding="12,0,0,0">
<CheckBox IsChecked="{Binding IsChecked}" Color="ForestGreen" WidthRequest="50" HeightRequest="50" />
<Label Text="{Binding SymptomName}" VerticalOptions="Center" Margin="0,20" FontSize="24" TextColor="Black" />
</StackLayout>
</ViewCell>
</DataTemplate>
</ListView.ItemTemplate>
<ListView.FooterTemplate>
<DataTemplate>
<ContentView>
<StackLayout>
<Button Text="Submit" TextColor="{StaticResource AppTextColor}" FontAttributes="Bold" FontSize="20" WidthRequest="220" HeightRequest="50" Margin="0,15" HorizontalOptions="Center" CornerRadius="10" BackgroundColor="{StaticResource ButtonColor}" Clicked="SubmitClick"/>
</StackLayout>
</ContentView>
</DataTemplate>
</ListView.FooterTemplate>
</ListView>
In the code behind, I want the button press to submit the checked check boxes as a new object per checked item. Format is explained in the commented code -
protected void SubmitClick(object sender, EventArgs e)
{
// Result output per symptom for the user e.g.
// If Breathlessness is checked with severity 4, Cough is checked with severity 8 & PTSD is checked with severity 2
// new AssessmentModel(UserID, Breathlessness, True, 4);
// new AssessmentModel(UserID, Cough, True, 8);
// new AssessmentModel(UserID, PTSD, True, 2);
// CODE HERE
this.Navigation.PopAsync();
}
How would I perform this? From what I can see there is no way to loop over ListView items to find which have been checked. Any help appreciated
Related
Using Xamarin.Forms. I have a ListView containing multiple ViewCells and in each one is a Picker and an Editor. Tapping the Editor fires Editor_Focused, but for some reason also fires Picker_Focused and Picker_Unfocused. I use the Picker_Unfocused event handler to add some data to a SQLite database and then refresh the ListView, so I can't have it firing every time the Editor is tapped. Following along with breakpoints, my refresher method is called twice, because Picker_Unfocused is also called twice for unknown reaons. Also worth noting is that Editor_Completed won't fire no matter what I do.
Things I have tried:
Adding a TapGestureRecognizer to the Editor which would set a property, which would then stop Picker_Unfocused from continuing its execution, but the TapGestureRecognizer never fires when the Editor is tapped.
Assigning a value to a property when Editor_Focused is fired that would do the same as above. Editor_Focused does fire first, but then leaves that property in the "don't fire Picker_Unfocused" state even when the Picker actually needs to be used. Countering that by setting the property back to "do fire" state in Picker_Focused doesn't work, as the order goes Editor_Focused -> Picker_Focused -> Picker_Unfocused -> Refresh list method.
Update: Forgot to include any code.
ListView defined in XAML.
<ListView x:Name="ListView"
HasUnevenRows="True"
SelectionMode="None">
<ListView.ItemTemplate>
<DataTemplate>
<ViewCell>
<StackLayout Orientation="Vertical" HorizontalOptions="FillAndExpand" VerticalOptions="FillAndExpand">
<StackLayout Orientation="Horizontal" HorizontalOptions="FillAndExpand" VerticalOptions="FillAndExpand" Margin="0,5,0,0">
<Label Text="{Binding Prop0}"
TextColor="DodgerBlue"
VerticalOptions="Center"/>
<Label Text="{Binding Prop1}"
TextColor="Black"
HorizontalOptions="StartAndExpand"
VerticalOptions="Center"/>
<Label Text="Task Time:" TextColor="Black" HorizontalOptions="End"
VerticalOptions="Center"/>
<Picker x:Name="Picker" WidthRequest="80"
Title="Enter time"
FontSize="15"
Focused="Picker_Focused"
Unfocused="Picker_Unfocused"
SelectedItem="{Binding Prop2}">
<Picker.ItemsSource>
<x:Array Type="{x:Type x:String}">
<x:String>0.25</x:String>
<x:String>0.50</x:String>
<x:String>0.75</x:String>
<x:String>1.00</x:String>
</x:Array>
</Picker.ItemsSource>
</Picker>
</StackLayout>
<StackLayout Orientation="Horizontal" HorizontalOptions="FillAndExpand" VerticalOptions="FillAndExpand"
IsVisible="{Binding Prop3}">
<Label Text="Comments:" TextColor="Black" VerticalOptions="Center"/>
<Editor x:Name="Editor" Text="{Binding Prop4}" TextColor="Black"
VerticalOptions="Center" HorizontalOptions="StartAndExpand" Focused="Editor_Focused"/>
</StackLayout>
</StackLayout>
<ViewCell.ContextActions>
<MenuItem Text="Delete"
x:Name="DeleteButton"
Clicked="DeleteButton_Clicked"
IsDestructive="True"
CommandParameter="{Binding .}"/>
</ViewCell.ContextActions>
</ViewCell>
</DataTemplate>
</ListView.ItemTemplate>
</ListView>
I am creating xamarin.forms page with a single ListView.
Each list item template consist of one vertical StackLayout which contains 3 StackLayouts inside. The problem is: I can see only first two stacklayouts
and the third is hidden or cut or skipped,i dont know, i cannot see it.
<ContentPage.Content>
<ListView x:Name="RoutesList" ItemsSource="{Binding Routes}">
<ListView.ItemTemplate>
<DataTemplate>
<ViewCell>
<StackLayout BackgroundColor="#eee" Orientation="Vertical" Padding="5,0,0,5" VerticalOptions="FillAndExpand">
<StackLayout Orientation="Horizontal" VerticalOptions="StartAndExpand">
<Label Text="{Binding Name}" FontAttributes="Bold"></Label>
<Label Text="{Binding StartDate}" HorizontalOptions="EndAndExpand"></Label>
</StackLayout>
<StackLayout Orientation="Horizontal" BackgroundColor="#f94" >
<Label Text="{Binding RouteType}" FontAttributes="Bold"></Label>
</StackLayout>
<StackLayout Orientation="Horizontal" VerticalOptions="EndAndExpand">
<Label Text="{Binding CreatorFirstName}" FontAttributes="Bold" HorizontalOptions="EndAndExpand"></Label>
<Label Text="{Binding CreatorLastName}" FontAttributes="Bold" HorizontalOptions="End"></Label>
</StackLayout>
</StackLayout>
</ViewCell>
</DataTemplate>
</ListView.ItemTemplate>
</ListView>
</ContentPage.Content>
How to set layout properties correctly so all stacklayouts and their items contents will fit? All the binding properties are regular strings\dates. I know that there is GridLayout but i wonder how to do this using StackLayouts ?
You need to set the RowHeight property of the ListView to something that will show all items. Alternatively you may set HasUnevenRows to true, but it is a significantly slower option.
Problem:
After following a few examples, one, two, three, I am not able to get my ContextActions to connect to my Code Behind.
This is from the examples. MenuItem_Clicked is not connecting the XAML to the code behind
<ViewCell.ContextActions>
<MenuItem Clicked="MenuItem_Clicked" Text="TEST" Command="{Binding .}"/>
</ViewCell.ContextActions>
Setup:
I am just working with a basic example i found online. it is not a MVVM. I have the ListItems_Refresh action setup and working.
Goal of the Code:
When the users clicks a row, I want to open the default browser and go to the URL from the row.
I would love to know how i can troubleshoot this issue or if i have glaring typo. Thanks in advance
Code:
XAML
<?xml version="1.0" encoding="utf-8" ?>
<ContentPage xmlns="http://xamarin.com/schemas/2014/forms"
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
xmlns:local="clr-namespace:HelloWorld"
x:Class="HelloWorld.MainPage">
<StackLayout Margin="20">
<Label Text="60 Second Sports" FontAttributes="Bold" HorizontalOptions="Center"/>
<ListView x:Name="rssList" IsPullToRefreshEnabled="True" Refreshing="ListItems_Refreshing">
<ListView.ItemTemplate>
<DataTemplate>
<ViewCell>
<ViewCell.ContextActions>
<MenuItem Clicked="MenuItem_Clicked" Text="TEST" Command="{Binding .}"/>
</ViewCell.ContextActions>
<StackLayout>
<Label Text="{Binding Title}" Font="8"/>
<!--<Label Text="{Binding Description}" Font="6"/>-->
<Label Text="{Binding PublishedDate}" Font="5"/>
<Label Text="{Binding Link}" Font="5"/>
</StackLayout>
</ViewCell>
</DataTemplate>
</ListView.ItemTemplate>
</ListView>
</StackLayout>
</ContentPage>
Code Behind
private void MenuItem_Clicked(object sender, EventArgs e)
{
Console.WriteLine("button was clicked");
System.Diagnostics.Process.Start("http://google.com");
}
protected void ListItems_Refreshing(object sender, EventArgs e)
{
Console.WriteLine("refresh triggered");
//doRefresh();
//my method for repopulating the list ImageListView.EndRefresh();
//this is a very important step. It will refresh forever without triggering it }
}
If you want to open a browser when you click on a ListView item, you can just listen to the ItemTapped event.
ItemTapped fires when an item is tapped.
So, in your ListView
<ListView x:Name="rssList" IsPullToRefreshEnabled="True"
ItemTapped="listItemTapped"
Refreshing="ListItems_Refreshing">
<ListView.ItemTemplate>
<DataTemplate>
<ViewCell>
<StackLayout>
<Label Text="{Binding Title}" Font="8"/>
<!--<Label Text="{Binding Description}" Font="6"/>-->
<Label Text="{Binding PublishedDate}" Font="5"/>
<Label Text="{Binding Link}" Font="5"/>
</StackLayout>
</ViewCell>
</DataTemplate>
</ListView.ItemTemplate>
</ListView>
And, the listener method.
public void listItemTapped(object sender, ItemTappedEventArgs e)
{
Console.WriteLine("button was clicked");
var item = (YourModel)e.Item;
}
I'm working on my first Xamarin app. I want to make a listview with grouping and it succeeded. The only problem I have that it won't scroll. My other listview on another page scrolls without a problem, but my listview with grouping won't do that. I tried this both on an Android simulator as on my Android phone (I don't have a macbook or something to test on iOS), and it won't scroll on either of them. I looked it up but a lot of people put the listview in a scrollview, and I didn't do that.
This is my XAML code:
<StackLayout Margin="10" Orientation="Vertical">
<Label Text="{Binding Title}" FontAttributes="Bold"
FontSize="20" HorizontalOptions="CenterAndExpand" />
<Label Text="{Binding Subtitle}" FontAttributes="Italic"
FontSize="15" HorizontalOptions="CenterAndExpand" />
<ListView HasUnevenRows="True" SeparatorColor="Accent"
VerticalOptions="FillAndExpand" IsEnabled="False"
IsGroupingEnabled="True" GroupDisplayBinding="{Binding Key}"
ItemsSource="{Binding ScansGroup}">
<ListView.ItemTemplate>
<DataTemplate>
<ViewCell>
<StackLayout Spacing="4">
<StackLayout Orientation="Horizontal" Margin="10,7,10,1">
<Label Text="{Binding Location, StringFormat='{0}'}"
FontAttributes="Bold" FontSize="16" />
<Label Text="{Binding DateTime, StringFormat='{0:dd/MM/y HH:mm}'}"
HorizontalOptions="EndAndExpand" />
</StackLayout>
<StackLayout Orientation="Horizontal">
<Label Text="{Binding ElapsedTimeOnLocation}"
HorizontalOptions="Start"
Margin="10,0,10,7" />
</StackLayout>
</StackLayout>
</ViewCell>
</DataTemplate>
</ListView.ItemTemplate>
</ListView>
</StackLayout>
I put it in an MVVM structure, and the grouping I did with a MVVM helper that I got from here https://channel9.msdn.com/Shows/XamarinShow/The-Xamarin-Show-12-MVVM-Helpers .
My code behind that is meant for the grouping is the following:
public ObservableRangeCollection<Grouping<string, ScanViewModel>> ScansGroup { get; } =
new ObservableRangeCollection<Grouping<string, ScanViewModel>>();
void Group()
{
var grouped = from scan in Scans
group scan by scan.Day into scanGroup
select new Grouping<string, ScanViewModel>(scanGroup.Key, scanGroup);
ScansGroup.ReplaceRange(grouped);
}
The grouping shows perfectly and the list too. The only problem is that
I can't scroll. Can someone help me?
I've figured it out. There's nothing wrong with your grouping. In your code you set IsEnabled="False" to the ListView. It makes the listview's scroll ability to be handled just if you drag from an enabled item inside the ListView, and even thus, the scroll is like belittled and with a very bad user experience.
Just set your ListView like this:
<ListView HasUnevenRows="True"
SeparatorColor="Accent"
VerticalOptions="FillAndExpand"
IsEnabled="True"
IsGroupingEnabled="True"
GroupDisplayBinding="{Binding Key}"
ItemsSource="{Binding ScansGroup}">
...
</ListView>
I can't tell you if it was designed to be this way, or if it 's a bug, but it is the cause of your issue.
It's probable you have done this to handle some unwanted behavior. If so, let us know what is specifically your intend with this IsEnabled="False", then we'll be able to help you with this.
I hope it helps you.
You didn't add the template for the group. Add this in the <ListView>
<ListView.GroupHeaderTemplate >
<DataTemplate >
<ViewCell Height="28" >
<Label Text="{Binding GroupName}" VerticalTextAlignment="Center" HorizontalOptions="Start" />
</ViewCell>
</DataTemplate>
</ListView.GroupHeaderTemplate>
Also, in the code bend or ViewModel, you need to bind to a group class of the items you want in the list such as:
public class GroupDetails : ObservableCollection<SomeItemsToShow>
{
public string GroupName { get; set; }
}
Check out this Example for more details:
https://xamarinhelp.com/xamarin-forms-listview-grouping/
Hi there, I am currently trying out the idea of a picker inside a listview.
I have assigned a name to said picker but I don't think I can reference this picker from code behind due to all the layers it has on top. Any suggestions on this?
<ListView ItemsSource="{Binding CUSs}" HasUnevenRows="True"
Margin="10,20"
ItemTapped="ListView_ItemTapped"
BackgroundColor="Silver">
<ListView.ItemTemplate>
<DataTemplate>
<ViewCell>
<StackLayout x:Name="ClientLevel" Padding="20">
<Label Text="{Binding .ClientName}"
TextColor="#000" FontSize="Small"/>
<StackLayout x:Name="UnitLevel" Padding="10" IsVisible="{Binding IsVisible}">
here --> <!--<Picker x:Name="SubPicker" Title="{Binding .UnitName}" HorizontalOptions="Start" IsVisible="True"/>-->
</StackLayout>
</StackLayout>
</ViewCell>
</DataTemplate>
</ListView.ItemTemplate>
</ListView>
Once I am able to reference this son-of-a-picker (sorry.Had to xD) I expect the code to work as intended. The user goes down the list and picks a picker for the list ( in this case there is only one of course)