选择项目时出现水平集合视图错误

Posted

技术标签:

【中文标题】选择项目时出现水平集合视图错误【英文标题】:Horizontal Collection View Error While Selecting Items 【发布时间】:2022-01-19 11:44:52 【问题描述】:

单击集合视图中的数据时,我在 CollectionView 中遇到问题。 我正在选择中间数据,但它本身就是第一个。我在 ios 中遇到了这个问题。

 <CollectionView 
                x:Name="rooms_List"
                IsEnabled="True"
                SelectedItem="Binding SelectedRoom"
                SelectionChangedCommand="Binding Source=x:Reference ThePage, Path= BindingContext.RoomChanged"
                ItemsLayout = "HorizontalList"
                SelectionChanged="RoomCollectionSelectionChanged"
                BackgroundColor = "white"
                HeightRequest="50"
                SelectionMode="Single"
                HorizontalScrollBarVisibility="Never"
                ItemsSource="Binding RoomList">
                <CollectionView.ItemTemplate>
                    <DataTemplate>
                        <Grid>
                            <StackLayout Orientation="Horizontal" Margin="0,0,0,15">
                                <StackLayout VerticalOptions="Start" Orientation="Vertical">
                                    <Label  Text ="Binding RoomName"  Padding="20,10,20,0" />
                                    <BoxView x:Name="line" HeightRequest="3" IsVisible="Binding IsSelected" BackgroundColor="#1484B8" WidthRequest="5" Margin="18,0,15,0" />
                                </StackLayout>
                            </StackLayout>
                        </Grid>
                    </DataTemplate>
                </CollectionView.ItemTemplate>
            </CollectionView>

这是目前使用的代码。在 android 中它工作正常。我只在 iOS 中遇到这个问题。

我的 RoomCollectionSelectionChanged 事件

private void RoomCollectionSelectionChanged(object sender, SelectionChangedEventArgs e)
        
            if (e.CurrentSelection.Count == 0)
            
                room_image.IsVisible = true;
            
            else
            
                var selectedItem = e.CurrentSelection.FirstOrDefault() as Room;
                selectedRoom = selectedItem.RoomName;
                if (selectedRoom == "All")
                
                    room_image.IsVisible = false;
                
                else if (e.PreviousSelection.Count == 1)
                
                    var previousItem = (e.PreviousSelection.FirstOrDefault() as Room)?.RoomName;
                    if (previousItem != "")
                    
                        room_image.IsVisible = true;
                        room_image.Source = selectedItem.RoomImage;
                    
                
                else
                 
                    room_image.IsVisible = true;
                    room_image.Source = selectedItem.RoomImage;
                
            
        

ViewModel - SelectedRoomEvent

 private void SelectedRoomEvent()
        
            if (SelectedRoom != null)
            
                string RoomName = SelectedRoom.RoomName;
                if (RoomName.Equals("All"))
                
                    GetDeviceAndRoomData();
                
                else
                
                    int RoomId = SelectedRoom.RoomId;
                    RoomList.Clear();
                    var rooms = db.GetRoomAsync().Result.ToList();
                    roomList.Add(new Room
                    
                        Id = 0,
                        RoomId = 0,
                        RoomName = "All",
                        RoomImage = "none",
                        IsSelected = false
                    );
                    foreach (var room in rooms)
                    
                        Room r = new Room();
                        r.Id = room.Id;
                        r.RoomId = room.RoomId;
                        r.RoomName = room.RoomName;
                        r.RoomImage = room.RoomImage;
                        r.IsSelected = (r.RoomName == RoomName) ? true : false;
                        RoomList.Add(r);
                    
                
            
            else
            

            
        

更新

列表在选择项目时弹回开始,因为在 ViewModel -> SelectedEvent() 中,列表被清除并再次创建,以显示所选项目的蓝色下划线。不清除 List 怎么办?

【问题讨论】:

我删除了我的答案,错误的问题。看这里***.com/questions/69824356/… 您尚未提供所有代码。请提供您的 ViewModel,以便我们了解视图所代表的业务逻辑。 你基于什么示例代码?你能提供一个链接吗?另外,需要查看RoomCollectionSelectionChanged方法的源代码。 @AndrewH 嗨,我添加了我的所有代码 - ViewModel 和 CodeBehind。请帮忙 运行我提供的 repo - 看看它是否有效。 SelectRoom 清除旧项目的下划线,并将其放在新项目上。这是你需要的吗? 【参考方案1】:

这是最少的代码,可以在 iOS 和 Android 上正确滚动 Horizo​​ntal CollectionView。

请从这段代码开始。然后将您的代码添加到其中。如果您的代码仍然有症状,请注释掉代码行,直到找到“中断”滚动的原因。使用您正在使用的代码更新有问题的代码,并说明导致该症状的行。

github repo here.

MainPage.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:ios="clr-namespace:Xamarin.Forms.PlatformConfiguration.iOSSpecific;assembly=Xamarin.Forms.Core"
             ios:Page.UseSafeArea="true"
             x:Class="XFIOSHorizCollViewScrollBug.MainPage">

    <StackLayout>
        <!--SelectionChangedCommand="Binding Source=x:Reference ThePage, Path= BindingContext.RoomChanged"-->
        <CollectionView 
                    x:Name="rooms_List" ItemsLayout = "HorizontalList" ItemsSource="Binding RoomList"
                    SelectionChanged="RoomCollectionSelectionChanged" HeightRequest="50"
                    SelectionMode="Single" HorizontalScrollBarVisibility="Never" >
            <CollectionView.ItemTemplate>
                <DataTemplate>
                    <Grid>
                        <StackLayout Orientation="Horizontal" Margin="0,0,0,15">
                            <StackLayout VerticalOptions="Start" Orientation="Vertical">
                                <Label  Text ="Binding RoomName"  Padding="20,10,20,0" />
                                <BoxView x:Name="line" HeightRequest="3" IsVisible="Binding IsSelected" BackgroundColor="#1484B8" WidthRequest="5" Margin="18,0,15,0" />
                            </StackLayout>
                        </StackLayout>
                    </Grid>
                </DataTemplate>
            </CollectionView.ItemTemplate>
        </CollectionView>
    </StackLayout>

</ContentPage>

MainPage.xaml.cs:

using System.Collections.ObjectModel;
using System.Linq;
using Xamarin.Forms;

namespace XFIOSHorizCollViewScrollBug

    public partial class MainPage : ContentPage
    
        public MainPage()
        
            InitializeComponent();
            InitRoomList();
            BindingContext = this;
        

        public ObservableCollection<Room> RoomList  get; set; 

        private Room _previousSelection;

        private void RoomCollectionSelectionChanged(object sender, SelectionChangedEventArgs e)
        
            var selectedItem = e.CurrentSelection.FirstOrDefault() as Room;
            SelectRoom(selectedItem);
        

        private void SelectRoom(Room room)
        
            if (room != null) 
                if (_previousSelection != null)
                    _previousSelection.IsSelected = false;

                room.IsSelected = true;
                rooms_List.ScrollTo(room, position: ScrollToPosition.Center, animate: false);

                _previousSelection = room;
            
        

        string[] roomNames = new string[] 
            "One", "Two", "Three", "Four", "Five", "Six", "Seven", "Eight"
        ;

        private void InitRoomList()
        
            var rooms = new ObservableCollection<Room>();
            foreach (var name in roomNames) 
                rooms.Add(new Room(name));
            

            var room = rooms[0];
            room.IsSelected = true;
            _previousSelection = room;

            RoomList = rooms;
        
    

Room.cs:

namespace XFIOSHorizCollViewScrollBug

    public class Room : Xamarin.Forms.BindableObject
    
        public string RoomName  get; set; 

        public bool IsSelected 
            get => _isSelected;
            set 
                _isSelected = value;
                OnPropertyChanged();
            
        
        private bool _isSelected;

        public Room(string name, bool isSelected = false)
        
            RoomName = name;
            IsSelected = isSelected;
        
    

【讨论】:

以上是关于选择项目时出现水平集合视图错误的主要内容,如果未能解决你的问题,请参考以下文章

创建新团队项目时出现TF218027错误

在 kivyMD 中选择 MDCheckbox 时出现应用错误

使用 Xcode 7、iOS 9 运行项目时出现“应用程序窗口应在应用程序启动结束时具有根视图控制器”错误

快速获取所选视图的索引时出现问题

创建 TFS 团队项目时出现问题

如何使用情节提要将集合视图部分项目滚动到水平