+-
如何用Winform C# 4.5在任务栏中显示进度?

EDIT: 我不想让它更新、改变或消失。 I 仅限 希望任务栏在40%的位置启动程序,并保持这种方式,直到它关闭。

我花了很多时间,尝试了很多例子......但没有成功。

为了简单起见,如何用Error颜色显示40%完成?

这段代码运行,但在屏幕上什么都不做,没有错误,只是直接运行。

public TaskbarItemInfo taskBar = new TaskbarItemInfo();

然后在一个方法中运行

taskBar.ProgressState = System.Windows.Shell.TaskbarItemProgressState.Error;
taskBar.ProgressValue = 0.40;

如果你在下一行的断点处看一下,它已经设置了值,它们只是... ... 不要 在屏幕上做任何事情...

5
投票

这里有一个简短的例子,你应该可以根据你的需求来定制。

    System.Windows.Window w = new System.Windows.Window();
    w.TaskbarItemInfo = new System.Windows.Shell.TaskbarItemInfo() { ProgressState = System.Windows.Shell.TaskbarItemProgressState.Normal };
    w.Loaded += delegate {
        Action<Object> callUpdateProgress = (o) => {
            w.TaskbarItemInfo.ProgressValue = (double) o;
        };

        Thread t = new Thread(() => {
            for (int i = 1; i <= 10; i++) {
                w.Dispatcher.BeginInvoke(callUpdateProgress, 1.0 * i / 10);
                Thread.Sleep(1000);
            }
        });
        t.Start();
    };

    System.Windows.Application app = new System.Windows.Application();
    app.Run(w);
7
投票

TaskbarItemInfo 它本身不做任何事情 它需要一个在任务栏上表示的窗口。请注意,通常我们会得到一个 TaskbarItemInfo 从一个WPF Window. 即该类是为了在WPF程序中使用,而不是Winforms。

对于Winforms程序来说,您可能会发现使用 Windows API代码包如果我没记错的话,它已经支持这个Shell功能。

你可以使用 TaskbarManager 阶层 WindowsAPICodePack.Taskbar 来设置表单窗口的任务栏进度,就像这样。

using Microsoft.WindowsAPICodePack.Taskbar;
...
private void Form1_Load(object sender, EventArgs e)
{
    TaskbarManager.Instance.SetProgressState(TaskbarProgressBarState.Error, Handle);
    TaskbarManager.Instance.SetProgressValue(40, 100, Handle);
}

使用当前表格的 .Handle 来告诉管理器这个功能应该提供给哪个窗口。如果你希望在同一个地方处理它的进度,你也可以使用另一个窗体的公共静态指针引用。

遗憾的是,由于某些原因,微软不再为其提供下载,尽管该库仍然具有相关性。但这里有一个乐贴网 Q&A,其中有许多其他的链接,用于同一个库。Windows API代码包 它在哪里?. 请注意,有两个版本,1.0和1.1。一般来说,你可能会更喜欢1.1版本;它有许多错误修正,增加了一些功能,并且符合Fxcop的要求。我提供的链接是1.1版本的,但在SO文章中也有下载1.0版本的链接。

1
投票

我的做法是,从你的主框架线程中创建一个单独的线程来执行发送进度更新的代码,在这里你可以在你的进度条上调用setProgress,但是你必须创建一个委托方法,否则你会得到一个运行时异常,即你的线程正在访问主线程上的一个控件,下面是我会做的。

在你有进度条的类中声明一个委托方法。

public delegate void SetProgressDelg(int level);

然后实现这个方法来更新你的进度条。

public void SetProgress(int level)
{
      if (this.InvokeRequired)
      {
        SetProgressDelg dlg = new SetProgressDelg(this.SetProgress);
        this.Invoke(dlg, level);
        return;
      } 
      progressBar.Value = level;
}

希望这个工作,我在几个应用程序中使用这个,它的工作原理。

下面是如何建立进度条。

 ToolStripContainer  = toolStripContainer1 = new System.Windows.Forms.ToolStripContainer();
 // StatusBar
 // 
 ToolStripStatusLabel StatusBar = new System.Windows.Forms.ToolStripStatusLabel();
 StatusBar.DisplayStyle = System.Windows.Forms.ToolStripItemDisplayStyle.Text;
 StatusBar.ForeColor = System.Drawing.Color.Blue;
 StatusBar.LinkColor = System.Drawing.Color.Navy;
 StatusBar.Name = "StatusBar";
 StatusBar.Size = new System.Drawing.Size(732, 20);
 StatusBar.Spring = true;
 StatusBar.Text = "Status Messages Go Here";
 StatusBar.TextAlign = System.Drawing.ContentAlignment.MiddleLeft;
 // 
 // ProgressBar
 // 
 ToolStripProgressBar ProgressBar = new System.Windows.Forms.ToolStripProgressBar();
 ProgressBar.ForeColor = System.Drawing.Color.Yellow;
 ProgressBar.Name = "ProgressBar";
 ProgressBar.Size = new System.Drawing.Size(150, 19);


 // 
 // StatusStrip
 // 
 StatusStrip StatusStrip = new System.Windows.Forms.StatusStrip();
 StatusStrip.Dock = System.Windows.Forms.DockStyle.None;
 StatusStrip.Items.AddRange(new System.Windows.Forms.ToolStripItem[] {
 StatusBar, this.ProgressBar});
 StatusStrip.Location = new System.Drawing.Point(0, 0);
 StatusStrip.Name = "StatusStrip";
 StatusStrip.Size = new System.Drawing.Size(899, 25);
 StatusStrip.TabIndex = 0;

 toolStripContainer1.BottomToolStripPanel.Controls.Add(this.StatusStrip);

然后你想把工具条容器添加到主面板的控件中。

你想从正在处理任务的线程中调用SetProgress,以下是启动线程的方法。

 //* from your class of your main frame
   //* this is where SetStatus is defined
   //* start a thread to process whatever task 
   //* is being done

   Thread t  = new Thread(StartProc);
   t.Start();


   public void StartProc()
   {
      //* start processing something, 
      //*let's assume your are processing a bunch of files
      List<string> fileNames;
      for (int i = 0; i < fileNames.Count; i++)
      {
         //* process file here
         //* ...........

         //* then update progress bar
         SetProgress((int)((i + 1) * 100 / fileNames.Length));
      }

      //* thread will exit here
    }

如果你还需要什么,请告诉我,希望对你有所帮助。

0
投票

尝试。

Microsoft.WindowsAPICodePack.Taskbar.TaskbarManager.Instance.SetProgressState(Microsoft.WindowsAPICodePack.Taskbar.TaskbarProgressBarState.NoProgress);
Microsoft.WindowsAPICodePack.Taskbar.TaskbarManager.Instance.SetProgressValue(ActualValue, MaxValue));