WPF pasek postępu na ikonie aplikacji, dodatkowe guziki w podlądzie apliacji – TaskbarItemInfo w natarciu.

Nauka WPF idzie całkiem dobrze, a to oznacza kolejną porcję informacji. Dzisiaj trochę o ficzerze z Windows7 (które jest w Viście), a nie wiem czy będzie nadal aktualny w nowej wersji Windows, która pewnie ukaże niebawem.
Opowiem trochę o pasku postępu, który można wyświetlać na ikonie aplikacji, która jest na systemowym pasku zadań, oraz o tym jak dodać kilka (maksymalnie 7 widocznych) guzików do podglądu aplikacji. Przez podgląd rozumiem, najechanie myszą na ikonę działającej aplikacji,
znajdującą się na pasku zadań, ale bez klikania na niej. Spowoduje to
wyświetlenie się małego okienka z podglądem naszej aplikacji.
Media Player Classic to ma, Zune to ma, Windows Media Player to, więc dlaczego i ja miałbym z tego nie skorzystać.

Podgląd aplikacji, z wyświetlonym podpisem dla pierwszego guzika.

Obie funkcjonalności (pasek postępu oraz dodatkowe guziki) opierają się na TaskbarItemInfo, który jest częścią wyświetlanego okna. Jak prawie wszystko w WPF, można to zdefiniować w XAML oraz code-behind. Wszyscy pamiętamy o tym, że samodzielne definiowane właściwości dla TaskbarItemInfo w code-behind zaczynamy od zaalokowania pamięci na ten obiekt, ponieważ początkowo TaskbarItemInfo jest NULLem. Ja o tym pamiętam po pierwszym uruchomienia programu.
Tak deklaruje się w XAML dodatkowe guziki, które mają być widoczne w podglądzie okna.

  1. <Window.TaskbarItemInfo>
  2.     <TaskbarItemInfo>
  3.       <TaskbarItemInfo.ThumbButtonInfos>
  4.         <ThumbButtonInfo x:Name=”ReverseThumb” ImageSource=”imagesrev.png” Description=”Reverse progress”
  5.                          Click=”ReverseThumbClick” />
  6.         <ThumbButtonInfo x:Name=”PauseThumb” ImageSource=”imagespause.png” Description=”Pause progress”
  7.                          Click=”PauseThumbClick” IsEnabled=”False” />
  8.         <ThumbButtonInfo x:Name=”RunThumb” ImageSource=”imagesplay.png” Description=”Run progress”
  9.                          Click=”RunThumbClick” />
  10.         <ThumbButtonInfo x:Name=”ForwardThumb” ImageSource=”imagesffd.png” Description=”Forward progress”
  11.                          Click=”ForwardThumbClick” IsEnabled=”False” />
  12.       </TaskbarItemInfo.ThumbButtonInfos>
  13.     </TaskbarItemInfo>
  14.   </Window.TaskbarItemInfo>

Nie ma w tym nic trudnego, ani skomplikowanego. Jenocześnie można wyświetlić nie więcej niż siedem, jeśli na liście będzie ich więcej, to tylko pierwszych siedem widocznych będzie wyświetlonych. Dynamiczne zachowanie się guzików, można osiągnąć poprzez zmianę wartości Visibility na Collapsed, ukrywając jedne, a odkrywając inne.
W przykładnie postanowiłem obsłużyć zdarzenie Click i wtedy wykonać odpowiedni kod. Do TaskbarItemInfo można również przypiąć wpf’owy Command.
ThumbButtonInfo ma pewną przypadłość, lub nie potrafiłem znaleźć tej informacji, otóż w C# nie można (nie wiem jak?) odwołać się do właściwości Name, przez co musiałem obsługę zdarzeń rozdzielić na pojedyncze metody. Funkcjonalność na której mi zależało, to uruchomienie paska postępu, pauza postępu, oraz zmiana kierunku postępu (np. na symulowanie rollback instalacji).

Oprócz tego, na kolorowym oknie aplikacji (to różowe GUI powstało w ramach praktyki WPF i ćwiczeń z layoutu) widać 5 pseudo guzików, które umożliwiają ustawienie właściwości paska postępu, wyświetlanego na ikonie aplikacji.
Stan postępu można sygnalizować na cztery (pięć) sposob:


  • Zielony (TaskbarItemProgressState.Normal), wszystko w porządeczku
  • Niezdecydowany (TaskbarItemProgressState.Indeterminate), gdy
    programista nie jest pewien ile czasu zajmie operacja, może wyświetlić
    pasek informujący o tym, że operacja jest w trakcie wykonywania i
    będzie gotowa gdy będzie gotowa (tak samo jak Diablo III). W tym
    przypadku aktualizowanie paska postępu nie wpływa w żaden sposób na
    sposób wyświetlania postępu)
  • Zółty (TaskbarItemProgressState.Paused) – brak postępu, pauza. Nie mniej jednak nic nie powstrzymuje aplikacji przed zwiększaniem wartości postępu, 
  • Czerwony (TaskbarItemProgressState.Error) – pojawił się błąd, nadal można aktualizować pasek.
  • Brak paska postępu (TaskbarItemProgressState.None)

Powtórzę się: w każdym przypadku wartość postępu może wzrastać czy maleć (cofać się).
Poszczególne stany można zmieniać w trakcie działania aplikacji, nie trzeba zerować czy resetować  postępu. Oczywiście wszyscy pamiętamy, że kontrolki modyfikować wolno tylko w głównym wątku, TaskbarItemInfo nie jest wyjątkiem. Wartości przyjmowane przez pasek postępu mieszcząc się od 0.0 do 1.0 (double).
Wątek który symuluje postęp paska:

  1. new Action(
  2. () =>
  3. {
  4.     this.TaskbarItemInfo.ProgressValue = progressValue;
  5.     progressValue += progress;
  6.     if (progressValue > 1.0)
  7.     {
  8.         progressValue = 0.0;
  9.     }
  10.     else if (progressValue < 0.0)
  11.     {
  12.         progressValue = 1.0;
  13.     }
  14. })

Tyle – cała filozofia. Przyznam szczerze, że tą funkcjonalność wcześniej, to myślałem że będzie więcej zabawy, jednak WPF kolejny raz mnie pozytywnie zaskakuje.
W świątecznej promocji dopiszę jeszcze na krótko, że dodatkowo na ikonie można dorysować jeszcze mniejszą ikonkę tzw. Overlay. Miniaturka pojawia się i znika płynnie, natomiast jeśli jest już widoczna i zostanie zmieniona na inną, to zmiana ta jest natychmiastowa.

  1. <Window.TaskbarItemInfo>
  2.     <TaskbarItemInfo Overlay=”imagesthree.png”>
  3. </Window.TaskbarItemInfo>

Znowu prosto – WPF nas rozpieszcza 🙂

Wszelkie uwagi i krytykę jak zwykle chętnie przyjmę w komentarzach.