我在 WinUI 3 应用程序中遇到奇怪的行为,其中 ListView 显示项目集合。每个项目模板中的复选框都绑定到名为 IsComplete 的 bool 属性。这是一个多客户端、服务器同步的应用程序,其中数据更改可以从不同的客户端发生并通过服务器同步。
<ListView
Grid.Row="1"
Margin="10"
ItemsSource="{x:Bind ViewModel.Items}"
ScrollViewer.VerticalScrollBarVisibility="Auto">
<ListView.ItemTemplate>
<DataTemplate>
<StackPanel Orientation="Horizontal">
<CheckBox
Margin="10"
Command="{Binding ViewModel.EditItemCommand, ElementName=ThisPage}"
CommandParameter="{Binding Id}"
Content="{Binding Title}"
IsChecked="{Binding IsComplete}" />
<TextBlock Margin="10" Text="Checked: " />
<TextBlock Text="{Binding IsComplete}" />
</StackPanel>
</DataTemplate>
</ListView.ItemTemplate>
</ListView>
[ObservableProperty]
private ConcurrentObservableCollection<TodoItem> items = [];
[RelayCommand]
public async Task RefreshItemsAsync(CancellationToken cancellationToken = default)
{
try
{
IsRefreshing = true;
// Synchronize data with the remote service (if any).
await service.SynchronizeAsync(cancellationToken);
// Pull all items from the database.
IEnumerable<TodoItem> itemsFromDatabase = await service.TodoItems.OrderBy(item => item.Id).ToListAsync(cancellationToken);
// Replace all the items in the collection.
Items.ReplaceAll(itemsFromDatabase);
//Items.Clear();
//_ = Items.AddRange(itemsFromDatabase);
}
catch (Exception ex)
{
NotificationHandler?.Invoke(this, new NotificationEventArgs(ex.GetType().Name, ex.Message, true));
}
finally
{
IsRefreshing = false;
NotificationHandler?.Invoke(this, new NotificationEventArgs("Items Refreshed", "", false));
}
}
public class TodoItem : OfflineClientEntity
{
private bool _isComplete = false;
public string Title { get; set; } = string.Empty;
public bool IsComplete { get; set; } = false;
public override string ToString()
=> JsonSerializer.Serialize(this);
}
using System;
using System.ComponentModel.DataAnnotations;
namespace TodoApp.WinUI3.Database;
/// <summary>
/// An abstract class for working with offline entities.
/// </summary>
public abstract class OfflineClientEntity
{
[Key]
public string Id { get; set; }
public DateTimeOffset? UpdatedAt { get; set; }
public string Version { get; set; }
public bool Deleted { get; set; }
}
首先,我不熟悉
ConcurrentObservableCollection
,所以我假设它基于ObservableCollection。
现在,当您在待办事项中应用更改时,通常需要实现 INotifyPropertyChanged。您可以自己完成,但由于您使用的是 CommunityToolkit.Mvvm,因此您可以为 TodoItem
创建一个
ObservableObject基类,或者只是用包装类包装它。