Search code examples
c#xamarinmauimaui-community-toolkit

Show button only on selected Item of a ListView


I'm creating a Listview in MAUI-Xamarin and I want to show a button to view more details in the selected line. But only in the selected line.

Edit: The question is how to show the button when an item is selected and hide it when it is not.

<ListView x:Name="listView"
    ItemsSource="{Binding Items}"
    SelectedItem="{Binding SelectedItem}">

  <ListView.ItemTemplate>
    <DataTemplate>
      <ViewCell>
        <Grid>
          <Grid.RowDefinitions>
            <RowDefinition Height="44"/>
          </Grid.RowDefinitions>

          <Grid.ColumnDefinitions>
            <ColumnDefinition Width="*" />
            <ColumnDefinition Width="Auto" />
          </Grid.ColumnDefinitions>

          <Label Text="{Binding Name}" Grid.Column="0"/>

          <Button x:Name="btnViewDetails"
            Grid.Column="1"
            Text="View"
            CornerRadius="50"
            IsVisible="{Binding "WHEN THIS LINE IS SELECTED"}}"/>

        </Grid>
      </ViewCell>
    </DataTemplate>
  </ListView.ItemTemplate>
</ListView>

I'v tryied using Converter and DataTrigger but i couldn't manage to pass the selected item as parameter


Solution

  • I share two solutions here. And this is the effect I get,

    enter image description here

    Option 1

    ListView has ItemSelected event. Each time we select an Item, the ListView will invoke this event handler. So we could add some logic in this event handler:

    In xaml, add the ItemSelected event for ListView

    <ListView x:Name="listView"
        ItemsSource="{Binding Items}"
        SelectedItem="{Binding SelectedItem}"
        ItemSelected="listView_ItemSelected">
    

    In code behind then,

         MainPageViewModel viewModel;
         public MainPage()
         {
             InitializeComponent();
             this.BindingContext = viewModel= new MainPageViewModel();
    
         }
    
        ...
        private void listView_ItemSelected(object sender, SelectedItemChangedEventArgs e)
        {
            //here we find the corresponding item we select in the ListView
            foreach(Item item in viewModel.Items) 
            { 
                if(e.SelectedItem == item) 
                { 
                    item.IsVisible = true;
                }
                else
                {
                    item.IsVisible = false; 
                }
            }
        }
    

    Using this way, remember to implement INotifyPropertyChanged for model Item,

    public class Item : INotifyPropertyChanged
    {
    
        private string name;
        public string Name
        {
            get
            {
                return name;
            }
            set
            {
                name = value;
                PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(nameof(Name)));
    
            }
        }
    
        private bool isVisible;
        public bool IsVisible 
        {
            get
            {
                return isVisible;
            }
    
            set
            {
                isVisible = value;
                PropertyChanged?.Invoke(this,new PropertyChangedEventArgs(nameof(IsVisible)));
            }      
        }
    
        public event PropertyChangedEventHandler PropertyChanged;
    }
    

    Option2

    Since you have binded SelectedItem, you could implement the above logic in the Setter of SelectedItem,

        private Item selectedItem;
        public Item SelectedItem
        {
            get
            {
                return selectedItem;
            }
            set
            {
                selectedItem = value;
                foreach (var item in Items) 
                { 
                    if(selectedItem != item) 
                    { 
                        item.IsVisible = false;
                    }
                    else
                    {
                        item.IsVisible = true;
                    }               
                }
            }
        }
    

    You also have to implement INotifyPropertyChanged for model Item.

    If you still have any question, feel free to ask me.

    Hope it helps!