Я создаю библиотеку компонентов бритвы, которая будет реализована в существующем приложении .NET 7 Blazor Server. По сути, простой клиент EMAP E-mail, я использую библиотеку MailKit.
Я использовал пример документации Mailkit для форм Windows и настроен на работу в Razor.
Это заполняет папки, как и ожидалось, но когда я пытаюсь обновить элемент MessageInfo, в качестве примера, изменение на помещение или нецветное, я пытаюсь обновить UDATE UDATE ARTINGE, но изменения в PARESEDALIED, но на PARESEDALIED. /> Я попробовал Statehaschanged, Invokeasync (statehaschanged), действие события, все без успеха.
Это то, что я получил до сих пор, Serviace: < /p>
Код: Выделить всё
using BlazorEmailLib.Models;
using MailKit;
using MailKit.Net.Imap;
namespace BlazorEmailLib.Services;
public interface IMessageListService
{
event EventHandler? MessageSelected;
event Action? OnMessagesUpdated;
Task OpenFolderAsync(IMailFolder folder);
void AddMessageSummaries(IMailFolder folder, IEnumerable[i] summaries);
void SelectMessage(MessageInfo messageInfo);
List GetMessages();
Task ToggleFlagAsync(MessageInfo messageInfo, MessageFlags flags);
}
public class MessageListService : IMessageListService
{
private static readonly FetchRequest _request = new(MessageSummaryItems.UniqueId | MessageSummaryItems.Envelope | MessageSummaryItems.Flags | MessageSummaryItems.BodyStructure);
private const int _batchSize = 512;
private readonly List _messages = new();
private IMailFolder? _folder;
public event EventHandler? MessageSelected;
public event Action? OnMessagesUpdated;
public async Task OpenFolderAsync(IMailFolder folder)
{
if (this._folder != null)
{
this._folder.MessageFlagsChanged -= OnMessageFlagsChanged;
this._folder.MessageExpunged -= OnMessageExpunged;
this._folder.CountChanged -= OnCountChanged;
}
folder.MessageFlagsChanged += OnMessageFlagsChanged;
folder.MessageExpunged += OnMessageExpunged;
this._folder = folder;
lock (_messages)
{
_messages.Clear();
}
try
{
if (!folder.IsOpen)
await folder.OpenAsync(FolderAccess.ReadWrite);
if (folder.Count > 0)
{
var summaries = await folder.FetchAsync(0, -1, _request);
AddMessageSummaries(folder, summaries);
}
}
catch (ImapCommandException ex) when (ex.Message.Contains("NO"))
{
Console.WriteLine("Algumas mensagens não existem mais. Atualizando a lista...");
await folder.OpenAsync(FolderAccess.ReadWrite);
}
catch (Exception ex)
{
Console.WriteLine($"Erro inesperado: {ex.Message}");
}
folder.CountChanged += OnCountChanged;
}
public void AddMessageSummaries(IMailFolder folder, IEnumerable summaries)
{
if (folder != this._folder)
return;
foreach (var message in summaries)
{
var info = new MessageInfo(message);
_messages.Add(info);
}
if (_messages.Count < folder.Count)
FetchNewMessages(folder);
}
private void FetchNewMessages(IMailFolder folder)
{
Task.Run(async () =>
{
if (!folder.IsOpen)
await folder.OpenAsync(FolderAccess.ReadWrite);
if (folder.Count > 0)
{
int currentCount;
lock (_messages)
{
currentCount = _messages.Count;
}
var summaries = await folder.FetchAsync(currentCount, Math.Min(folder.Count - 1, currentCount + _batchSize - 1), _request);
AddMessageSummaries(folder, summaries);
}
});
}
private void OnMessageFlagsChanged(object? sender, MessageFlagsChangedEventArgs e)
{
lock (_messages)
{
if (e.Index < _messages.Count)
{
var info = _messages[e.Index];
info.Flags = e.Flags;
}
}
}
private void OnMessageExpunged(object? sender, MessageEventArgs e)
{
lock (_messages)
{
if (e.Index < _messages.Count)
{
_messages.RemoveAt(e.Index);
}
}
}
private void OnCountChanged(object? sender, EventArgs e)
{
var folder = (IMailFolder)sender!;
FetchNewMessages(folder);
}
public void SelectMessage(MessageInfo messageInfo)
{
if (_folder != null)
{
MessageSelected?.Invoke(this, new MessageSelectedEventArgs(_folder, messageInfo.Summary.UniqueId, messageInfo.Summary.Body));
}
}
public List GetMessages()
{
lock (_messages)
{
return new List(_messages);
}
}
public async Task ToggleFlagAsync(MessageInfo messageInfo, MessageFlags flags)
{
if (_folder != null)
{
if (messageInfo.Flags.HasFlag(flags))
{
await _folder.RemoveFlagsAsync(messageInfo.Summary.UniqueId, flags, true);
}
else
{
await _folder.AddFlagsAsync(messageInfo.Summary.UniqueId, flags, true);
}
// Notifica que as mensagens mudaram
OnMessagesUpdated?.Invoke();
}
}
}
public class MessageSelectedEventArgs : EventArgs
{
public IMailFolder Folder { get; }
public UniqueId UniqueId { get; }
public BodyPart Body { get; }
public MessageSelectedEventArgs(IMailFolder folder, UniqueId uniqueId, BodyPart body)
{
Folder = folder;
UniqueId = uniqueId;
Body = body;
}
}
< /code>
и компонент бритвы: < /p>
@using Microsoft.AspNetCore.Components.Web
@using Microsoft.Extensions.Logging
@using BlazorEmailLib.Services
@using BlazorEmailLib.Helpers
@using BlazorEmailLib.Models
@using MailKit
@using MailKit.Net.Imap;
@using MimeKit
@inject IImapClientService ImapClientService
@inject IMessageListService MessageListService
@inject ILogger Logger
@namespace BlazorEmailLib.Components
@if (IsLoading)
{
foreach (var i in Enumerable.Range(0, 10))
{
}
}
else if (_messages != null && _messages.Any())
{
@foreach (var message in _messages)
{
class="email-item @(message.Flags.HasFlag(MessageFlags.Seen) ? "seen" : "") @(IsCurrent ? "email-item__selected":"")">
@message.Summary.Envelope.From.Mailboxes.FirstOrDefault()!.Address
@if (message.Summary.Envelope.Date?.Date == DateTimeOffset.Now.Date)
{
@message.Summary.Envelope.Date?.DateTime.ToString("HH:mm")
}
else
{
@message.Summary.Envelope.Date?.DateTime.ToString("dd/MM/yyyy")
}
@CommonHelpers.TruncateText(message.Summary.NormalizedSubject)
@CommonHelpers.ConvertMessageSize(message.Summary.Size.GetValueOrDefault())
@if (message.Summary.Attachments.Any(a => a.IsAttachment))
{
[/i]
}
@if (message.Summary.Flags != null)
{
@if (message.Summary.Flags.Value.HasFlag(MessageFlags.Answered))
{
[i][/i]
}
[i][/i]
}
}
}
else
{
No messages found.
}
@code {
[Parameter] public IMailFolder? Folder { get; set; }
private List? _messages;
private bool IsLoading { get; set; } = true;
private bool IsCurrent { get; set; }
public bool IsSelected { get; set; }
public EventCallback IsSelectedChanged { get; set; }
protected override async Task OnParametersSetAsync()
{
if (Folder != null)
{
IsLoading = true;
await MessageListService.OpenFolderAsync(Folder);
_messages = new List(MessageListService.GetMessages());
IsLoading = false;
}
}
protected override void OnInitialized()
{
MessageListService.OnMessagesUpdated += async () => await InvokeAsync(StateHasChanged);
}
private async void HandleMessagesUpdated()
{
await InvokeAsync(StateHasChanged);
}
private void SelectMessage(MessageInfo messageInfo)
{
MessageListService.SelectMessage(messageInfo);
}
private async Task HandleClick(MouseEventArgs e)
{
}
private async Task HandleFlagClick(MessageInfo message, MessageFlags flags)
{
await MessageListService.ToggleFlagAsync(message, flags);
// Atualiza o estado do objeto (Blazor só deteta mudanças em propriedades e não referências)
message.Flags = message.Flags.HasFlag(flags)
? message.Flags & ~flags // Remove flag
: message.Flags | flags; // Adiciona flag
// Força o Blazor a redesenhar o componente
await InvokeAsync(StateHasChanged);
}
public void Dispose()
{
MessageListService.OnMessagesUpdated -= HandleMessagesUpdated;
}
}
Подробнее здесь: https://stackoverflow.com/questions/794 ... pdating-ui