Not
Bu sayfaya erişim yetkilendirme gerektiriyor. Oturum açmayı veya dizinleri değiştirmeyi deneyebilirsiniz.
Bu sayfaya erişim yetkilendirme gerektiriyor. Dizinleri değiştirmeyi deneyebilirsiniz.
Bu adımda yardımcıdan uygulamanın görsel olmayan bölümlerini isteyin. Bu değişikliğin XAML'den ayrı tutulması, derleyici hatalarını ve tasarım sorunlarını yalıtmak daha kolay hale getirir.
Model ve depolama hizmeti isteyin
Şu istemi kullanın:
Add the data layer for TaskTally.
- Create a TaskItem model with an ID, title, and completion state.
- Use MVVM Toolkit observable properties.
- Create a TaskStorage service that serializes the task list to JSON.
- Store tasks in ApplicationData.Current.LocalFolder because this is
a packaged WinUI 3 app.
- Return an empty list when the file doesn't exist.
- Serialize save operations so rapid changes don't write the file concurrently.
- Surface real read and write errors to the caller.
- Build the project after the change.
Oluşturulan modeli şu uygulamayla karşılaştırın:
using CommunityToolkit.Mvvm.ComponentModel;
namespace TaskTally.Models;
public partial class TaskItem : ObservableObject
{
public Guid Id { get; init; } = Guid.NewGuid();
[ObservableProperty]
public partial string Title { get; set; } = string.Empty;
[ObservableProperty]
public partial bool IsComplete { get; set; }
}
[ObservableProperty] özniteliği genel özellikler oluşturur ve bildirimleri değiştirir. MVVM Toolkit kaynak oluşturucusunun bu kodu ekleyebilmesi için sınıfı olmalıdır partial .
Depolama hizmeti şöyle görünmelidir:
using System.Text.Json;
using System.Threading;
using TaskTally.Models;
using Windows.Storage;
namespace TaskTally.Services;
internal static class TaskStorage
{
private const string FileName = "tasks.json";
private static readonly SemaphoreSlim SaveLock = new(1, 1);
public static async Task<IReadOnlyList<TaskItem>> LoadAsync()
{
StorageFile? file =
await ApplicationData.Current.LocalFolder.TryGetItemAsync(FileName) as StorageFile;
if (file is null)
{
return [];
}
string json = await FileIO.ReadTextAsync(file);
return JsonSerializer.Deserialize<List<TaskItem>>(json) ?? [];
}
public static async Task SaveAsync(IEnumerable<TaskItem> tasks)
{
await SaveLock.WaitAsync();
try
{
string json = JsonSerializer.Serialize(tasks, new JsonSerializerOptions
{
WriteIndented = true
});
StorageFile file = await ApplicationData.Current.LocalFolder.CreateFileAsync(
FileName,
CreationCollisionOption.ReplaceExisting);
await FileIO.WriteTextAsync(file, json);
}
finally
{
SaveLock.Release();
}
}
}
ApplicationData.Current.LocalFolder burada uygundur çünkü uygulama paket kimliğine sahiptir.
SaveLock ekleme, silme ve tamamlama işlemlerinin aynı dosyayı aynı anda yazmasını engeller. Daha sonra dağıtım modelini değiştirirseniz, bu depolama seçimini otomatik olarak kopyalamak yerine paket kimliği varsayımını yeniden doğrulayın.
Daha fazla bilgi edinin: Ayarları ve diğer uygulama verilerini veApplicationData.LocalFolder'ı depolayıp alın.
Görünüm modelini isteme
Ardından şu istemi kullanın:
Add MainPageViewModel.
- Expose an ObservableCollection<TaskItem>.
- Add observable properties for the new-task text and status message.
- Add asynchronous commands to add and delete tasks.
- Disable AddTaskCommand when the title is blank.
- Load tasks once when the page starts.
- Save after add, delete, or completion changes.
- Expose a summary and empty-state property for x:Bind.
- Catch storage exceptions only where the UI can report them.
- Build and fix all warnings.
Yanıtta denetlenecek ana desenler şunlardır:
public ObservableCollection<TaskItem> Tasks { get; } = [];
[ObservableProperty]
public partial string NewTaskTitle { get; set; } = string.Empty;
public string Summary =>
Tasks.Count == 0
? "No tasks yet"
: $"{Tasks.Count(task => !task.IsComplete)} of {Tasks.Count} remaining";
[RelayCommand(CanExecute = nameof(CanAddTask))]
private async Task AddTaskAsync()
{
string title = NewTaskTitle.Trim();
Tasks.Add(new TaskItem { Title = title });
NewTaskTitle = string.Empty;
RefreshTaskState();
await SaveAsync($"Added \"{title}\".");
}
[RelayCommand]
private async Task DeleteTaskAsync(TaskItem task)
{
Tasks.Remove(task);
RefreshTaskState();
await SaveAsync($"Deleted \"{task.Title}\".");
}
private bool CanAddTask() => !string.IsNullOrWhiteSpace(NewTaskTitle);
partial void OnNewTaskTitleChanged(string value)
{
AddTaskCommand.NotifyCanExecuteChanged();
}
Yardımcının, .Result veya .Wait() ile eşzamansız çalışmayı engellemediğinden emin olun. Depolama işlemlerinin tamamlanması beklenmelidir.
Görünüm modeli, depolama özel durumlarını sayfa için bir iletiye dönüştürdüğünde yakalayabilir:
private async Task SaveAsync(string successMessage)
{
try
{
await TaskStorage.SaveAsync(Tasks);
ShowStatus(successMessage);
}
catch (Exception ex)
{
ShowStatus($"Changes couldn't be saved: {ex.Message}");
}
}
Bu sessiz bir geri dönüş değildir: kullanıcı bir hata alır ve görünüm modeli kaydetme işleminin başarılı olduğunu iddia etmez.
Derleme ve inceleme
x64 için derleme. Uyarıları, özellikle bağlama ve nullable başvuru uyarılarını, çalışma öğeleri olarak değerlendirin:
dotnet build -p:Platform=x64
Yardımcıdan eklediği her paketi açıklamasını isteyin. Bu uygulama için şablondaki Windows Uygulama SDK'sı ve MVVM Araç Seti başvurularının ötesinde yeni bir pakete gerek duyulmamalıdır.
Windows developer