我尝试编写一个代码来读取JSON文件,并允许用户在JSON文件中逐个输入对象的所有参数。
我试着写一个类似于“等待按钮”的东西,但是我没有为按钮写一个“GetAwaiter”扩展,尽管我找到了关于如何做的信息。
https://learn.microsoft.com/en-us/dotnet/desktop/winforms/controls/how-to-inherit-from-existing-windows-forms-controls?view=netframeworkdesktop-4.8
how can I combine await.WhenAny() with GetAwaiter extension method
http://blog.roboblob.com/2014/10/23/awaiting-for-that-button-click/
下面是我点击按钮“loadJSON”后的代码:
for (int i = 0; i<templist_net.Count; i++)
{
GeneratorFunctions.GetNetworkParameterList(templist_net[i].Type, templist_net[i], treeViewPath.SelectedPath, SolutionFolder);
cBoxPouItem.Text = templist_net[i].Type;
ListViewParam2.ItemsSource = GeneratorFunctions.TempList; // Parameter list binding
temp = GeneratorFunctions.TempList;
ListViewParam2.Visibility = Visibility.Visible; // Set list 2 visible
ListViewParam.Visibility = Visibility.Collapsed; // Set list 1 invisible
//something stop loop, and wait user to type parameters in Listview, and click Button, Then the loop move on.
}
下面是尝试编写一个带扩展的Button的代码。我为自定义控件添加了一个新类,并编写了扩展。
public partial class CustomControl2 : System.Windows.Forms.Button
{
static CustomControl2()
{
}
public static TaskAwaiter GetAwaiter(this Button self)
{
ArgumentNullException.ThrowIfNull(self);
TaskCompletionSource tcs = new();
self.Click += OnClick;
return tcs.Task.GetAwaiter();
void OnClick(object sender, EventArgs args)
{
self.Click -= OnClick;
tcs.SetResult();
}
}
}
但是我不能写一个继承System.Windows.Forms.Button的扩展,我该怎么办?
更新:以下是我尝试过的。
private async Task Btn_loadJsonAsync(object sender, RoutedEventArgs e) {
// Initialize an open file dialog, whose filter has a extend name ".json"
OpenFileDialog openFileDialog = new OpenFileDialog();
openFileDialog.Filter = "(*.json)|*.json";
TextBoxInformation.Text += "Opening project ...\n";
if (openFileDialog.ShowDialog() == System.Windows.Forms.DialogResult.OK)
{
networks = GeneratorFunctions.ReadjsonNetwork(openFileDialog.FileName);
for (int i = 0; i < networks.Count; i++)
{
if (temp != null)
{
if (networks[i].Type == "Network")
{
templist_net.Add(networks[i]);
i = 1;
}
if (networks[i].Type == "Subsystem")
{
templist_sub.Add(networks[i]);
i = 1;
}
if (networks[i].Type == "Component: Data Point Based Control")
{
templist_com.Add(networks[i]);
i = 1;
}
}
}
using (SemaphoreSlim semaphore = new SemaphoreSlim(0, 1))
{
void OnClick(object sender, RoutedEventArgs e) => semaphore.Release();
btn.Click += OnClick;
for (int i = 0; i < templist_net.Count; i++)
{
//...
//wait here until [btn] is clicked...
await semaphore.WaitAsync();
}
btn.Click -= OnClick;
}}}
3条答案
按热度按时间sdnqo3pr1#
虽然你可能想重新设计你做事的方式,一个快速的解决方案是在模态模式下使用一个对话框,在对话框关闭时,捕获输入的数据并继续循环。循环将一直阻塞,直到对话框关闭。
liwlm1x92#
您可以使用
SemaphoreSlim
异步等待按钮单击,例如:khbbv19g3#
首先,我必须坚持你的请求违背了基于事件的MVVM模式的原则。
您的逻辑应该在一个单独的类中,并公开一个
OnNext
方法,该方法应该通过ActionCommand
从模型中调用无论如何,为了(尽可能地)符合MVVM模式,您不希望在按钮上使用
await
,而希望在绑定到按钮的命令上使用更多。因此,让我们构建一个可等待的命令:
然后你可以用它来创建你的逻辑(我把它放在模型里,这是一个不好的做法):
而你的看法:
可用的工作演示here。