locked
Binding Command for Button inside a ListView and Toggled Action from Switch inside ListView RRS feed

  • Question

  • User245874 posted

    Hi everyone,

    I'm trying to add a command to a button inside a listview in a MVVM architecture, but i'm not being so succeed. Also i'm trying to attach an action to when the switch is toggled, but i have no idea how to do that (and i know that i can put an method inside the SET property in the MODEL, but i want to call an method from the view model). The data from the notification model (Time, Legend, Activated and AlarmStatus) is appearing on the screen and the button outside the listview is working as well... See bellow my code until now:

    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"
                 x:Class="AppTest.Views.NotifyManager">
      <ContentPage.Content>
        <StackLayout Padding="25">
          <Button Text="Add" Command="{Binding AddNotify} />
          <ListView ItemsSource="{Binding Notifications}" HasUnevenRows="True" SelectedItem="{Binding notifSelected}">
            <ListView.ItemTemplate>
              <DataTemplate>
                <ViewCell>
                  <ViewCell.View>
                    <StackLayout>
                      <Label Text="{Binding Time}" FontSize="20"/>
                      <Label Text="{Binding Legend}" FontSize="15"/>
                      <Switch IsToggled="{Binding Activated}" />
                      <Label Text="{Binding AlarmStatus}" FontSize="15"/>
                      <Button Text="Remove" Command="{Binding ???}"/>
                    </StackLayout>
                  </ViewCell.View>
                </ViewCell>
              </DataTemplate>
            </ListView.ItemTemplate>
          </ListView>
        </StackLayout>
      </ContentPage.Content>
    </ContentPage>
    

    and the view model:

    namespace AppTest.ViewModel
    {
        class NotifyManagerViewModel
        {
            SaveNotification sn;
            public ObservableCollection<Notification> Notifications { get; set; }
            private NotificationDAO dao;
            public ICommand AddNotify { get; protected set; }
            public INavigation Navigation { get; set; }
    
            private Notification notifSelected;
            public Notification notifSelected
            {
                get
                {
                    return notifSelected;
                }
                set
                {
                    if(notifSelected != value)
                    {
                        notifSelected = value;
                    }
                }
            }
    
            public NotifyManagerViewModel(NotificationDAO notDao)
            {
                dao = notDao;
                Notifications = dao.Notifications;
    
                AddNotify = new Command(() => 
                {
                    sn = new SaveNotification(dao);
                    Navigation.PushAsync(sn);
                });
            }
    
        }
    }
    

    Thanks :)

    Friday, September 16, 2016 2:04 AM

All replies

  • User76049 posted

    You can use relative source binding to achieve this

    <?xml version="1.0" encoding="utf-8" ?> <ContentPage xmlns="http://xamarin.com/schemas/2014/forms" xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml" x:Name="MyNotifyPage" x:Class="AppTest.Views.NotifyManager"> <ContentPage.Content> <StackLayout Padding="25"> <Button Text="Add" Command="{Binding AddNotify} /> <ListView ItemsSource="{Binding Notifications}" HasUnevenRows="True" SelectedItem="{Binding notifSelected}"> <ListView.ItemTemplate> <DataTemplate> <ViewCell> <ViewCell.View> <StackLayout> <Label Text="{Binding Time}" FontSize="20"/> <Label Text="{Binding Legend}" FontSize="15"/> <Switch IsToggled="{Binding Activated}" /> <Label Text="{Binding AlarmStatus}" FontSize="15"/> <Button Text="Remove" Command="{Binding Source={x:Reference MyNotifyPage}, Path=BindingContext.AddNotify}"/> </StackLayout> </ViewCell.View> </ViewCell> </DataTemplate> </ListView.ItemTemplate> </ListView> </StackLayout> </ContentPage.Content> </ContentPage>

    Remember to give your page a name

    x:Name="MyNotifyPage"

    Friday, September 16, 2016 8:03 AM
  • User240159 posted

    @AlexRod you can also look at this - https://forums.xamarin.com/discussion/73470/detecting-tap-on-label-inside-viewcell-inside-listview

    Friday, September 16, 2016 8:57 AM
  • User245874 posted

    Thank you very much @NMackay and @NamyslawSzymaniuk for the help!!! I could put the two answers together and solved the button issue :smiley: ... Now i'm trying to figure out how to solve the switch issue

    Friday, September 16, 2016 8:06 PM
  • User349936 posted

    Hi Alex, Please let me know if you were able to find solution for the Switch issue. Please share your findings ... I have a similar issue where I need to capture the Switch actions for Switch buttons ( mote than 20) and remember them and load the state when application is invoked next time.... Thanks, MKJ

    Friday, December 15, 2017 5:43 PM
  • User364459 posted

    @NMackay I am trying to use the solution given by you and here is my code

    XAML

    <ContentPage.BindingContext>
        <vm:AddTaskVM />
    </ContentPage.BindingContext>
    <StackLayout Orientation="Vertical">
        <Button Command="{Binding ShowTask}" Text="Show" />
        <!--<Button Command="{Binding ShowTask}" Text="Show" />-->
    
        <ListView ItemsSource="{Binding TaskItems,Mode=TwoWay}"
              CachingStrategy="RecycleElement"
              RowHeight="60" x:Name="ListTTasks">
    
            <ListView.ItemTemplate>
                <DataTemplate>
                    <ViewCell>
                        <StackLayout Margin="8">
                            <Grid x:Name="GridTasks">
                                <Grid.ColumnDefinitions>
                                    <ColumnDefinition Width="1*" />
                                    <ColumnDefinition Width="1*" />
                                </Grid.ColumnDefinitions>
    
    
                                <Label Text="{Binding Tasktext}"
                               FontAttributes="Bold" Grid.Column="0" />
    
                                <Button Text="Remove" Command="{Binding Source={x:Reference ShowTasksPage}, Path=BindingContext.DelCommand}"/>
                            </Grid>
                        </StackLayout>
    
                    </ViewCell>
                </DataTemplate>
            </ListView.ItemTemplate>
    
        </ListView>
    
    </StackLayout>
    

    ViewModel

     public ICommand DelCommand { get; set; }
        public AddTaskVM()
        {         
    
            DelCommand = new Command((q) => this.DelTaskMethod(q), (q) => this.CanShowTaskMethod(q));
    
        }
    
    public void DelTaskMethod(object parameter)
        {
    
        }
        public bool CanDelTaskMethod(object parameter)
        {
    
            return true;
        }
    

    not sure why its not working.. any help will be greatly appreciated

    Tuesday, January 16, 2018 3:39 AM
  • User76049 posted

    If you attach a small repo I can take a look at this tonight or if I have a few minutes at lunch.

    Tuesday, January 16, 2018 9:38 AM
  • User382562 posted

    Thank you @NMackay your solution worked for me.

    Wednesday, January 1, 2020 8:27 PM
  • User355323 posted

    Hi @NMackay and @NamyslawSzymaniuk your solution is working but it returns all values of the page and i need the value of current object of listview

    thanks.

    Wednesday, May 27, 2020 10:06 AM
  • User355323 posted

    Its working as i need when i set the command parameter ={"Binding ."}

    Thanks

    Wednesday, May 27, 2020 12:18 PM