在 Xamarin Forms 中选择项目时集合视图刷新问题
Collection View Refreshing issue While Selecting Item in Xamarin Forms
我在 Xamarin 表单中使用 集合视图 实现了水平列表。下划线不正确,选择项目时会迟到。刷新为时已晚。正如您在下面的视频中看到的那样
我的Xaml代码
<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>
我的 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;
}
}
}
我的视图模型
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;
}
}
我的模型
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; }
}
请提供解决此问题的建议enter image description here
我看到您在代码中使用了 e. PreviousSelection
。这比我在我的存储库中所做的要好,所以我修改了 github ToolmakerSteve - repo XFIOSHorizCollViewScrollBug 以使用它。
我在这个文件的几个地方做了修改:
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;
}
}
}
其他文件同。
请下载我的存储库,构建并运行它,验证它是否有效。下划线的更改会立即发生 - 只要您单击一个项目。
然后将其与您的代码进行比较。更改您的代码,直到它与工作仓库的功能相匹配。
我在 Xamarin 表单中使用 集合视图 实现了水平列表。下划线不正确,选择项目时会迟到。刷新为时已晚。正如您在下面的视频中看到的那样
我的Xaml代码
<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>
我的 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;
}
}
}
我的视图模型
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;
}
}
我的模型
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; }
}
请提供解决此问题的建议enter image description here
我看到您在代码中使用了 e. PreviousSelection
。这比我在我的存储库中所做的要好,所以我修改了 github ToolmakerSteve - repo XFIOSHorizCollViewScrollBug 以使用它。
我在这个文件的几个地方做了修改:
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;
}
}
}
其他文件同
请下载我的存储库,构建并运行它,验证它是否有效。下划线的更改会立即发生 - 只要您单击一个项目。
然后将其与您的代码进行比较。更改您的代码,直到它与工作仓库的功能相匹配。