Search This Blog

Thursday, July 23, 2015

WPF Busy Indicator

After reading Better WPF Circular Progress Bar I knew I could do this in XAML with no code behind.  So I stole the design for the oracular progress bar and reworked the animation.

 <UserControl Name="BusyIndicator" HorizontalAlignment="Stretch" VerticalAlignment="Stretch">    
   <Viewbox Width="{Binding Width, ElementName=BusyIndicator}" Height="{Binding Height, ElementName=BusyIndicator}"      
        HorizontalAlignment="Center" VerticalAlignment="Center">  
     <Grid Background="Transparent" ToolTip="Searching...." HorizontalAlignment="Center" VerticalAlignment="Center">  
       <Canvas Name="Canvas1"  
         VerticalAlignment="Center" Width="120" Height="120">  
           <RotateTransform Angle="0" />  
           <Style TargetType="Canvas">  
               <Trigger Property="IsVisible" Value="True">  
                   <BeginStoryboard Name="Storyboard_Rotate">  
                     <Storyboard RepeatBehavior="Forever">  
                       <DoubleAnimation Storyboard.TargetProperty="RenderTransform.Angle"   
                          From="0" To="360" Duration="0:0:2"/>  
                   <StopStoryboard BeginStoryboardName="Storyboard_Rotate" />  
         <Ellipse Width="20" Height="20" Stretch="Fill" Fill="Black" Opacity="1.0" Canvas.Left="50" Canvas.Top="0" />  
         <Ellipse Width="20" Height="20" Stretch="Fill" Fill="Black" Opacity="0.9" Canvas.Left="20.6107373853764" Canvas.Top="9.54915028125262" />  
         <Ellipse Width="20" Height="20" Stretch="Fill" Fill="Black" Opacity="0.8" Canvas.Left="2.44717418524233" Canvas.Top="34.5491502812526" />  
         <Ellipse Width="20" Height="20" Stretch="Fill" Fill="Black" Opacity="0.7" Canvas.Left="2.44717418524232" Canvas.Top="65.4508497187474" />  
         <Ellipse Width="20" Height="20" Stretch="Fill" Fill="Black" Opacity="0.6" Canvas.Left="20.6107373853763" Canvas.Top="90.4508497187474" />  
         <Ellipse Width="20" Height="20" Stretch="Fill" Fill="Black" Opacity="0.5" Canvas.Left="50" Canvas.Top="100" />  
         <Ellipse Width="20" Height="20" Stretch="Fill" Fill="Black" Opacity="0.4" Canvas.Left="79.3892626146236" Canvas.Top="90.4508497187474" />  
         <Ellipse Width="20" Height="20" Stretch="Fill" Fill="Black" Opacity="0.3" Canvas.Left="97.5528258147577" Canvas.Top="65.4508497187474" />  
         <Ellipse Width="20" Height="20" Stretch="Fill" Fill="Black" Opacity="0.2" Canvas.Left="97.5528258147577" Canvas.Top="34.5491502812526" />  

I got the idea from the Code Project article linked above.  They use the The Code Project Open License (CPOL) and I derived my work from that and make no claim of ownership at all.

Friday, March 20, 2015

Hardcodet Taskbar RoutedUICommand workaround.

I have found a way to use Taskbar command using bubbled routed UI commands.

Here is the object.

/// <summary>
/// Taskbar routed UI command.
/// </summary>
public class TaskbarRoutedUICommand : DependencyObject, ICommand
   #region Private
   /// <summary>
   /// Window to send command.
   /// </summary>
   private Window window = null;

   #region Parameters
   /// <summary>
   /// Command DependencyProperty
   /// </summary>
   public static readonly DependencyProperty CommandProperty =
       DependencyProperty.Register("Command", typeof(RoutedUICommand), typeof(TaskbarRoutedUICommand), new PropertyMetadata(null));

   /// <summary>
   /// Command
   /// </summary>
   public RoutedUICommand Command
       get { return (RoutedUICommand)GetValue(CommandProperty); }
       set { SetValue(CommandProperty, value); }

   public static bool IsDesignMode
           return (bool)

   /// <summary>
   /// Can Execute Change
   /// Not used
   /// </summary>
   public event EventHandler CanExecuteChanged;

   #region ICommand        
   public bool CanExecute(object parameter)
       if (window == null)                
           window = GetTaskbarWindow(parameter);
       if (window == null)
           return true;
           return this.Command.CanExecute(parameter, window);

   public void Execute(object parameter)
       if (window == null)
           window = GetTaskbarWindow(parameter);

       this.Command.Execute(parameter, window);

   #region TryFindParent helper
   /// <summary>
   /// Resolves the window that owns the TaskbarIcon class.
   /// </summary>
   /// <param name="commandParameter"></param>
   /// <returns></returns>
   protected Window GetTaskbarWindow(object commandParameter)
       if (IsDesignMode) return null;

       //get the showcase window off the TaskbarIcon
       var tb = commandParameter as TaskbarIcon;
       return tb == null ? null : TryFindParent<Window>(tb);

   /// <summary>
   /// Finds a parent of a given item on the visual tree.
   /// </summary>
   /// <typeparam name="T">The type of the queried item.</typeparam>
   /// <param name="child">A direct or indirect child of the
   /// queried item.</param>
   /// <returns>The first parent item that matches the submitted
   /// type parameter. If not matching item can be found, a null
   /// reference is being returned.</returns>
   public static T TryFindParent<T>(DependencyObject child)
       where T : DependencyObject
       //get parent item
       DependencyObject parentObject = GetParentObject(child);

       //we've reached the end of the tree
       if (parentObject == null) return null;

       //check if the parent matches the type we're looking for
       T parent = parentObject as T;
       if (parent != null)
           return parent;
           //use recursion to proceed with next level
           return TryFindParent<T>(parentObject);

   /// <summary>
   /// This method is an alternative to WPF's
   /// <see cref="VisualTreeHelper.GetParent"/> method, which also
   /// supports content elements. Keep in mind that for content element,
   /// this method falls back to the logical tree of the element!
   /// </summary>
   /// <param name="child">The item to be processed.</param>
   /// <returns>The submitted item's parent, if available. Otherwise
   /// null.</returns>
   public static DependencyObject GetParentObject(DependencyObject child)
       if (child == null) return null;
       ContentElement contentElement = child as ContentElement;

       if (contentElement != null)
           DependencyObject parent = ContentOperations.GetParent(contentElement);
           if (parent != null) return parent;

           FrameworkContentElement fce = contentElement as FrameworkContentElement;
           return fce != null ? fce.Parent : null;

       //if it's not a ContentElement, rely on VisualTreeHelper
       return VisualTreeHelper.GetParent(child);


Here is how to use it in the xaml file.
Place this in the resources section

<objects:taskbarrouteduicommand command="RoutedUICommand" x:key="ApplicationExit">

Here is an example Taskbar be sure to pass the TaskbarIcon as the parameter.

<tb:TaskbarIcon x:Name="TaskbarIcon"
              DoubleClickCommand="{StaticResource ApplicationExit}"                        
              DoubleClickCommandParameter="{Binding RelativeSource={RelativeSource Self}}">            
          <MenuItem Header="Exit" Command="{StaticResource ApplicationExit}" CommandParameter="{Binding}"/>