问题
EDIT: I don't want it to update, change or go away. I ONLY want the taskbar to be at 40% to start the program, stay that way till it closes.
I spent a lot of hours and tried many examples...but no luck.
To keep it simple, how do you show 40% done in Error color?
This code runs but does nothing on the screen, no errors, just runs right by:
public TaskbarItemInfo taskBar = new TaskbarItemInfo();
then in a method:
taskBar.ProgressState = System.Windows.Shell.TaskbarItemProgressState.Error;
taskBar.ProgressValue = 0.40;
If you breakpoint on the next line and look, it has set the values, they just don't do anything on the screen...
回答1:
Here's a short example that you should be able to use to tailor to your needs:
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);
回答2:
TaskbarItemInfo
doesn't do anything by itself. It needs a window which is represented on the taskbar. Note that one normally gets an instance of TaskbarItemInfo
from an instance of a WPF Window
. I.e. that class is intended for use in WPF programs, not Winforms.
For a Winforms program, you may find it is more practical to use the Windows API Codepack, which if I recall correctly has support for this Shell feature.
You can use the TaskbarManager
class in WindowsAPICodePack.Taskbar
to set the Form Window's task bar progress like this:
using Microsoft.WindowsAPICodePack.Taskbar;
...
private void Form1_Load(object sender, EventArgs e)
{
TaskbarManager.Instance.SetProgressState(TaskbarProgressBarState.Error, Handle);
TaskbarManager.Instance.SetProgressValue(40, 100, Handle);
}
Using the current Form's .Handle
to tell the manager to which window this feature should be provided. You can use a public static pointer reference from another form, too, if you wish to handle its progress in the same place.
Unfortunately, for some reason Microsoft is no longer hosting a download for this, in spite of the continued relevance for the library. But here is a StackOverflow Q&A with numerous other links for the same library: Windows API Code Pack: Where is it?. Note that there are two versions, 1.0 and 1.1. In general, you will likely prefer the 1.1 version; it has numerous bug fixes, added features, and much better Fxcop compliance. The link I've provided is for 1.1, but there are links for downloading 1.0 on that SO article as well.
回答3:
I have done this by creating a separate thread from you main frame thread to execute the code that sends out the progress update, where you can call setProgress on your progress bar, but you must create a delegate method otherwise you will get a runtime exception that your thread is accessing a control on the main thread, here is what i would do,
declare a delegate method in your the class were you have the progress bar,
public delegate void SetProgressDelg(int level);
Then implement this method to update your progress bar,
public void SetProgress(int level)
{
if (this.InvokeRequired)
{
SetProgressDelg dlg = new SetProgressDelg(this.SetProgress);
this.Invoke(dlg, level);
return;
}
progressBar.Value = level;
}
hope this works for, I use this in several applications and it works great.
Here is how you build the progress bar,
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);
then you want to add the toolStripContainer to you controls of the main panel.
you want to call SetProgress from the thread that is processing your task, here is how you start a thread,
//* 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
}
Let me know if you need something else, hope this helps,
来源:https://stackoverflow.com/questions/28391165/how-do-you-show-progress-in-the-taskbar-with-winform-c-sharp-4-5