dotnet / winforms

Windows Forms is a .NET UI framework for building Windows desktop applications.
MIT License
4.41k stars 984 forks source link

Support Progress on Task Bar Entries #3851

Open nikeee opened 4 years ago

nikeee commented 4 years ago

I'm currently migrating some of the stuff that was handled by the WindowsAPICodePack to use WinForms APIs (like the new TaskDialog and the new FolderBrowserDialog). As described in #181, individual issues should be opened for feature requests.

The WindowsAPICodePack had this API to set the progress of the window in the task bar:

TaskbarManager.Instance.SetProgressValue(value, maximum, windowHandle)

It also supported different states like Indeterminate:

TaskbarManager.Instance.SetProgressState(TaskbarProgressBarState.Indeterminate)
// Defined as:
public enum TaskbarProgressBarState
{
    NoProgress = 0,
    Indeterminate = 1,
    Normal = 2,
    Error = 4,
    Paused = 8,
}

The result looks like in this article: Screenshot from Code project

Will this feature affect UI controls? Yes

Keywords:

RussKie commented 4 years ago

TaskbarManager isn't part of Windows Forms API. It is certainly something can be considered for an addition, but we'll need a fully fledged API proposal. Here's a list of proposals that have been accepted: https://github.com/dotnet/winforms/issues?q=label%3Aapi-approved

weltkante commented 4 years ago

WPF has an API for this already, I think the references are already included in .NET Core projects and you can just use it?

(Once WPF and WinForms can be deployed separately it may make sense to have a WinForms-only version of the API, but as far as I'm aware in current deployment scenarios WPF and WinForms are always deployed together.)

nikeee commented 4 years ago

Summary

Currently, Winforms does not offer an API to set the progress of a taskbar entry. @weltkante poited out that WPF already has a API for that. We try to add this capability to Winforms with this proposal.

Rationale

In the past, developers had to use the WindowsAPICodePack's API for that. That API basically vanished from the internet and there are a lot of people trying to bring its APIs back to developers. While WPF got first-class support for some of that APIs, Winforms is still missing a lot of them.

Proposed API

It may be appropriate to offer a similar API surface like WPF. That API surface differs significantly from the original WindowsAPICodePack's API surface. We can implement it as a property TaskbarItemInfo on a windows Form similar to how WPF does it on its Window class:

namespace System.Windows.Forms {
    class Form {
        // ...
        public TaskbarItemInfo TaskbarItemInfo { get; }
        // ...
    }

    public class TaskbarItemInfo {
        public TaskbarItemProgressState ProgressState { get; set; }
        public double ProgressValue { get; set; }
    }

    public enum TaskbarItemProgressState
    {
        NoProgress = 0,
        Indeterminate = 1,
        Normal = 2,
        Error = 4,
        Paused = 8,
    }
}

Class Description

The semantics of the classes are equivalent to the ones of WPF. If the OS does not support the feature (all platforms below Windows 7), it should not result in an exception (this behaviour differs from the WindowsAPICodePack). Instead, we just do nothing.

The ProgressValue is clamped to [0, 1] while NaN is coerced to 0.

Future Entries into TaskbarItemInfo

TaskbarItemInfo could also be the home for more taskbar-related APIs like an overlay icon or thumbnail buttons. The WPF API already supports these features.

Examples

Simple Progress State

public partial class SomeForm : Form
{
    public SomeForm()
    {
        InitializeComponent();
        this.TaskbarItemInfo.ProgressState = TaskbarItemProgressState.Normal;
        this.TaskbarItemInfo.ProgressValue = 0.5;
    }
    void button1_click()
    {
        this.TaskbarItemInfo.ProgressValue += 0.1;
    }
}

Different Progress states

public partial class SomeForm : Form
{
    public SomeForm()
    {
        InitializeComponent();
        this.TaskbarItemInfo.ProgressState = TaskbarItemProgressState.Normal;
    }
    void button1_click()
    {
        this.TaskbarItemInfo.ProgressState = TaskbarItemProgressState.Error;
    }
}
kpreisser commented 4 years ago

I think this might also be a nice gimmick for a (modal) Task Dialog, e.g. when using progress bars: TaskDialog-TaskBar

Or when using the colored icon bars: TaskDialog-TaskBar2

merriemcgaw commented 4 years ago

This is a great feature suggestion, thanks so much! We'll put it on the backlog and do a holistic investigation of what else we might want out of the WindowsAPICodePack.

merriemcgaw commented 4 years ago

@OliaG getting this on your radar for future discussion.

bkqc commented 3 years ago

Is there any time frame to expect this feature to be integrated in Microsoft.Windows.SDK.Contracts? To be totally honest, when I read that this package was supposed to allow .NET 4.6 to access Windows Runtime APIs, I understood everything from WindowsAPICodePack would have migrated to it... Is there actually any right way to access this feature in a Winform application without having to move back to the dead WindowsAPICodePack dlls?

RussKie commented 3 years ago

@bkqc I'm not sure what you're asking for. Windows Forms has no relation Microsoft.Windows.SDK.Contracts, which contains WinRT API.

ghost commented 2 years ago

Yes, WPF not only implements a progress bar, but also implements other features.

wpfshell-taskbariteminfo

TaskbarItemInfo.ThumbButtonInfos https://docs.microsoft.com/en-us/dotnet/api/system.windows.shell.taskbariteminfo.thumbbuttoninfos

TaskbarItemInfo.Overlay https://docs.microsoft.com/en-us/dotnet/api/system.windows.shell.taskbariteminfo.overlay

ahdung commented 2 years ago

Any news?

0xced commented 1 year ago

Any chance this gets addressed in .NET 8 ?

Also what does the champion-required label mean? Unlike the good first issue and help wanted labels, the champion-required is not explained in the CONTRIBUTING.md document.

JeremyKuhne commented 1 year ago

Sorry about the delay on this. We've been resource constrained this year, @lonitra is going to champion this for .NET 9.

The "champion" is someone on our internal team that is following up on the issue and making sure it has traction. :)

willibrandon commented 11 months ago

I think users would appreciate being able to see the progress of a long-running task just by taking a quick glance at the taskbar.

willibrandon commented 11 months ago

@lonitra - If you could use any assistance with this issue, please let me know and I would be happy to help.

willibrandon commented 11 months ago

https://github.com/dotnet/winforms/assets/5017479/a356302b-05a2-41d3-b39f-362482a46911

willibrandon commented 11 months ago

And thumbnail tooltip text! That's cool!

ThumbnailTooltip_Text

RussKie commented 11 months ago

In Git Extensions we've been using WindowsAPICodePack for that.

My main concern with the original proposal that the API shape wasn't quote aligned with the Windows Forms API. And in my opinion, it'd be wrong to consider just this API in isolation without considering how the rest of the TaskBar API will fit. That is, if this API was implemented as proposed, and later we decide to add more of the TaskBar API to Windows Forms SDK, how well would those synergise?

willibrandon commented 11 months ago

In Git Extensions we've been using WindowsAPICodePack for that.

My main concern with the original proposal that the API shape wasn't quote aligned with the Windows Forms API. And in my opinion, it'd be wrong to consider just this API in isolation without considering how the rest of the TaskBar API will fit. That is, if this API was implemented as proposed, and later we decide to add more of the TaskBar API to Windows Forms SDK, how well would those synergise?

Agreed. Ideally there would only need to be one round of design needed to add support for this API.

I feel very inclined to support this Taskbar API, especially since it already has first-class support in WPF.

willibrandon commented 11 months ago

I see there is also support for adding buttons to the thumbnail toolbar which could leverage the ICommand interface, similar to the new command binding API, to get or set the command to invoke when the thumbnail button is clicked.

willibrandon commented 10 months ago

Here is a demo using the taskbar thumbnail toolbar buttons themselves to exercise the ITaskbarList interface methods.

https://github.com/dotnet/winforms/assets/5017479/929a2876-0de0-477e-a8a9-50370dce09d7

willibrandon commented 10 months ago

Just over here dreaming about new taskbar APIs.

MeowLove

willibrandon commented 2 months ago

It would be great if this API could also support adding, removing, and setting the order of taskbar tabs.

https://github.com/user-attachments/assets/fd08c16b-0944-409c-a03f-fc55d36099ca