使用WinForms. NET 8表单中的BlazorWebView控件(introduction),我确实显示了这个"Counter. razour"文件:
<p><button @onclick="IncrementCount">Increment counter</button></p>
<p>@_counterValue</p>
@code
{
private int _counterValue = 0;
private void IncrementCount()
{
_counterValue++;
}
}
正确行为
上面的代码很完美:
- 用户点击按钮.
- 变量递增.
- 页面显示新的变量值.
不正确的行为
现在我把IncrementCount()
方法改为这样:
private void IncrementCount()
{
Synchronization上下文.Current!.Post(
delegate
{
_counterValue++;
},
null);
}
现在它的行为像这样:
- 用户点击按钮.
- 变量递增(现在为"1").
- 页面仍显示"0".
- 用户再次点击按钮.
- 变量再次递增.(现在是"2").
- 页面显示"1".
- 等
也就是说,我总是会有一个错误.
修复它
为了解决这个问题,我必须将代码更改为:
private void IncrementCount()
{
Synchronization上下文.Current!.Post(
delegate
{
_counterValue++;
StateHasChanged();
},
null);
}
现在,在添加一个对StateHasChanged()
的调用之后,它的行为就像预期的那样:
- 用户点击按钮.
- 变量递增.
- 页面显示新的变量值.
上下文
以上Synchronization上下文
的用法是一个最小的例子,我必须通过这个机制分派调用(主要是因为I have to call other WinForms dialogs).
我确实想理解为什么需要调用"StateHasChanged",因为我想避免它.
在我的实际应用程序中(不是上面最小的例子),这将迫使大量的重新渲染以适合应用程序.
我的问题
有人能解释一下为什么我直接改变变量和改变它通过Synchronization上下文
的行为不同吗?
有没有改变,使它工作,没有额外的呼叫StateHasChanged()
?
更新1
在我的现实应用程序中,我大致执行以下步骤:
- 用户单击Blazor按钮.
- 显示了WinForms表单.
- 关闭表单后,我必须更新Blazor中的一些值.
所以这就是我在Synchronization上下文.Current!.Post()
调用中执行代码的原因,建议here.
我还try 将代码放入队列中,并在WinForms应用程序的Application.Idle
事件处理程序中处理此队列,但其行为是一样的(off—by—one错误).