选择项目时出现水平集合视图错误
Horizontal Collection View Error While Selecting Items
我在 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() 中,列表被清除并再次创建,以显示所选项目的蓝色下划线。如何在不清除列表的情况下执行此操作?
这是最少的代码,可以在 iOS 和 Android 上正确滚动 Horizontal CollectionView。
请从这段代码开始。然后将您的代码添加到其中。如果您的代码仍然有此症状,请注释掉您的代码行,直到您找到“中断”滚动的原因。使用您正在使用的代码更新有问题的代码,并说明导致该症状的行。
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;
}
}
}
我在 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() 中,列表被清除并再次创建,以显示所选项目的蓝色下划线。如何在不清除列表的情况下执行此操作?
这是最少的代码,可以在 iOS 和 Android 上正确滚动 Horizontal CollectionView。
请从这段代码开始。然后将您的代码添加到其中。如果您的代码仍然有此症状,请注释掉您的代码行,直到您找到“中断”滚动的原因。使用您正在使用的代码更新有问题的代码,并说明导致该症状的行。
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;
}
}
}