- Custom Jumplists
- Progress bar
- Overlays
Custom Jumplists
Start a new WPF project called TaskBarDemo. I'm using Visual Studio 2019, Framework 4.7, and C#.
The JumpList is a customized context-sensitive menu displayed when the user right-clicks on the task bar button for an application. It's defined in App.xaml. I'm hard-coding mine, but you can also manipulate it at run time. It occurs to me you could provide links to your application's documentation, possibly customizing it based on your user's security.
In App.xaml, add the jump list like this (substitute your file paths).
<Application x:Class="TaskbarDemo.App"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:local="clr-namespace:TaskbarDemo"
StartupUri="MainWindow.xaml">
<JumpList.JumpList>
<JumpList>
<JumpTask Title="Transmittal
Receiving Guide"
Description="Guide to the APY Transmittal Receiving process"
ApplicationPath="%PROGRAMFILES%\Microsoft
Office\root\Office16\WINWORD.EXE"
IconResourcePath="%PROGRAMFILES%\Microsoft Office\root\Office16\WINWORD.EXE"
Arguments='"APY
Transmittal Receiving Guide.docx"'
CustomCategory="Documentation"/>
<JumpTask Title="Creating
a Payment"
Description="Simple Steps for Creating a Payment"
ApplicationPath="%PROGRAMFILES%\Adobe\Acrobat Reader
DC\Reader\AcroRd32.exe"
IconResourcePath="%PROGRAMFILES%\Adobe\Acrobat Reader DC\Reader\AcroRd32.exe"
Arguments='"Simple Steps for Creating a Payment.pdf"'
CustomCategory="Documentation"/>
</JumpList>
</JumpList.JumpList>
</Application>
- Title: The text displayed for the jump task
- Description: The tooltip for the jump task
- ApplicationPath: The fully qualified path to the executable to launch - this honors environment variables
- IconResourcePath: The fully qualified path to the executable that contains the icon to display on the jump task
- IconResourceIndex: Allows the jump task to display alternative icons from the executable
- Arguments: Arguments passed to executable. Arguments are space delimited, so a single argument that contains spaces must be surrounded by quotes hence '"xxx xxx"'
- CustomCategory: groups and titles jump tasks
If you are launching a registered file type and want to allow the registered application to launch it, you can set ApplicationPath to the file path, for example.
<JumpTask Title="CNN"
Description="CNN Website"
ApplicationPath="http://www.cnn.com"
CustomCategory="News"/>
There are also JumpPath, Recently used, and Frequently used classes that can be used to launch this application with specific parameters, but are not used to launch other applications.
Progress Bar
The task button can act as a progress bar via the TaskBarItemInfo class. You can alter the color, width, and visibility of the progress bar. Let's shift our attention to the MainWindow. We need to define the TaskBarItemInfo class and bind some of its properties. The ProgressState property controls the visibility and color of the progress bar while the ProgressValue controls the width of the progress bar.
While we're there, we will also define the rest of the window's controls.
<Window x:Class="TaskbarDemo.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:local="clr-namespace:TaskbarDemo"
mc:Ignorable="d"
DataContext="{Binding RelativeSource={RelativeSource Self}}"
Title="MainWindow" Height="450" Width="800">
<Window.Resources>
<RoutedCommand x:Key="ApproveCommand"/>
<local:ProportionConverter x:Key="ProportionConverter"/>
<local:StateConverter x:Key="StateConverter"/>
</Window.Resources>
<Window.CommandBindings>
<CommandBinding Command="{StaticResource ApproveCommand}" Executed="CommandBinding_Executed"/>
</Window.CommandBindings>
<Window.TaskbarItemInfo>
<TaskbarItemInfo ProgressValue="{Binding Count, Converter={StaticResource ProportionConverter}, ConverterParameter=10>
<TaskbarItemInfo.ProgressState>
<MultiBinding Converter="{StaticResource StateConverter}">
<Binding Path="Count"/>
<Binding Path="IsError"/>
</MultiBinding>
</TaskbarItemInfo.ProgressState>
</TaskbarItemInfo>
</Window.TaskbarItemInfo>
<Grid>
<StackPanel HorizontalAlignment="Center" VerticalAlignment="Center">
<Button Width="200" Height="22" Content="Do 10 Things with errors" Command="{StaticResource ApproveCommand}" CommandParameter="ERROR" Foreground="Red"/>
<TextBlock Text="{Binding Count, StringFormat='{}{0} things done.'}">
<TextBlock.Style>
<Style TargetType="TextBlock">
<Setter Property="Visibility" Value="Visible"/>
<Style.Triggers>
<DataTrigger Binding="{Binding Count}" Value="0">
<Setter Property="Visibility" Value="Hidden"/>
</DataTrigger>
</Style.Triggers>
</Style>
</TextBlock.Style>
</TextBlock>
</StackPanel>
</Grid>
</Window>
using System.ComponentModel;
using System.Threading;
using System.Windows;
using System.Windows.Input;
namespace TaskbarDemo
{
public partial class MainWindow : Window, INotifyPropertyChanged
{
private BackgroundWorker bw = new BackgroundWorker();
private int _Count =
0;
public int Count
{
get { return _Count;
}
set
{
_Count = value;
PropChanged("Count");
}
}
private bool _IsError
= false;
public bool IsError
{
get { return
_IsError; }
set
{
_IsError = value;
PropChanged("IsError");
}
}
public MainWindow()
{
InitializeComponent();
bw.DoWork += Bw_DoWork;
}
private void
Bw_DoWork(object sender, DoWorkEventArgs e)
{
Count = 0;
IsError = false;
while (Count < 10)
{
Thread.Sleep(500);
Count++;
if (e.Argument != null && Count == 5 && e.Argument.ToString() == "ERROR") IsError = true;
}
Thread.Sleep(500);
Count = 0;
}
private void
CommandBinding_Executed(object sender,
ExecutedRoutedEventArgs e)
{
if (!bw.IsBusy) bw.RunWorkerAsync(e.Parameter);
}
public event
PropertyChangedEventHandler PropertyChanged;
public void
PropChanged(string name)
{
if (PropertyChanged != null)
PropertyChanged(this, new PropertyChangedEventArgs(name));
}
}
}
using System;
using System.Collections.Generic;
using System.Globalization;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Data;
namespace TaskbarDemo
{
class ProportionConverter : IValueConverter
{
public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
{
double MaxValue = 1;
double NewValue = 0;
double.TryParse((string)parameter,
out MaxValue);
double.TryParse(value.ToString(), out NewValue);
return NewValue / MaxValue;
}
public object
ConvertBack(object value,
Type targetType, object
parameter, CultureInfo culture)
{
throw new
NotImplementedException();
}
}
class StateConverter : IMultiValueConverter
{
public object Convert(object[] values, Type targetType, object parameter, CultureInfo culture)
{
int NewValue = 0;
bool IsError = false;
int.TryParse(values[0].ToString(), out NewValue);
bool.TryParse(values[1].ToString(), out IsError);
if (NewValue < 10)
if (IsError)
return
System.Windows.Shell.TaskbarItemProgressState.Error;
else
return
System.Windows.Shell.TaskbarItemProgressState.Normal;
else
return System.Windows.Shell.TaskbarItemProgressState.None;
}
public object[]
ConvertBack(object value,
Type[] targetTypes, object
parameter, CultureInfo culture)
{
throw new
NotImplementedException();
}
}
}
Overlay
Add a converter that converts from a boolean to a file path.
class OverlayConverter : IValueConverter
{
public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
{
string Path = parameter.ToString();
bool IsModified = (bool)value;
return IsModified ? Path : "";
}
public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
{
throw new NotImplementedException();
}
}
<TaskbarItemInfo
ProgressValue="{Binding Count, Converter={StaticResource ProportionConverter}, ConverterParameter=10}" Overlay="{Binding IsModified, Converter={StaticResource OverlayConverter}, ConverterParameter='Icons\\Save.png'}" >
Add a reference to the overlay converter to the Windows.Resources.
Add a checkbox to the stack panel.
<Window.Resources>
<RoutedCommand x:Key="ApproveCommand"/>
<local:ProportionConverter x:Key="ProportionConverter"/>
<local:StateConverter x:Key="StateConverter"/>
<local:OverlayConverter x:Key="OverlayConverter"/>
</Window.Resources>Add a checkbox to the stack panel.
<StackPanel
HorizontalAlignment="Center" VerticalAlignment="Center">
<CheckBox Content="Page
Modified?" IsChecked="{Binding IsModified}"/>
<Button Width="200" Height="22"
Content="Do 10 Things" Command="{StaticResource ApproveCommand}"/>
<Button Width="200"
Height="22" Content="Do 10 Things with errors" Command="{StaticResource
ApproveCommand}" CommandParameter="ERROR" Foreground="Red"/>
Add the IsModified property to MainWindow.xaml.cs
private bool
_IsModified = false;
public bool
IsModified
{
get { return
_IsModified; }
set
{
_IsModified = value;
PropChanged("IsModified");
}
}
Now run the application and watch the task bar button when you check the check box.
No comments:
Post a Comment