К этому нужно подходить немного по-другому, так как тип EventHandler<T>
здесь не работает, как ожидалось. (По крайней мере, не для меня)
Прежде всего, для EventArgs
, помните, что это тип, поэтому вы не можете присвоить их свойству Status
(которое у вас есть в виде строки) без актерского состава. Способ сделать это - определить свой собственный тип аргументов, производный от EventArgs, что-то вроде этого:
public class PatientEventArgs: EventArgs
{
public string PatientName {get; set;}
public string StatusValue {get; set;}
}
Далее для метода-обработчика, который вам нужно использовать, установите его как asyn c метод. Я обнаружил, что асин c был важен, так что вы можете использовать InvokeAsync
дальше и избежать исключения, когда поток и диспетчер не согласны, как в других открытых windows или других пользователях, вошедших в другое место, через это post: Обсуждение потока против контекста синхронизации
private async void OnStatusChanged(object sender, EventArgs e) {
// Make sure the args are the type you are expecting
if(e.GetType() == typeof(PatientEventArgs))
//Cast to the correct Args type to access properties
var patientStatus = e as PatientEvendArgs;
status = patientStatus.StatusValue;
Console.Writeline(patientStatus.PatientName);
/* Use InvokeAsync method with await to make sure
StateHasChanged runs correctly here without interfering with another
thread (open window or other users) */
await InvokeAsync(() => StateHasChanged());
}
Далее и важно для вашего сценария, вы попадете в стену с объявление Частичного класса в том виде, в каком оно у вас есть, поскольку вам нужно реализовать IDisposable
для очистки после себя, когда компонент разрушается. Вместо этого используйте структуру наследования следующим образом и используйте переопределения OnInitialized и Dispose
AppHeader.razor.cs
public class AppHeaderBase : OwningComponentBase
{
// OnStatusChanged method as described above
protected override void OnInitialized() //Can use the Async version as well
{
// Unsubscribe once to make sure you are only connected once
// Prevents event propogation
// If this component is not subscribed this doesn't do anything
state.StatusHandler -= onStatusChanged;
// Subscribe to the event
state.StatusHandler += onStatusChanged;
}
protected override void Dispose(bool disposing)
{
// Unsubscribe on teardown, prevent event propogation and memory leaks
state.StatusHandler -= onStatusChanged;
}
}
В этом используются некоторые встроенные функции Blazor в OwningComponentBase
и включает метод Dispose
, в то же время выполняя намного лучшую работу по управлению инъекцией зависимостей для вас.
Дополнительная информация ЗДЕСЬ (Обратите внимание, что я не go слишком глубоко для этого примера, так как он использует синглтон, но стоит прочитать, чтобы понять время жизни DI в Blazor)
А потом в вашем AppHeader.razor
....
@inherits AppHeaderBase
....
Теперь, когда вы используете обработчик событий в StateService
откуда-то еще, создайте новый тип PatientEventArgs
со значениями, которые необходимо передать:
var newArgs = new PatientEventArgs(){
PatientName = "SomeName",
StatusValue = "SomeStatus"
};
И передайте его по мере необходимости в вашем коде:
state.OnStatusChanged(this, newArgs);
Или прямо из синтаксиса Razor:
<button @onclick="@(() => state.OnStatusChanged(this, new PatientEventArgs(){ PatientName = "SomeName", StatusValue = "SomeStatus"})">Sender Button</button>
Это должно обеспечить многоадресную передачу вашего события по мере необходимости, и все подписчики должны забрать его и обновить.
Вот быстро работающий дем o при необходимости , адаптированный из другой версии, над которой я работал.