0

我有一个带有一些工具提示按钮的应用程序。其中一个按钮(以下称为“运行”按钮)在按下时开始在我的应用程序之外触发进程。因为我的应用程序需要从这些进程的输出中获取数据,所以我让它暂停,直到所有进程完成运行,然后在没有用户进一步干预的情况下获取数据。当然,这意味着我的应用程序在外部进程运行时挂起,但这没什么大不了的,因为用户可以点击离开并处理我的应用程序之外的其他内容;我的申请落到了后台。不幸的是,与“运行”按钮相关的工具提示不会落到后台,并且在我的代码停止执行之前它不会消失。

以下代码略有帮助:

private void RunButton_Click(object sender, RoutedEventArgs e)
{
    /*Gets the tooltip out of the way while running, otherwise it will stay in front of   everything until the optimizers finish.*/
    ToolTipService.SetShowDuration(runButton, 0);
    RunTooltip.IsOpen = false;//Doesn't close fast enough. It fades a little then hangs there until the code stop running. googling has been remarkably unhelpful.
    Run();
    ToolTipService.SetShowDuration(runButton, 5000);
}

RunTooltip 是相关工具提示的名称。将持续时间设置为 0 或将 isOpen 设置为 false 具有相同的行为:导致工具提示变为半透明(但无论如何仍高于其他窗口),直到 Run() 完成。

似乎有一种方法可以使用 Windows.Forms.Tooltips 立即发生工具提示褪色(请参阅http://msdn.microsoft.com/en-us/library/system.windows.forms.tooltip.usefading.aspx)但是WPF 工具提示似乎不再是这种情况(http://msdn.microsoft.com/en-us/library/ms617634.aspx)

除了完全删除此按钮的工具提示之外,如何防止此工具提示妨碍用户在等待我的应用程序完成时想做的任何事情?谢谢

4

3 回答 3

1

可以使用 BackgroundWorker,然后在 CallBack 上加载 UI。

BackgroundWorker 类

如果要报告进度链接过程 X 的 Y 可以使用 ReportsProgress。你可以取消。

于 2012-09-26T22:56:35.600 回答
0

如果我错了,请纠正我,因为我可能会误解你,但听起来你正在处理 UI 的线程中做一些计算上昂贵的东西。这个问题的一个更简单的解决方案可能是创建一个工作线程,如下所示:

    private void button1_Click(object sender, EventArgs e)
    {
        Thread workerThread = new Thread(ExpensiveMethod);
        btnShow.Visible = false;
        workerThread.Start();
    }

    private void ExpensiveMethod()
    {
        for (int i = 0; i < int.MaxValue; i++)
        {

        }

        btnShow.Visible = true;
    }

这意味着处理 UI(以及工具提示)的线程可以正常进行,而工作线程正在处理计算量大的东西。

如果我误解了你,请告诉我!

于 2012-09-26T22:59:32.823 回答
0

您可能会在 OnClicked 事件中更改 ToolTip 的 Popup 组件的可见性,但您必须使用 VisualTreeHelper 才能找到 ToolTip,这有点混乱。UI 仍将被冻结,这不是执行此操作的最佳方式。

这里有一条经验法则:如果你冻结了 UI,那你就做错了。

您可能需要一个繁忙的指示器来包装您的控件(codeplex 上的 WPF 工具包中有一个很棒的指示器)。WPF 使用 MVVM 模式效果最好(即最干净),但如果您直接在代码隐藏中工作,则如下所示:

void MyButton_Click(object sender, EventArgs e)
{
    var backgroundThread = new Thread(DoWork);
    this.MyBusyIndicator.IsBusy = true;
    backgroundThread.Start();
}

然后在工作完成后,将 BusyIndi​​cator 设置为不再忙碌。

于 2012-09-26T23:33:41.493 回答