简体   繁体   中英

Bold label for selected item in ListView?

I have the following 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" 
    xmlns:local="clr-namespace:StyleLabelInViewCell" x:Class="StyleLabelInViewCell.MainPage">

    <ContentPage.Resources>
        <ResourceDictionary>
            <local:MainVM x:Key="MainVm" />
            <local:IsSelectedToStyle x:Key="IsSelectedToStyle" />
            <Style x:Key="SelectedStyle" TargetType="Label">
                <Setter Property="FontAttributes" Value="Bold" />
            </Style>
        </ResourceDictionary>
    </ContentPage.Resources>

    <StackLayout BindingContext="{StaticResource MainVm}">
        <ListView x:Name="ChildListView" VerticalOptions="Center" ItemsSource="{Binding Chidren}" SelectedItem="{Binding SelectedVm}">
            <ListView.ItemTemplate>
                <DataTemplate>
                    <ViewCell x:Name="ChildViewCell">
                        <ViewCell.View>
                            <Grid>
                                <Grid.ColumnDefinitions>
                                    <ColumnDefinition Width="Auto" />
                                    <ColumnDefinition Width="*" />
                                    <ColumnDefinition Width="Auto" />
                                </Grid.ColumnDefinitions>

                                <Button Text="&lt;" />

                                <Label 
                                    Grid.Column="1" 
                                    Text="{Binding Name}" 
                                    FontAttributes="{Binding Source={x:Reference ChildListView}, Path=SelectedItem.Id, Converter={StaticResource IsSelectedToStyle}, ConverterParameter={Binding Path=Id}}" 
                                />

                                <Button Grid.Column="2" Text="&gt;"  />
                            </Grid>
                        </ViewCell.View>
                    </ViewCell>
                </DataTemplate>
            </ListView.ItemTemplate>
        </ListView>
    </StackLayout>
</ContentPage>

And the following code:

using System;
using System.Collections.ObjectModel;
using System.ComponentModel;
using System.Globalization;
using Xamarin.Forms;

namespace StyleLabelInViewCell {
    public class MainVM : INotifyPropertyChanged {
        public MainVM() {
            Chidren = new ObservableCollection<ChildVM> {
                new ChildVM(1, "Item 1"),
                new ChildVM(2, "Item 2"),
                new ChildVM(3, "Item 3"),
                new ChildVM(4, "Item 4"),
                new ChildVM(5, "Item 5"),
                new ChildVM(6, "Item 6")
            };
        }

        public ObservableCollection<ChildVM> Chidren { get; }

        private ChildVM selectedVm;
        public ChildVM SelectedVm {
            get { return selectedVm; }
            set {
                if (!ReferenceEquals(selectedVm, value)) {
                    selectedVm = value;
                    OnPropertyChanged(nameof(SelectedVm));
                }
            }
        }

        public event PropertyChangedEventHandler PropertyChanged;
        protected virtual void OnPropertyChanged(string propertyName) {
            PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
        }
    }

    public class ChildVM {
        public ChildVM() { }

        public ChildVM(int id, string name) {
            Id = id;
            Name = name;
        }

        public int Id { get; }

        public string Name { get; }
    }

    public sealed class IsSelectedToStyle : IValueConverter {
        public object Convert(object value, Type targetType, object parameter, CultureInfo culture) {
            var selectedId = (int)value;
            var currentItemId = (int)parameter; // This ends up being Xamarin.Forms.Binding instance

            return selectedId == currentItemId ? Application.Current.MainPage.Resources["SelectedStyle"] : null;
        }

        public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture) {
            throw new NotSupportedException();
        }
    }
}

I'm trying to bold the label when the ItemTemplate is rending the currently selected row. The issue is that that ConverterParameter is sent in as a Xamarin.Forms.Binding instance, when I would have expected another integer.

Is there some way to get the value instead of the binding, or if not, from the Binding? Or is there another way to accomplish what I'm trying to do?

I think you can take a look to this post .

I have updated the repo . Now there is a Binding also for FontAttributes property

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

when you select a row, Selected property is set in VM

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

            _selectedItem = value;

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

and a IValueConverter convert the boolean "Selected" property to a FontAttribute

public class SelectedToFontAttributeConverter : 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 FontAttributes.Bold;
            else
                return FontAttributes.None;
        }
        return FontAttributes.None;
    }

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

    #endregion
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM