【问题标题】:Notify main thread when button is clicked单击按钮时通知主线程
【发布时间】:2013-01-09 10:51:33
【问题描述】:

我正在尝试创建一个这样的弹出窗口

// Create a Popup
var Pop = new Popup() { IsOpen = true };

// Create a StackPanel for the Buttons
var SPanel = new StackPanel() { Background = MainGrid.Background };

// Set the comment
var TxtBlockComment = new TextBlock { Margin = new Thickness(20, 5, 20, 5), Text = Obj.Comment };

// Set the value
var TxtBoxValue = new TextBox { Name = "MeasureValue" };
TxtBoxValue.KeyUp += (sender, e) => { VerifyKeyUp(sender, Measure); };

// Create the button
var ButtonFill = new Button { Content = Loader.GetString("ButtonAccept"), Margin = new Thickness(20, 5, 20, 5), Style = (Style)App.Current.Resources["TextButtonStyle"] };
ButtonFill.Click += (sender, e) => { Obj.Value = TxtBoxValue.Text; };

// Add the items to the StackPanel
SPanel.Children.Add(TxtBlockComment);
SPanel.Children.Add(TxtBoxValue);
SPanel.Children.Add(ButtonFill);

// Set the child on the popup
Pop.Child = SPanel;

我想在ButtonFill.Click事件执行后通知主线程,这样我就可以继续那个线程了

但是我该怎么做呢?

【问题讨论】:

  • 您可以尝试使用AutoResetEvent,msdn.microsoft.com/en-us/library/…
  • 你的意思是 ButtonFill.Clicked 事件吗?
  • 不清楚应该通知主线程的另一个线程在哪里。从您发布的代码看起来它是单线程的。
  • 是的,我的意思是 ButtonFill.Click 事件 ;)
  • @Kimi 我的意思是如何在方法中通知 Click 事件已被抛出?

标签: c# windows-runtime .net-4.5


【解决方案1】:

我假设您要问的是如何实现类似于FileOpenPicker.PickSingleFileAsync 的对话框行为。您可以使用TaskCompletionSource 创建等待任务:

private Task<string> OpenPopupAsync()
{
    var taskSource = new TaskCompletionSource<string>();

    // Create a Popup
    var Pop = new Popup() { IsOpen = true };

    // Create a StackPanel for the Buttons
    var SPanel = new StackPanel() { Background = MainGrid.Background };

    // Set the comment
    var TxtBlockComment = new TextBlock { Margin = new Thickness(20, 5, 20, 5), Text = Obj.Comment };

    // Set the value
    var TxtBoxValue = new TextBox { Name = "MeasureValue" };
    TxtBoxValue.KeyUp += (sender, e) => { VerifyKeyUp(sender, Measure); };

    // Create the button
    var ButtonFill = new Button { Content = Loader.GetString("ButtonAccept"), Margin = new Thickness(20, 5, 20, 5), Style = (Style)App.Current.Resources["TextButtonStyle"] };
    ButtonFill.Click += (sender, e) => { Pop.IsOpen = false; taskSource.SetResult(TxtBoxValue.Text); };

    // Add the items to the StackPanel
    SPanel.Children.Add(TxtBlockComment);
    SPanel.Children.Add(TxtBoxValue);
    SPanel.Children.Add(ButtonFill);

    // Set the child on the popup
    Pop.Child = SPanel;

    return taskSource.Task;
}

简而言之:

  • 您创建了一个TaskCompletionSource 的实例
  • 您将其Task 属性作为等待任务返回
  • 当你想让调用方法继续时,你调用SetResult

在调用方法中,您只需 await 让方法在继续执行之前返回:

string result = await OpenPopupAsync();
// continue execution after the method returns

我还建议您查看Callisto's Flyout 控件,以更简单地实现弹出窗口。

【讨论】:

  • 这正是我想要的
【解决方案2】:

在类和事件的开头放置一个布尔属性,将该布尔属性设置为 true。

ButtonFill.Click += (sender, e) => { ButtonClicked = true; Obj.Value = TxtBoxValue.Text; };

【讨论】:

  • 如我所见,我需要使用 while 循环来检查值
  • @The87Boy 我的观点来自 MVVM,其中布尔值将通过 INotifyPropertyChanged 方法来宣布(可以这么说)。任何绑定到布尔值的项目都会收到通知。我猜你没有 INotifyPropertyChanged。如果您正在从主线程运行某些东西,那么是的,您需要等待,并且可能需要 Thread.Sleep 等待更改。
  • 哦,那我想我需要调用另一个方法
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2016-10-26
  • 2014-07-22
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多