Silverlight 确认暂停线程的对话框

发布于 2024-08-18 13:02:43 字数 1408 浏览 10 评论 0原文

我正在尝试使用 Silverlight 的 ChildWindow 对象执行确认对话框。

理想情况下,我希望它像 MessageBox.Show() 一样工作,整个应用程序将暂停,直到收到用户的输入。

例如:

for (int i = 0; i < 5; i++)
{
    if (i==3 && MessageBox.Show("Exit early?",
        "Iterator", MessageBoxButton.OKCancel) == MessageBoxResult.OK)
    {
        break;
    }
}

如果用户点击“确定”,则会在 3 处停止迭代...

但是,如果我要按照以下方式执行某些操作:

ChildWindow confirm = new ChildWindow();
confirm.Title = "Iterator";
confirm.HasCloseButton = false;
Grid container = new Grid();

Button closeBtn = new Button();
closeBtn.Content = "Exit early";
closeBtn.Click += delegate { confirm.DialogResult = true; confirm.Close(); };
container.Children.Add(closeBtn);

Button continueBtn = new Button();
continueBtn.Content = "Continue!";
continueBtn.Click += delegate { confirm.DialogResult = false; confirm.Close(); };
container.Children.Add(continueBtn);

confirm.Content = container;

for(int i=0;i<5;i++) {
  if (i==3) {
    confirm.Show();
    if (confirm.DialogResult.HasResult && (bool)confirm.DialogResult) {
      break;
    }
  }
}

这显然行不通,因为线程不会停止... 确认。 DialogResult.HasResult 将为 false,并且循环将继续经过 3。

我只是想知道,我如何才能正确地处理这个问题。 Silverlight是单线程的,所以我不能只是让线程休眠,然后在准备好时唤醒它,所以我只是想知道人们是否还有其他可以推荐的东西?

我考虑过反转逻辑 - 即,将我想要发生的操作传递给“是/否”事件,但在我的具体情况下,这不太有效。

提前致谢!

I'm trying to do a confirmation dialog using Silverlight's ChildWindow object.

Ideally, I'd like it to work like MessageBox.Show(), where the entire application halts until an input is received from the user.

For example:

for (int i = 0; i < 5; i++)
{
    if (i==3 && MessageBox.Show("Exit early?",
        "Iterator", MessageBoxButton.OKCancel) == MessageBoxResult.OK)
    {
        break;
    }
}

Would stop the iteration at 3 if the user hits OK...

However, if I were to do something along the lines:

ChildWindow confirm = new ChildWindow();
confirm.Title = "Iterator";
confirm.HasCloseButton = false;
Grid container = new Grid();

Button closeBtn = new Button();
closeBtn.Content = "Exit early";
closeBtn.Click += delegate { confirm.DialogResult = true; confirm.Close(); };
container.Children.Add(closeBtn);

Button continueBtn = new Button();
continueBtn.Content = "Continue!";
continueBtn.Click += delegate { confirm.DialogResult = false; confirm.Close(); };
container.Children.Add(continueBtn);

confirm.Content = container;

for(int i=0;i<5;i++) {
  if (i==3) {
    confirm.Show();
    if (confirm.DialogResult.HasResult && (bool)confirm.DialogResult) {
      break;
    }
  }
}

This clearly would not work, as the thread isn't halted... confirm.DialogResult.HasResult would be false, and the loop would continue past 3.

I'm just wondering, how I could go about this properly. Silverlight is single-threaded, so I can't just put the thread to sleep and then wake it up when I'm ready, so I'm just wondering if there's anything else that people could recommend?

I've considered reversing the logic - ie, passing the actions I want to occur to the Yes/No events, but in my specific case this wouldn't quite work.

Thanks in advance!

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

优雅的叶子 2024-08-25 13:02:43

我认为您无法像使用 WinForms 的 ShowDialog 那样在消息循环中阻止代码。

但是,您可以滥用迭代器来达到相同的效果:

interface IAction { void Execute(Action callback); }

public static void ExecAction(IEnumerator<IAction> enumerator) {
    if (enumerator.MoveNext())
        enumerator.Current.Execute(() => ExecAction(enumerator));
}

class DialogAction : ChildWindow, IAction {
    void IAction.Execute(Action callback) {
       //Show the window, then call callback when it's closed
    }
}

IEnumerator<IAction> YourMethod() { 
    ...
    var confirm = new DialogAction();
    yield return confirm;
    if (confirm.DialogResult.HasResult && (bool)confirm.DialogResult)
        yield break;
    ...
}

要使用此系统,您可以编写 ExecAction(YourMethod());。请注意,这将是一个半阻塞调用,并且我根本没有对此进行测试。

C#5 的新 async 功能的工作方式完全相同(事实上,async 编译器代码的初始版本在很大程度上基于现有的迭代器实现),但具有更好的功能句法支持。

I don't think you'll be able to block your code in a message loop the way you can with WinForms' ShowDialog.

However, you can misuse iterators to achieve the same effect:

interface IAction { void Execute(Action callback); }

public static void ExecAction(IEnumerator<IAction> enumerator) {
    if (enumerator.MoveNext())
        enumerator.Current.Execute(() => ExecAction(enumerator));
}

class DialogAction : ChildWindow, IAction {
    void IAction.Execute(Action callback) {
       //Show the window, then call callback when it's closed
    }
}

IEnumerator<IAction> YourMethod() { 
    ...
    var confirm = new DialogAction();
    yield return confirm;
    if (confirm.DialogResult.HasResult && (bool)confirm.DialogResult)
        yield break;
    ...
}

To use this system, you would write ExecAction(YourMethod());. Note that this would be a semi-blocking call, and that I haven't tested this at all.

C#5's new async features work exactly the same way (in fact, the initial versions of the async compiler code were heavily based on the existing iterator implementation), but with nicer syntactic support.

↙温凉少女 2024-08-25 13:02:43

您可以使用RX Framework轻松实现这种安静:

var continued = Observable.FromEvent<RoutedEventArgs>(continueBtn, "Click");

var iter = new Subject<int>();

var ask = iter.Where(i => i == 3).Do(_ => confirm.Show());

iter.Where(i => i != 3 && i < 10)
    .Merge(ask.Zip(continued, (i, _) => i))
    .Do(i => Debug.WriteLine("Do something for iteration {0}", i))
    .Select(i => i + 1)
    .Subscribe(iter);

iter.OnNext(0);

该解决方案可以轻松扩展对于确定何时显示对话框的任何规则。例如,假设我们想要阻止迭代并每 3 次迭代请求用户确认。您所要做的就是将条件 i == 3 替换为 i % 3 == 0 (并将 i != 3 替换为 >i%3!=0)。

You can achieve this quiet easily with RX Framework:

var continued = Observable.FromEvent<RoutedEventArgs>(continueBtn, "Click");

var iter = new Subject<int>();

var ask = iter.Where(i => i == 3).Do(_ => confirm.Show());

iter.Where(i => i != 3 && i < 10)
    .Merge(ask.Zip(continued, (i, _) => i))
    .Do(i => Debug.WriteLine("Do something for iteration {0}", i))
    .Select(i => i + 1)
    .Subscribe(iter);

iter.OnNext(0);

The solution easily scales for any rule determining when to show a dialog. E.g. suppose we want to block the iteration and request user confirmation every 3 iterations. All you have to do is to replace condition i == 3 with i % 3 == 0 (and i != 3 with i % 3 != 0).

香橙ぽ 2024-08-25 13:02:43

查看此项目 http://silverlightmsgbox.codeplex.com/。它提供了几个有用的消息框(即确认、错误、信息、用户输入等)的简单但美观的实现,可能对您有所帮助。祝你好运。

Check out this project http://silverlightmsgbox.codeplex.com/. It presents a simple but presentable implementation of several useful message boxes i.e. confirm, error, info, user input, etc. and might be helpful to you. Good luck.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文