2
votes

I have ListView using custom template. How do I highlight selected item or tabbed item without using code-behind ?

View

<StackLayout
  Grid.Row="1"
  BackgroundColor="#21576C"
  HorizontalOptions="StartAndExpand"
  VerticalOptions="StartAndExpand">
  <StackLayout
    BackgroundColor="#134359"
    Margin="5,5,5,5">
    <ListView x:Name="Catagoris"
              HorizontalOptions="Start"
              VerticalOptions="FillAndExpand"
              BackgroundColor="Transparent"
              HasUnevenRows="True"
              ItemsSource="{Binding CatagoryType}"
              ItemSelected="ListView_OnItemSelected"
              MinimumHeightRequest="100"
              SeparatorVisibility="None"
        >
      <ListView.ItemTemplate>
        <DataTemplate>
          <ViewCell>
            <Label x:Name="ListViewLabel"
                   HorizontalOptions="FillAndExpand"
                   HorizontalTextAlignment="Center"
                   VerticalOptions="FillAndExpand"
                   VerticalTextAlignment="Center"
                   TextColor="#3C9DC5"
                   Text="{Binding ., Converter={StaticResource SpaceOnUpperAndStringToUpperCaseConverter}}"
                   HeightRequest="50">
            </Label>
          </ViewCell>
        </DataTemplate>
      </ListView.ItemTemplate>
    </ListView>
  </StackLayout>
</StackLayout>

Prop in VM

public bool IsCatagorySelected
        {
            get { return _isCatagorySelected; }
            set
            {
                if (_isCatagorySelected != value)
                {
                    OnPropertyChanging(()=>IsCatagorySelected);
                    _isCatagorySelected = value;
                    OnPropertyChanged(() => IsCatagorySelected);
                }
            }
        }

Code behind

private void ListView_OnItemSelected(object sender, SelectedItemChangedEventArgs e)
{
    MyViewModel myViewModel= sender as  MyViewModel;
    if (e.SelectedItem == null)
    {
        return; 
    }
    myViewModel.IsCatagorySelected= true; 
    DisplayAlert("Item Selected", e.SelectedItem.ToString(), "OK");
}

I need to change the background color and text color of Label 'ListviewLabel'.

1
Try in Xamarin.Forms its not that simple.Santosh Thapa
Have you take a look to DataTrigger? blog.xamarin.com/triggers-in-xamarin-formsAlessandro Caliaro
Thanks for your suggestion Caliaro. Problem here is, I am using DataTemplate type of Label in a ViewCell. Label doesn't have IsSelected property. So trigger is not helpful here to change the BackgroundColor and TextColor of label when an item is selected.Santosh Thapa
Ok, but your listview has a SelectedItem. When you have a SelectedItem you can set a IsSelected property (that you have in your model).. post your model and your xamlAlessandro Caliaro
@AlessandroCaliaro I have update my post per your request.Santosh Thapa

1 Answers

3
votes

I suggest to take a look to this Blog

you should add to your Model a "Selected" property

public bool Selected { get; set; }

In your ViewModel you should have a property that define the SelectedItem in your ListView

MyModel _selectedItem { get; set; }

and use it in this way

public MyModel SelectedItem
 {
    get { return _selectedItem; }
    set
    {
        if (_selectedItem != null)
            _selectedItem.Selected = false;

        _selectedItem = value;

        if (_selectedItem != null)
            _selectedItem.Selected = true;
    }
 }

then in your XAML you have to bind the ListView's SelectedItem and the TextColor property

    <ListView SelectedItem="{Binding SelectedItem}" ItemsSource="{Binding List}">
    <ListView.ItemTemplate>
        <DataTemplate>
            <ViewCell>
                <Label Text="{Binding Name}" TextColor="{Binding Selected, Converter={StaticResource cnvInvert}}}" FontSize="18"></Label>
            </ViewCell>
        </DataTemplate>
    </ListView.ItemTemplate>

The TextColor property has an IValueConverter that converter the Selected property to a Color property

public class SelectedToColorConverter : IValueConverter
 {

    #region IValueConverter implementation

    public object Convert(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
    {
        if (value is bool)
        {
            if ((Boolean)value)
                return Color.Orange;
            else
                return Color.Black;
        }
        return Color.Black;
    }

    public object ConvertBack(object value, Type targetType, object parameter,    System.Globalization.CultureInfo culture)
    {
        throw new NotImplementedException();
    }

    #endregion
 }

in the Blog there is a link to a REPO on GitHub