【问题标题】:Xamarin forms: How to add an underline only for the selected item in CollectionviewXamarin 表单:如何仅为 Collectionview 中的选定项目添加下划线
【发布时间】:2020-08-03 06:23:47
【问题描述】:

我有一个带有某些项目的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 总是在第一个项目上,我在这里缺少什么?

【问题讨论】:

    标签: xamarin.forms collectionview


    【解决方案1】:

    您需要在模型中实现接口INotifyPropertyChanged,以便您可以在运行时更新UI

    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;
            }
        }
    

    【讨论】:

    • 我已经这样尝试过了,但是boxview总是在第一个项目上
    • 通过这个实现不需要CategoryTapped函数吧?
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多