我目前有一个集合视图,它显示从我设备中的本地数据库中提取的记录列表。数据库工作正常,添加记录、删除记录都工作正常。问题是当我添加或删除记录时,当集合视图被刷新时,它显示的是每个现有记录的副本。奇怪的是,如果我再次刷新,它将返回到正常状态,并且只显示从中提取的数据库中的表的记录。
这是我的观点模型:
[QueryProperty(nameof(Players), "Players")]
public partial class ManagePlayersPageViewModel : ObservableObject
{
/// <summary>
/// List of players being displayed
/// </summary>
private ObservableCollection<Player> _players = new();
public ObservableCollection<Player> Players
{
get => _players;
set => SetProperty(ref _players, value);
}
[ObservableProperty] private bool isRefreshing;
/// <summary>
/// Options for selection modes
/// </summary>
public SelectionOptions SelectionOptions { get; } = new();
/// <summary>
/// Adds player to list
/// </summary>
/// <returns></returns>
[RelayCommand]
async Task AddPlayer()
{
var task = await Shell.Current.ShowPopupAsync(new AddPlayerPopup());
var player = task as Player;
if (task == null)
return;
if (await PlayerService.RecordExists(player))
{
await Shell.Current.DisplaySnackbar("Jugador ya existe");
return;
}
await PlayerService.AddAsync(player);
await Refresh();
}
下面是refresh()方法:
/// <summary>
/// Refreshs and updates UI after each database query
/// </summary>
/// <returns></returns>
[RelayCommand]
async Task Refresh()
{
IsRefreshing = true;
await Task.Delay(TimeSpan.FromSeconds(1));
Players.Clear();
var playersList = await PlayerService.GetPlayersAsync();
foreach (Player player in playersList)
Players.Add(player);
IsRefreshing = false;
}
下面是控件所在的xaml:
<RefreshView Grid.Row="2" Grid.Column="0" Grid.ColumnSpan="3"
IsRefreshing="{Binding IsRefreshing}"
Command="{Binding RefreshCommand}">
<CollectionView
ItemsSource="{Binding Players}"
SelectionMode="{Binding SelectionOptions.SelectionMode}">
<CollectionView.ItemTemplate>
<DataTemplate>
<SwipeView>
<SwipeView.RightItems>
<SwipeItems>
<SwipeItemView
Padding="0, 2.5"
Command="{Binding Source={RelativeSource AncestorType={x:Type viewModels:ManagePlayersPageViewModel}}, Path= DeletePlayerCommand}"
CommandParameter="{Binding .}">
<Border
StrokeShape="RoundRectangle 10"
Stroke="{StaticResource DimBlackSolidColorBrush}"
Background="{StaticResource DimBlackSolidColorBrush}">
<Grid>
<Image
Source="Resources/Images/delete.svg"
WidthRequest="35"
HeightRequest="35"
Aspect="AspectFill"/>
</Grid>
</Border>
</SwipeItemView>
</SwipeItems>
</SwipeView.RightItems>
<Grid>
<Border Grid.Column="0"
StrokeShape="RoundRectangle 10"
Stroke="{StaticResource DimBlackSolidColorBrush}"
StrokeThickness="3">
<Grid
RowDefinitions="auto, auto, auto"
Background="{StaticResource DimBlackSolidColorBrush}">
<Label Grid.Row="0"
Text="{Binding Name}"
VerticalTextAlignment="Center"
Margin="10, 2.5"
TextColor="White"/>
<Label Grid.Row="1"
Text="{Binding Alias}"
VerticalTextAlignment="Center"
Margin="10, 2.5" />
<Label Grid.Row="2"
Text="{Binding Team, TargetNullValue=Ninguno}"
VerticalTextAlignment="Center"
FontAttributes="Italic"
Margin="10, 2.5" />
</Grid>
</Border>
<Grid.GestureRecognizers>
<TapGestureRecognizer
Command="{Binding Source={RelativeSource AncestorType={x:Type viewModels:ManagePlayersPageViewModel}}, Path=ItemTappedCommand}"
CommandParameter="{Binding .}"/>
</Grid.GestureRecognizers>
</Grid>
</SwipeView>
</DataTemplate>
</CollectionView.ItemTemplate>
</CollectionView>
</RefreshView>
知道为什么会发生这种情况吗?注意:数据库在上一页被查询,并作为参数传递到集合视图所在的页,不知道这是否与它有关。注意:它曾经与列表视图控件一起工作得很好,但我没有那么多的灵活性来定制该控件,这就是为什么我要走使用集合视图的路线。
当我调试时,它显示setter中的值已经重复,但我不知道为什么或在哪里重复。只有当我添加或删除记录时才会发生这种情况。任何帮助都是感激的,谢谢!
1条答案
按热度按时间v440hwme1#
如果在
Refresh
完成之前再次调用Refresh
,则可能会出现此症状。具体来说,如果在await PlayerService.GetPlayersAsync()
期间再次调用x1m0 n1,,则Players
上的操作序列将是:要确定是否发生了这种情况,请添加一个检查:
这是否会引发该异常?
如果是这样,那么在代码后面移动
Players.Clear()
。这 * 可能 * 会修复它:如果这样做还不能解决问题,那么在触及玩家的语句周围添加一个
lock
,以确保在前一个调用完成之前,一个调用不能触及它: