Формы Xamarin: как добавить подчеркивание только для выбранного элемента в Collectionview - PullRequest
0 голосов
/ 03 августа 2020

У меня есть horizontal collectionview с некоторым элементом, мне нужно подчеркивание только для выбранного элемента.

Я пробовал, как показано ниже:

MainPage.xaml.cs

public partial class MainPage : ContentPage
{
    public List<Category> categoryList { get; set; }
    public MainPage()
    {
        InitializeComponent();
        categoryList = new List<Category>();
        SetItems(true, false, false, false, false, false);
    }

    private void SetItems(bool v1, bool v2, bool v3, bool v4, bool v5, bool v6)
    {
        categoryList.Add(new Category() { Title = "itme1", IsSelected = v1 });
        categoryList.Add(new Category() { Title = "itme2", IsSelected = v2 });
        categoryList.Add(new Category() { Title = "itme3", IsSelected = v3 });
        categoryList.Add(new Category() { Title = "itme4", IsSelected = v4 });
        categoryList.Add(new Category() { Title = "itme5", IsSelected = v5 });
        categoryList.Add(new Category() { Title = "itme6", IsSelected = v6 });
        Category_collectionview.ItemsSource = categoryList;
    }

    public void CategoryTapped(object sender, SelectionChangedEventArgs e)
    {
        var selectedItem = (e.CurrentSelection.FirstOrDefault() as Category);
        if (selectedItem != null)
        {
            if (selectedItem.Title == "itme1")
            {
                SetItems(true, false, false, false, false, false);
            }
            else if (selectedItem.Title == "itme2")
            {
                SetItems(false, true, false, false, false, false);
            }
            else if (selectedItem.Title == "itme3")
            {
                SetItems(false, false, true, false, false, false);
            }
        }
        Category_collectionview.SelectedItem = null;
    }
}

public class Category 
{
    public string Title { get; set; }
    public bool IsSelected { get; set; }
}

MainPage.xaml

<CollectionView 
        SelectionMode="Single"
        SelectionChanged="CategoryTapped"
        x:Name="Category_collectionview"
        ItemsLayout="HorizontalList">
        <CollectionView.ItemTemplate>
            <DataTemplate>
                <StackLayout 
                    Orientation="Vertical"
                    Margin="5">

                    <Label
                        TextColor="Black"
                        HorizontalTextAlignment="Center"
                        VerticalTextAlignment="Center"
                        Text="{Binding Title}">
                        <Label.FontSize>
                            <OnIdiom x:TypeArguments="x:Double">
                                <OnIdiom.Phone>16</OnIdiom.Phone>
                                <OnIdiom.Tablet>32</OnIdiom.Tablet>
                                <OnIdiom.Desktop>16</OnIdiom.Desktop>
                            </OnIdiom>
                        </Label.FontSize>
                    </Label>

                    <BoxView 
                        HorizontalOptions="FillAndExpand"
                        BackgroundColor="Black"
                        IsVisible="{Binding IsSelected}"
                        HeightRequest="2"/>
                </StackLayout>
            </DataTemplate>
        </CollectionView.ItemTemplate>
    </CollectionView>

Но boxview всегда стоит на первом элементе, чего мне здесь не хватает?

1 Ответ

1 голос
/ 03 августа 2020

Вам необходимо реализовать интерфейс INotifyPropertyChanged в модели, чтобы вы могли обновлять пользовательский интерфейс во время выполнения

public class Category : INotifyPropertyChanged
{
    public event PropertyChangedEventHandler PropertyChanged;



    protected virtual void OnPropertyChanged([CallerMemberName] string propertyName = null)
    {
        PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
    }

    public string Title { get; set; }

    bool isSelected;
    public bool IsSelected { get {

            return isSelected;

        }
        set
        {
            if(value!= isSelected)
            {
                isSelected = value;
                OnPropertyChanged("IsSelected");
            }
        }
    }
}

Кроме того, событие CategoryTapped не будет работать в вашем случае. Вы можете использовать TapGestureRecognizer

<CollectionView 
        SelectionMode="Single"
        
        x:Name="Category_collectionview"
        ItemsSource="{Binding categoryList}"
        ItemsLayout="HorizontalList">
            <CollectionView.ItemTemplate>
<DataTemplate>
     <StackLayout 
           Orientation="Vertical"
           Margin="5">

          <StackLayout.GestureRecognizers>
             <TapGestureRecognizer Tapped="TapGestureRecognizer_Tapped" />
          </StackLayout.GestureRecognizers>
          //...

И в коде позади

Примечание: Было бы лучше использовать ObservableCollection вместо List. И это не лучший дизайн, чтобы каждый раз сбрасывать ItemsSource .

public partial class MainPage : ContentPage
    {
        public ObservableCollection<Category> categoryList { get; set; }
        public MainPage()
        {
            InitializeComponent();
            categoryList = new ObservableCollection<Category>();
            SetItems(true, true, false, false, false, false);
            BindingContext = this;
        }

        private void SetItems(bool v1, bool v2, bool v3, bool v4, bool v5, bool v6)
        {
            categoryList.Add(new Category() { Title = "itme1", IsSelected = v1 });
            categoryList.Add(new Category() { Title = "itme2", IsSelected = v2 });
            categoryList.Add(new Category() { Title = "itme3", IsSelected = v3 });
            categoryList.Add(new Category() { Title = "itme4", IsSelected = v4 });
            categoryList.Add(new Category() { Title = "itme5", IsSelected = v5 });
            categoryList.Add(new Category() { Title = "itme6", IsSelected = v6 });
            Category_collectionview.ItemsSource = categoryList;
           
        }

        private void TapGestureRecognizer_Tapped(object sender, EventArgs e)
        {
            var obj = sender as StackLayout;

            var currentItems = obj.BindingContext as Category;

            foreach (Category category in categoryList)
            {
                category.IsSelected = false;

                if (currentItems == category)
                {
                    category.IsSelected = true;
                }
            }

            Category_collectionview.SelectedItem = null;
        }
    }

введите описание изображения здесь

...