How to keep item selected in xamarin forms?

sagarsagar Member ✭✭
edited April 12 in Xamarin.Forms

Hi am using LIstView, when I tap on the item background of that item will be default some color will set. If I click on another item then both items background will be set. What I need to do when I click on second item first Item should not be selected, only clicked item should be active. How to do it?

Find below for xaml file code
<ListView ItemsSource="{Binding MainMenues}" SeparatorVisibility="None" HasUnevenRows="true"  SelectionMode="Single">
            <ListView.ItemTemplate>
                <DataTemplate>
                    <ViewCell>
                        <StackLayout Orientation="Vertical">
                            <Grid Padding="15">
                                <Label Text="{Binding MainMenuTitle}"  FontSize="16" VerticalOptions="Center" HorizontalOptions="Start"/>
                                <Image x:Name="im" Source="{Binding ArrowIconSource}" IsVisible="{Binding IsSubmenu}" HeightRequest="15" WidthRequest="15" VerticalOptions="Center" 
                                           HorizontalOptions="End">
                                </Image>
                                <Grid.GestureRecognizers>
                                    <TapGestureRecognizer 
                                                Tapped="Handle_Tapped"
                                                NumberOfTapsRequired="1" />
                                </Grid.GestureRecognizers>
                            </Grid>
                            <Grid IsVisible="{Binding IsChildrenVisible}" HeightRequest="{Binding ChildrenRowHeightRequest}">
                                <ListView ItemsSource="{Binding Submenues}" SelectionMode="Single" ItemTapped="ListView_ItemTapped" SeparatorVisibility="None" SelectionMode="Single" HasUnevenRows="false">
                                    <ListView.ItemTemplate>
                                        <DataTemplate>
                                            <ViewCell>
                                                <Grid Padding="10">
                                                    <Label Text="{Binding SubMenuTitle}"  VerticalOptions="Center" HorizontalOptions="Start" />
                                                    <Image IsVisible="False" Source="rightarrow.png" HeightRequest="12" WidthRequest="12" VerticalOptions="Center" 
                                                                HorizontalOptions="End"/>
                                                </Grid>
                                            </ViewCell>
                                        </DataTemplate>
                                    </ListView.ItemTemplate>
                                </ListView>
                            </Grid>
                        </StackLayout>
                    </ViewCell>
                </DataTemplate>
            </ListView.ItemTemplate>
        </ListView>

C# Code
 async void Handle_Tapped(object sender, EventArgs e)
        {
            try
            {
                Grid g = sender as Grid;
                Image im = g.Children[1] as Image;
                await im.RotateTo(180);
                Label label = g.Children[0] as Label;
                g.BackgroundColor = Color.Red;

                viewModel.ShowCities(label.Text);
            }
            catch (Exception ex)
            {
                throw;
            }
        }

        private async void ListView_ItemTapped(object sender, ItemTappedEventArgs e)
        {
            try
            {
                var s = e.Group as SubMenu;
                switch (s.SubMenuTitle.ToLower())
                {
                    case "mobile":
                        await RootPage.NavigateFromMenu(5);
                        break;
                    case "sub menu":
                        await RootPage.NavigateFromMenu(4);
                        break;
                }   
            }
            catch (Exception ex)
            {

            }
            ((ListView)sender).SelectedItem = null;
        }

In both, I need to select only one listview at a time.

Answers

  • abhishabdabhishabd USMember ✭✭

    Hello Sagar, Default property is listview_ItemSeleted you can select one at one time if you select antoher item in list view first will be deselect automatically.

    ListView.ItemSelected += (object sender, SelectedItemChangedEventArgs e) =>
    {
    var item = (Item) e.SelectedItem;

    // now you can reference item.Name, item.Location, etc
    

    };

  • chetanrawatchetanrawat USMember ✭✭✭

    Hi, @sagar
    Try this code

    private async void ListViewItemSelected(object sender, SelectedItemChangedEventArgs e)
    {

                    if ((sender != null && ListView.SelectedItem != null))
                    {
                        // put your Code here..
                    }
                   ListView.SelectedItem = null;
            }
    
  • abhishabdabhishabd USMember ✭✭

    If you want more information you can check my blog.
    https://xmonkeys360.com/2019/03/26/xamarin-forms-listview-with-checkbox/

  • yogeshwaranmohanyogeshwaranmohan Member ✭✭

    Set SelectionMode="Single" to your ListView

  • sagarsagar Member ✭✭
    edited April 12

    @abhishabd and @chetanrawat , Thank for your reply I will let you know once I implement.

  • sagarsagar Member ✭✭

    @yogeshwaranmohan , It's already set to SelectionMode="Single"

  • chetanrawatchetanrawat USMember ✭✭✭
    edited April 12
    Grid g= null;
    
        async void Handle_Tapped(object sender, EventArgs e)
                {
                    try
                    {
                if(g !=null)
                {
                  g.BackgroundColor = Color.White;
                }
             else
             {
                 g = sender as Grid;
                     Image im = g.Children[1] as Image;
                     await im.RotateTo(180);
                     Label label = g.Children[0] as Label;
                     g.BackgroundColor = Color.Red;
                     viewModel.ShowCities(label.Text);
                } 
    
                }
                    }
                    catch (Exception ex)
                    {
                        throw;
                    }
                }
    
  • sagarsagar Member ✭✭

    @chetanrawat, When I declare Grid g outside the function it is never going inside the if(g !=null) condition.

  • Sumit_SharmaSumit_Sharma USMember ✭✭✭

    Tell me one thing, you want to change background color of list item on Grid Click or ListView item selection ?

  • chetanrawatchetanrawat USMember ✭✭✭

    call Grid
    Grid g= new Grid();

  • sagarsagar Member ✭✭

    @chetanrawat, Now it is going inside in if condition every time

  • yogeshwaranmohanyogeshwaranmohan Member ✭✭

    Please attach screenshot of your issue. That will more helpful

  • sagarsagar Member ✭✭

    @Sumit_Sharma, I want to be set the background color for listview, since grid in the inside listview, if we can change color of it no problem. The user should understand which item he tapped.

  • sagarsagar Member ✭✭
    edited April 12

    @yogeshwaranmohan, when i declare Grid g = new Grid(); It will never go insde else condtion see below

  • chetanrawatchetanrawat USMember ✭✭✭
    edited April 12

    Hi @Sagar i just gave you the idea i have not tested my code

    try this plz

    async void Handle_Tapped(object sender, EventArgs e)
    {
        try
        {
            if (g != null)
            {
                g.BackgroundColor = Color.White;
            }
    
                g = sender as Grid;
                Image im = g.Children[1] as Image;
                await im.RotateTo(180);
                Label label = g.Children[0] as Label;
                g.BackgroundColor = Color.Red;
                viewModel.ShowCities(label.Text);
        }
        catch (Exception ex)
         {
              throw;
           }
     }
    
  • yogeshwaranmohanyogeshwaranmohan Member ✭✭

    No, show the andoid mobile app UI issue screenshot, not your code screenshot

  • sagarsagar Member ✭✭

    @yogeshwaranmohan
    First menus will bind like below

    After clicking on the menu it will be like below

    My requirement user should know on which item currently he clicked.

  • yogeshwaranmohanyogeshwaranmohan Member ✭✭

    Create both list for selected item property. When user click the main list item then, check the sub list has selected item value, if sub list has selected item then set the value as null. Same as if sub list item is selected then check the main list selected item property has value. So you don't change the grid background color. Instead of changing the grid background color, set the list selected item it will change the background.

  • yogeshwaranmohanyogeshwaranmohan Member ✭✭
    edited April 12

    Do like this,

    <ListView ItemsSource="{Binding MainMenues}" SelectedItem="{Binding MainMenuSelectedItem, Mode=TwoWay}" SeparatorVisibility="None" HasUnevenRows="true"  SelectionMode="Single">
        <ListView.ItemTemplate>
            <DataTemplate>
                <ViewCell>
                    <StackLayout Orientation="Vertical">
                        <Grid Padding="15">
                            <Label Text="{Binding MainMenuTitle}"  FontSize="16" VerticalOptions="Center" HorizontalOptions="Start"/>
                            <Image x:Name="im" Source="{Binding ArrowIconSource}" IsVisible="{Binding IsSubmenu}" HeightRequest="15" WidthRequest="15" VerticalOptions="Center" 
                                               HorizontalOptions="End">
                            </Image>
                            <Grid.GestureRecognizers>
                                <TapGestureRecognizer 
                                                    Tapped="Handle_Tapped"
                                                    NumberOfTapsRequired="1" />
                            </Grid.GestureRecognizers>
                        </Grid>
                        <Grid IsVisible="{Binding IsChildrenVisible}" HeightRequest="{Binding ChildrenRowHeightRequest}">
                            <ListView ItemsSource="{Binding Submenues}" SelectedItem="{Binding SubMenuSelectedItem, Mode=TwoWay}" SelectionMode="Single" ItemTapped="ListView_ItemTapped" SeparatorVisibility="None" HasUnevenRows="false">
                                <ListView.ItemTemplate>
                                    <DataTemplate>
                                        <ViewCell>
                                            <Grid Padding="10">
                                                <Label Text="{Binding SubMenuTitle}"  VerticalOptions="Center" HorizontalOptions="Start" />
                                                <Image IsVisible="False" Source="rightarrow.png" HeightRequest="12" WidthRequest="12" VerticalOptions="Center" 
                                                                    HorizontalOptions="End"/>
                                            </Grid>
                                        </ViewCell>
                                    </DataTemplate>
                                </ListView.ItemTemplate>
                            </ListView>
                        </Grid>
                    </StackLayout>
                </ViewCell>
            </DataTemplate>
        </ListView.ItemTemplate>
    </ListView>
    

    Code behind

    private {MainMenuModel} mainMenuSelectedItem;
    
            public {MainMenuModel} MainMenuSelectedItem
            {
                get { return mainMenuSelectedItem; }
                set { mainMenuSelectedItem = value; }
            }
    
            private {SubMenuModel} subMenuSelectedItem;
    
            public {SubMenuModel} subMenuSelectedItem
            {
                get { return subMenuSelectedItem; }
                set { subMenuSelectedItem = value; }
            }
    
      async void Handle_Tapped(object sender, EventArgs e)
            {
                try
                {
                    if (SubMenuSelectedItem != null)
                        SubMenuSelectedItem = null;
    
                    Grid g = sender as Grid;
                    Image im = g.Children[1] as Image;
                    await im.RotateTo(180);
                    Label label = g.Children[0] as Label;                
    
                    viewModel.ShowCities(label.Text);
                }
                catch (Exception ex)
                {
                    throw;
                }
            }
    
    private async void ListView_ItemTapped(object sender, ItemTappedEventArgs e)
            {
                try
                {
                    if (MainMenuSelectedItem != null)
                        MainMenuSelectedItem = null;
    
                    var s = e.Group as SubMenu;
                    switch (s.SubMenuTitle.ToLower())
                    {
                        case "mobile":
                            await RootPage.NavigateFromMenu(5);
                            break;
                        case "sub menu":
                            await RootPage.NavigateFromMenu(4);
                            break;
                    }
                }
                catch (Exception ex)
                {
    
                }
                ((ListView)sender).SelectedItem = null;
            }
    

    When grid is tabbed the, set the grid item to MainMenuSelectedItem, so the list item background will be change. MainMenuSelectedItem means main list items "SelectedItem".

  • sagarsagar Member ✭✭

    @yogeshwaranmohan said:
    Do like this,

    <ListView ItemsSource="{Binding MainMenues}" SelectedItem="{Binding MainMenuSelectedItem, Mode=TwoWay}" SeparatorVisibility="None" HasUnevenRows="true"  SelectionMode="Single">
        <ListView.ItemTemplate>
            <DataTemplate>
                <ViewCell>
                    <StackLayout Orientation="Vertical">
                        <Grid Padding="15">
                            <Label Text="{Binding MainMenuTitle}"  FontSize="16" VerticalOptions="Center" HorizontalOptions="Start"/>
                            <Image x:Name="im" Source="{Binding ArrowIconSource}" IsVisible="{Binding IsSubmenu}" HeightRequest="15" WidthRequest="15" VerticalOptions="Center" 
                                               HorizontalOptions="End">
                            </Image>
                            <Grid.GestureRecognizers>
                                <TapGestureRecognizer 
                                                    Tapped="Handle_Tapped"
                                                    NumberOfTapsRequired="1" />
                            </Grid.GestureRecognizers>
                        </Grid>
                        <Grid IsVisible="{Binding IsChildrenVisible}" HeightRequest="{Binding ChildrenRowHeightRequest}">
                            <ListView ItemsSource="{Binding Submenues}" SelectedItem="{Binding SubMenuSelectedItem, Mode=TwoWay}" SelectionMode="Single" ItemTapped="ListView_ItemTapped" SeparatorVisibility="None" HasUnevenRows="false">
                                <ListView.ItemTemplate>
                                    <DataTemplate>
                                        <ViewCell>
                                            <Grid Padding="10">
                                                <Label Text="{Binding SubMenuTitle}"  VerticalOptions="Center" HorizontalOptions="Start" />
                                                <Image IsVisible="False" Source="rightarrow.png" HeightRequest="12" WidthRequest="12" VerticalOptions="Center" 
                                                                    HorizontalOptions="End"/>
                                            </Grid>
                                        </ViewCell>
                                    </DataTemplate>
                                </ListView.ItemTemplate>
                            </ListView>
                        </Grid>
                    </StackLayout>
                </ViewCell>
            </DataTemplate>
        </ListView.ItemTemplate>
    </ListView>
    

    Code behind

      async void Handle_Tapped(object sender, EventArgs e)
            {
                try
                {
                    if (SubMenuSelectedItem != null)
                        SubMenuSelectedItem = null;
    
                    Grid g = sender as Grid;
                    Image im = g.Children[1] as Image;
                    await im.RotateTo(180);
                    Label label = g.Children[0] as Label;                
    
                    viewModel.ShowCities(label.Text);
                }
                catch (Exception ex)
                {
                    throw;
                }
            }
    
    private async void ListView_ItemTapped(object sender, ItemTappedEventArgs e)
            {
                try
                {
                    if (MainMenuSelectedItem != null)
                        MainMenuSelectedItem = null;
    
                    var s = e.Group as SubMenu;
                    switch (s.SubMenuTitle.ToLower())
                    {
                        case "mobile":
                            await RootPage.NavigateFromMenu(5);
                            break;
                        case "sub menu":
                            await RootPage.NavigateFromMenu(4);
                            break;
                    }
                }
                catch (Exception ex)
                {
    
                }
                ((ListView)sender).SelectedItem = null;
            }
    

    When grid is tabbed the, set the grid item to MainMenuSelectedItem, so the list item background will be change.

    Please Don't mind how you declared the following two variables?
    SubMenuSelectedItem
    MainMenuSelectedItem

  • yogeshwaranmohanyogeshwaranmohan Member ✭✭

    Check my updated code

Sign In or Register to comment.