How set the item in ContextActions. In my example I want to set default car.
<ListView.ItemTemplate>
<DataTemplate>
<ViewCell>
<ViewCell.ContextActions>
<MenuItem Text="Ustaw domyslny" Command="{Binding DefultCarCommand}" CommandParameter="{Binding .}"/>
</ViewCell.ContextActions>
<StackLayout>
<Label Text="{Binding RegistrationNumber}" />
<Label Text="{Binding Brand}" />
</StackLayout>
</ViewCell>
</DataTemplate>
</ListView.ItemTemplate>
In ViewModel I use DelegateCommand
public DelegateCommand DefultCarCommand { get; private set; }
Now it does not work and I do not know why
Please note BindingContext of MenuItem is the Single Model that you bind in ItemSource of ListView not the whole ViewModel. You need to use reference binding to bind to ViewModel properties like this:
<ListView x:Name="MyListView">
<ListView.ItemTemplate>
<DataTemplate>
<ViewCell>
<ViewCell.ContextActions>
<MenuItem Text="Ustaw domyslny" Command="{Binding Path=BindingContext.DefultCarCommand, Source={x:Reference Name=MyListView}}" CommandParameter="{Binding .}"/>
</ViewCell.ContextActions>
<StackLayout>
<Label Text="{Binding RegistrationNumber}" />
<Label Text="{Binding Brand}" />
</StackLayout>
</ViewCell>
</DataTemplate>
</ListView.ItemTemplate>
</ListView>
Related
ListView --> ItemSource = { Binding Items } //Works
MenuItem --> Command={ Binding MarkAsCompleted } // is not wokring
This works only when I add path and Source
Command="{Binding Path=BindingContext.MarkAsCompletedCommand, Source={x:Reference TodoViewPage}}"
Why is this happening?!?
<ListView ItemsSource="{Binding Items}" SelectedItem="{Binding SelectedItem}">
<ListView.ItemTemplate>
<DataTemplate>
<ViewCell>
<ViewCell.ContextActions>
<MenuItem Text="Complete" Command="{Binding Path=BindingContext.MarkAsCompletedCommand, Source={x:Reference TodoViewPage}}" CommandParameter="{Binding .}"/>
</ViewCell.ContextActions>
<StackLayout>
<Label Text="{Binding Name}"></Label>
</StackLayout>
</ViewCell>
</DataTemplate>
</ListView.ItemTemplate>
</ListView>
Assuming MyCommand is in MyViewModel in namespace MyViewModels, use Source RelativeSource with AncestorType and x:Type.
Below the Command and CommandParameter Bindings refers to MyViewModel and the item in ListView.ItemsSource, respectively:
xmlns:vm="clr-namespace:MyViewModels"
...
<ListView ItemsSource="{Binding Items}" SelectedItem="{Binding SelectedItem}">
<ListView.ItemTemplate>
<DataTemplate>
<ViewCell>
...
Command="{Binding Source={RelativeSource AncestorType={x:Type vm:MyViewModel}},
Path=MyCommand}"
CommandParameter="{Binding .}"
I'm new to Xamarin. I want to setup a ListView in Xamarin plus 2 buttons to check/uncheck every CheckBox inside the ListView to utilize the checked ones afterwards. Could you please tell me how to access these Checkboxes with kind of a foreach loop?
<ListView x:Name="countryListView" HasUnevenRows="true" ItemTapped="Handle_ItemTapped">
<ListView.ItemTemplate>
<DataTemplate>
<ViewCell>
<ViewCell.ContextActions>
<MenuItem Text="Bla" CommandParameter="{Binding .}" />
<MenuItem Text="Delete" IsDestructive="true" CommandParameter="{Binding .}" Clicked="deleteCountry" />
</ViewCell.ContextActions>
<StackLayout Orientation="Horizontal" Padding="5">
<controls:CircleImage HeightRequest="30" WidthRequest="30" Aspect="AspectFill" Source="{Binding imageURL}" VerticalOptions="Center" HorizontalOptions="Center" />
<!--<Image Source="{Binding imageURL}" />-->
<StackLayout HorizontalOptions="StartAndExpand">
<Label Text="{Binding name}" />
<Label Text="{Binding capital}" />
</StackLayout>
<CheckBox x:Name="checkbox" IsChecked="false" />
</StackLayout>
</ViewCell>
</DataTemplate>
</ListView.ItemTemplate>
</ListView>
Thanks,
Thomas
Bind the IsChecked property of your checkbox to bool in your ViewModel and in OnClick event make it true or false. Don't forget to implement INotifyPropertyChanged to refresh your UI.
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!
I don't know why, but when I tap any ListView item, the Button inside it's template loses the background color.
I use default ViewCell inside ListView. Is this a Xamarin.Forms bug?
I have this problem only on iOS.
<ListView x:Name="lv" Grid.Row="2" HasUnevenRows="true" BackgroundColor="White" ItemTapped="OnItemTapped">
<ListView.ItemTemplate>
<DataTemplate>
<ViewCell>
<StackLayout Padding="16" HorizontalOptions="FillAndExpand" VerticalOptions="FillAndExpand" BackgroundColor="{Binding .,Converter={StaticResource IndexColorConverter}">
<StackLayout VerticalOptions="Center">
<Label Text="{Binding Auditorium}" FontSize="18" TextColor="Black"/>
<ContentView Padding="0,-5,0,0">
<Label Text="{Binding Title}" FontSize="16" TextColor="Black"/>
</ContentView>
<StackLayout Orientation="Horizontal">
<Button WidthRequest="100" Text="{Binding ButtonOverviewText}" TextColor="White" BackgroundColor="{Binding ButtonColor}" CommandParameter="{Binding .}" Clicked="Handle_Clicked"/>
<Button WidthRequest="100" Text="{Binding ButtonOverviewText}" TextColor="White" BackgroundColor="{Binding ButtonColor}" CommandParameter="{Binding .}" Clicked="Handle_Clicked" />
</StackLayout>
</StackLayout>
<Label Text="{Binding Coordinator}" FontSize="14" TextColor="Gray"/>
</StackLayout>
</ViewCell>
</DataTemplate>
</ListView.ItemTemplate>
</ListView>
There was an old issue that I filed fora similar bug: https://bugzilla.xamarin.com/show_bug.cgi?id=27502.
However, the specific scenario you mention is expected behavior on iOS and happens in native (non-Xamarin.Forms) projects too. See the comment here. You might consider disabling the UITableViewCellSelectionStyle of your cells with UITableViewCellSelectionStyle.None. Here is an example of a cell renderer. You can set the cell.SelectionStyle here. This would stop the gray highlight of the cell. If you don't want that it could be a workaround to keep your button colors.
My workaround for this problem is the following.
<Grid>
<BoxView BackgroundColor="{Binding ButtonColor}"/>
<Button Text="{Binding ButtonOverviewText}" TextColor="White" BackgroundColor="Transparent" CommandParameter="{Binding .}" Clicked="Handle_Clicked"/>
</Grid>
I would like to add a command to my listview. When an item is clicked I would like to execute my relayCommand.
Now I have these solution, it works, but I think it is not so MVVM :)
<ListView ItemsSource="{Binding Taxons}" IsItemClickEnabled="True" ItemClick="ListViewBase_OnItemClick">
<ListView.ItemTemplate>
<DataTemplate>
<TextBlock Text="{Binding Name}"/>
</DataTemplate>
</ListView.ItemTemplate>
</ListView>
Code Behind:
private void ListViewBase_OnItemClick(object sender, ItemClickEventArgs e)
{
viewModel.TreeItemSelected.Execute(((Taxon)e.ClickedItem).Name);
}
I would like to use this way without any code behind, but it is not possible as the VS tells me:
<ListView ItemsSource="{Binding Taxons}" IsItemClickEnabled="True" ItemClick="{Binding TreeItemSelected}">
<ListView.ItemTemplate>
<DataTemplate>
<TextBlock Text="{Binding Name}"/>
</DataTemplate>
</ListView.ItemTemplate>
</ListView>
I use the following extra dll-s, but i dont want to install anything else if it possible.
GalaSoft.MvvmLight.Extras.Win8
GalaSoft.MvvmLight.Win8
Can you suggest a solution to me?
Here's a working example :
<ListBox x:Name="name_here"
ItemsSource="{Binding your_item_source}"
SelectedItem="{Binding your_selected_item, UpdateSourceTrigger=PropertyChanged}"
...
>
<i:Interaction.Triggers>
<i:EventTrigger EventName="MouseDoubleClick">
<Command:EventToCommand Command="{Binding your_command_here}"
CommandParameter="{Binding ElementName=name_here, Path=SelectedItem}" />
</i:EventTrigger>
</i:Interaction.Triggers>
</ListBox>
It make use of Blend's Interaction triggers (you don't have to install blend, the dll is enough if you don't have it).
also, if you're using the CommandParameter, bind the ElementName to the name of the control (in this example it's name_here )
For those who have the same problem, I would like to say that there is another way:
You can define a TapGestureRecognizer for the ListView items and bind it to a command in your ViewModel, as I'm showing here :
<StackLayout x:Name="StackLayout1" Orientation="Vertical" HorizontalOptions="StartAndExpand" VerticalOptions="FillAndExpand">
<StackLayout.BindingContext>
<viewModels:NotificationsViewModel />
</StackLayout.BindingContext>
<ListView ItemsSource="{Binding NotificationsList}">
<ListView.ItemTemplate>
<DataTemplate>
<ViewCell>
<StackLayout Orientation="Vertical">
<StackLayout.GestureRecognizers> <!-- here you bind the TAP event to your ViewModel -->
<TapGestureRecognizer Command="{Binding Path=BindingContext.OnListItemTapped, Source={x:Reference StackLayout1}}"
CommandParameter="{Binding}"/>
</StackLayout.GestureRecognizers>
<RelativeLayout HorizontalOptions="FillAndExpand" VerticalOptions="FillAndExpand">
<Image x:Name="IsReadImage" StyleId="IsReadImage" WidthRequest="{StaticResource OptionImageSize}"
Source='{Binding IsRead, Converter={StaticResource BooleanToValueConverter}, ConverterParameter="Resources.emailOpenIcon,Resources.emailIcon"}'
RelativeLayout.YConstraint="{ConstraintExpression Type=Constant, Constant=0}"
RelativeLayout.HeightConstraint="{ConstraintExpression Type=RelativeToParent, Property=Height, Factor=0.8, Constant=0}"></Image>
<Label Text="{Binding Title}" x:Name="TitleLabel" HorizontalTextAlignment="Start" FontAttributes='{Binding IsRead, Converter={StaticResource BooleanToValueConverter}, ConverterParameter="Bold?!"}'
RelativeLayout.XConstraint="{ConstraintExpression Type=RelativeToView, ElementName=IsReadImage, Property=Width, Constant=5}"
RelativeLayout.YConstraint="{ConstraintExpression Type=RelativeToView, ElementName=IsReadImage, Property=Y, Constant=3}" /></RelativeLayout>
</StackLayout>
</ViewCell>
</DataTemplate>
</ListView.ItemTemplate>
</ListView>
</StackLayout>
And then you can define your command in the page's ViewModel
public ICommand OnListItemTapped
{
get
{
return new Command<Notification>(item =>
{
Debug.WriteLine(item.Title + " Cliked!");
});
}
}
You can accomplish this two ways.
One would be to bind the list views SelectedItem to a property on your viewmodel. (maybe call that property SelectedTaxon), then in the property setter you could take whatever action you wish on the viewmodel.
The other way, if you are really tied to executing a command on your viewmodel. You can use the mvvmlight EventToCommand behavior.
You can find info about that via Google or at this link is a description of its use. http://adammills.wordpress.com/2011/02/14/eventtocommand-action-mvvm-glue/
I believe that you already have that behavior as part of the mvvmlight extras dll you have.