Home > database >  Collection View Refreshing issue While Selecting Item in Xamarin Forms
Collection View Refreshing issue While Selecting Item in Xamarin Forms

Time:12-23

I have implemented horizontal list using collection view in Xamarin forms. The Underline doesn't come properly it will be late while selecting Item. The Refreshing is too late. AS you can see in the following Video

My Xaml Code

  <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 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>
                            </Grid>
                    </DataTemplate>
                </CollectionView.ItemTemplate>
            </CollectionView>

My Xaml.cs 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;
                }
            }
        }

My ViewModel

private ObservableCollection<Room> roomList { get; set; }

        public ObservableCollection<Room> RoomList
        {
            get { return roomList; }
            set
            {
                roomList = value;
                OnPropertyChanged(nameof(RoomList));
            }
        }

        private Room selectedRoom { get; set; }

        public Room SelectedRoom
        {
            get { return selectedRoom; }
            set
            {
                selectedRoom = value;
            }
        }

        public bool isSelected { get; set; }

        public bool IsSelected
        {
            get { return isSelected; }
            set
            {
                if (value != isSelected)
                {
                    isSelected = value;
                    OnPropertyChanged(nameof(IsSelected));
                }
            }
        }

        private Room previousSelectedRoom;

        private void SelectedRoomEvent()
        {
            if (SelectedRoom != null)
            {
                DevicePage.checkRoom = true;
                string RoomName = SelectedRoom.RoomName;

                if (RoomName.Equals("All"))
                {
                    GetDeviceAndRoomData();
                }
                else
                {
                    int RoomId = SelectedRoom.RoomId;

                    if (previousSelectedRoom != null)
                    {
                        previousSelectedRoom.IsSelected = false;
                    }
                    previousSelectedRoom = SelectedRoom;
                    previousSelectedRoom.IsSelected = true;

                }
        }

My Model

public class Room
    {
        [PrimaryKey, AutoIncrement]
        public int Id { get; set; }
        [JsonProperty("roomId")]
        public int RoomId { get; set; }
        [JsonProperty("serialNumber")]
        public string SerialNumber { get; set; }
        [JsonProperty("roomName")]
        public string RoomName { get; set; }
        [JsonProperty("roomImage")]
        public string RoomImage { get; set; }
        [JsonIgnore]
        public bool IsSelected { get; set; }
    }

Please give suggestions how to fix this enter image description here

CodePudding user response:

I see you use e. PreviousSelection in your code. That is better than what I was doing in my repository, so I have modified github ToolmakerSteve - repo XFIOSHorizCollViewScrollBug to use that.

I made changes in several places in this file:

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

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

            // After set BindingContext, so RoomCollectionSelectionChanged gets called.
            var room = RoomList[0];
            rooms_List.SelectedItem = room;
        }

        public ObservableCollection<Room> RoomList { get; set; }

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

        private void DeselectRoom(Room room)
        {
            if (room != null)
            {
                room.IsSelected = false;
            }
        }

        private void SelectRoom(Room room)
        {
            if (room != null) {
                room.IsSelected = true;
                rooms_List.ScrollTo(room, position: ScrollToPosition.Center, animate: false);
            }
        }

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

            RoomList = rooms;
        }
    }
}

The other files are the same as in my answer to your previous question.

Please download my repository, build and run it, verify that it works. The change to underline happens INSTANTLY - as soon as you click on an item.

Then compare that to your code. Change your code until it matches what the working repo does.

  • Related