Windows 7 programming: Taskbar. Part 1 – Progress Bar.

Windows7 +1New OS Windows 7 contains a considerable quantity of innovations and improvements. These improvements concern safety, productivity, reliability etc. Also, the big attention is given to the user interface. In several posts we will talk about the innovations and program model.

The first that is appreciable in Windows 7 is, of course, updated task bar. In new taskbar many conceptual changes. One of such changes – possibility of display of progress of performance of a task (progress bar).

Windows 7 taskbar - progress

In this picture it is well visible, that on the taskbar the information on copying process is displayed. Such functionality is realised in Windows 7 with copying of files on a disk, downloading of data from a Internet (IE8). However, it is important, that we can use this functionality and for own applications. Scenarios can be different – display of process of transformation, copying, formation of data, construction of reports, generation of images, etc.

From the point of view of the developer of client Windows applications, process of use of the given functionality is very simple. Interaction occurs to OS on unmanaged level, therefore for.NET application implementation of managed wrappers is necessary. All this work was already done by developers from Microsoft and have placed it in  .NET Interop Sample Library.

The library “.NET Interop Sample Library” consists of set of components and demonstration applications. We will not stop in detail on each of them. For us it is important, that into its structure enters Vista Bridge Sample Library, Windows7.DesktopIntegration and Windows7.DesktopIntegration. Registration.

The project “Windows7.DesktopIntegration” contains those classes which are necessary for us for work with taskbar. As a part of this project there is class WindowsFormsExtensions, which contains a set of extension methods for class Form (Windows Forms). In our case following methods are interested for us:

  • SetTaskbarProgress(float percent)
  • SetTaskbarProgressState(ThumbnailProgressState state)

The call of the first method allows to specify percent of completion of a current task. Because it is extension method for class Form this class is passed in a method in parametre. It is necessary to define handle windows for which actions are carried out.

WindowsFormsExtensions.SetTaskbarProgress(this, 35);




We also have a possibility to specify a progress-bar state. Accessible states:



  • NoProgress – progress is not displayed
  • Indeterminate – progress a bar flickers
  • Normal – usual display of progress
  • Error – error display
  • Paused – pause display


The setting of the state of a progress-bar is carried out by the second method.



WindowsFormsExtensions.SetTaskbarProgressState(this, Windows7Taskbar.ThumbnailProgressState.Normal);


Unfortunately, such extension methods exist only for WinForms applications. However, it is simple to construct a similar class and for WPF applications (see the demo-app).



Finally I have created the small application which shows progress-bar possibilities in the Windows 7 taskbar.



Windows7 taskbar demo application



By means of buttons we can specify current value of a progress-bar, and also we can choose its state.



  • Mode “Normal”
  • Mode “Indeterminate”
  • Mode “Error”
  • Mode “Paused”


Good luck to you in development of your Windows 7 applications!



Sample application:





VisualStateManager – how we can define user interface in WPF and Sliverlight

It is known, that technologies WPF and Silverlight allow to change appearance of the application essentially. However, as it is found out, it is far not all know as it it is possible to do conveniently.

For definition of appearance of controls we usually use ControlTemplate, and dynamics we set via triggers. Undoubtedly, triggers in XAML – the most powerful tool. Nevertheless at construction of difficult interfaces the logic constructed on triggers happens not trivial and opaque, and at times sets restrictions.

Alternative way of construction of the task of appearance of controls is use of object VisualStateManager. I will not go deep into details, I will tell only the most necessary.

VisualStateManager is DependencyObject, with all consequences. We can set behaviour of this object for each control which we wish to operate. Idea of VSM is based on realisation of a state of an control. We can define a set of states  (VisualState) in which can there is a controls and to set for each state the appearance. States are packed into groups (VisualStateGroup). Thus, it is possible to define logic groups of states and to define in them transitions.

Each state (VisualState) is Storyboard. State realisation consists that at transition in this condition works set Storyboard, i.e. animation will be starting.

It is possible to present representation of the described structure graphically.

VisualStateManager sample

Let’s create a small example on the basis of states. Let’s create new UserControl in the application WPF with simple structure.

<UserControl x:Class="WpfApplication15.UserControl1"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml">
    <Grid>
        <Border Name="State1Panel" Background="Red" Opacity="1"/>
        
        <TextBlock Text="Text of control" Foreground="White" HorizontalAlignment="Center" VerticalAlignment="Center"/>
    </Grid>
</UserControl>


It is a control with the text and a red background. Let’s define two states for this control – State1 and State2. Each of states will visually differ a background. Let’s describe two objects VisualState and we will set transition animations.In our case we will simply put against each other two elements Border with a different background. Animation will consist in concealment and display of the necessary element depending on a state.



<UserControl x:Class="WpfApplication15.UserControl1"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml">
    <Grid>
        <VisualStateManager.VisualStateGroups>
            <VisualStateGroup x:Name="Common">
                <VisualState x:Name="State1">
                    <Storyboard>
                        <DoubleAnimation To="1" Duration="0:00:00.4" Storyboard.TargetName="State1Panel" Storyboard.TargetProperty="(UIElement.Opacity)" />
                        <DoubleAnimation To="0" Duration="0:00:00.7" Storyboard.TargetName="State2Panel" Storyboard.TargetProperty="(UIElement.Opacity)" />
                    </Storyboard>
                </VisualState>
                <VisualState x:Name="State2">
                    <Storyboard>
                        <DoubleAnimation To="0" Duration="0:00:00.7" Storyboard.TargetName="State1Panel" Storyboard.TargetProperty="(UIElement.Opacity)" />
                        <DoubleAnimation To="1" Duration="0:00:00.4" Storyboard.TargetName="State2Panel" Storyboard.TargetProperty="(UIElement.Opacity)" />
                    </Storyboard>
                </VisualState>
            </VisualStateGroup>
        </VisualStateManager.VisualStateGroups>
        <Border Name="State2Panel" Background="Green" Opacity="0"/>
        <Border Name="State1Panel" Background="Red" Opacity="1"/>
        
        <TextBlock Text="Text of control" Foreground="White" HorizontalAlignment="Center" VerticalAlignment="Center"/>
    </Grid>
</UserControl>


Now, using VisualStateManager, it is possible to switch states of a control and thus to change appearance. For this purpose we will place a control on the form.



<Window x:Class="WpfApplication15.Window1"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    xmlns:WpfApplication15="clr-namespace:WpfApplication15"
    Title="Window1" Height="300" Width="300">
    <Grid>
        <Grid.RowDefinitions>
            <RowDefinition/>
            <RowDefinition Height="40"/>
        </Grid.RowDefinitions>
        <WpfApplication15:UserControl1 x:Name="Control1" Height="118" VerticalAlignment="Top" Margin="50,12,101,0" />
        
        <StackPanel Orientation="Horizontal" Grid.Row="1">            
            <Button Name="State1Button" Width="75" Click="State1Button_Click">State1</Button>
 
            <Button Name="State2Button" Width="75" Click="State2Button_Click">State2</Button>
        </StackPanel>
    </Grid>
</Window>




Also we will create handlers of pressing of buttons.



private void State1Button_Click(object sender, RoutedEventArgs e)
{
    VisualStateManager.GoToState(Control1, "State1", true);
}
 
private void State2Button_Click(object sender, RoutedEventArgs e)
{
    VisualStateManager.GoToState(Control1, "State2", true);
}


As a result it is had the following application.





Thus we can create some states of our control and on the basis of it to build the user interface.



Such approach becomes especially useful when we see, that for standard controls there is a set of the predefined states. For example, for the Button – Normal, MouseOver, Pressed, Disabled etc. Such states are and at other elements. Because of such possibility creation of templates for controls essentially becomes simpler. For example, we can describe the button as follows.



<Style TargetType="{x:Type Button}">
    <Setter Property="Margin" Value="5"/>
    <Setter Property="Width" Value="100"/>
    <Setter Property="Template">
        <Setter.Value>
            <ControlTemplate TargetType="{x:Type Button}">
                <Grid>
                    <VisualStateManager.VisualStateGroups>
                        <VisualStateGroup x:Name="Common">
                            <VisualState x:Name="Normal"/>
                            <VisualState x:Name="MouseOver">
                                <Storyboard>
                                    <DoubleAnimation To="0" Duration="0:00:00.5" Storyboard.TargetName="NormalBorder" Storyboard.TargetProperty="(UIElement.Opacity)" />
                                    <DoubleAnimation To="1" Duration="0:00:00.3" Storyboard.TargetName="OverBorder" Storyboard.TargetProperty="(UIElement.Opacity)" />
                                    <DoubleAnimation From="0" To="10" AutoReverse="True" Duration="0:00:00.3" Storyboard.TargetName="OverBorderRotateTransform" Storyboard.TargetProperty="Angle" />
                                </Storyboard>
                            </VisualState>
                            <VisualState x:Name="Pressed">
                                <Storyboard>
                                    <DoubleAnimation To="0" Duration="0:00:00.5" Storyboard.TargetName="NormalBorder" Storyboard.TargetProperty="(UIElement.Opacity)" />
                                    <DoubleAnimation To="1" Duration="0:00:00.3" Storyboard.TargetName="OverBorder" Storyboard.TargetProperty="(UIElement.Opacity)" />
                                    <DoubleAnimation From="0" To="360" AutoReverse="True" Duration="0:00:00.4" Storyboard.TargetName="OverBorderRotateTransform" Storyboard.TargetProperty="Angle" />
                                </Storyboard>
                            </VisualState>
                        </VisualStateGroup>
                    </VisualStateManager.VisualStateGroups>
                    
                    <Border Name="NormalBorder" CornerRadius="5" Background="Gray" Opacity="1"/>
                    <Border Name="OverBorder" CornerRadius="5" Background="Green" Opacity="0">
                        <Border.RenderTransform>
                            <RotateTransform x:Name="OverBorderRotateTransform" CenterX="50" CenterY="20" />
                        </Border.RenderTransform>
                    </Border>
                    
                    <ContentPresenter Content="{TemplateBinding Content}" Margin="5" HorizontalAlignment="Center" VerticalAlignment="Center"/>
                </Grid>
            </ControlTemplate>
        </Setter.Value>
    </Setter>
</Style>




Now our buttons will look as follows.





Similarly it is possible to adjust appearance in Silverlight applications.



Unfortunately, this time remained without attention a Transitions, but about them next time.



WPF sample:





Silverlight3 sample:



3D-capabilities in Silverlight 3

As is known, in WPF there are great possibilities to work with 3D. Silverlight concedes WPF because it is cross-platform technology. However, in Silverlight 3 a support of 3D has appeared. Let’s consider this subject.

Actually, if to look more detailed at possibilities 3D in Siliverlight 3 it is possible to understand quickly that it not that support which is present in WPF. It is logical. Actually, possibilities 3D in Silverlight are reduced to creation of projections of the image under different corners on three axes. Certainly, it not what it would be desirable in an ideal. Nevertheless this functionality allows to present our application in a three-dimensional kind.

Property Projection which is accessible to all objects is responsible for creation of 3D-projections in Silverlight 3. Using this property it is possible to set parametres of display of a control. Let’s create the panel in which we will put standard controls.

<StackPanel Name="InputPanel" Grid.Row="1">
    <TextBlock Text="Text:"/>
    <TextBox />
    <ComboBox />
    <Button Content="Go!"/>
</StackPanel>


Now we will create a 3D-projection of our panel. Let’s turn the panel on an axis X.



<StackPanel Name="InputPanel" Grid.Row="1">
    <StackPanel.Projection>
        <PlaneProjection RotationX="20" />
    </StackPanel.Projection>
    <TextBlock Text="Text:"/>
    <TextBox />
    <ComboBox />
    <Button Content="Go!"/>
</StackPanel>


That is interesting, values of parametres of 3D-projections can be changed by means of bindings and animations.



Let’s test it. Let’s create three Slider controls. Let’s bind each such control to the axis.



<StackPanel>
    <Slider Value="{Binding ElementName=InputPanel, Path=Projection.RotationX, Mode=TwoWay}" Minimum="0" Maximum="720" />
    <Slider Value="{Binding ElementName=InputPanel, Path=Projection.RotationY, Mode=TwoWay}" Minimum="0" Maximum="720" />
    <Slider Value="{Binding ElementName=InputPanel, Path=Projection.RotationZ, Mode=TwoWay}" Minimum="0" Maximum="720" />
</StackPanel>
    
<StackPanel Name="InputPanel" Grid.Row="1">
    <StackPanel.Projection>
        <PlaneProjection RotationX="20" />
    </StackPanel.Projection>
    <TextBlock Text="Text:"/>
    <TextBox />
    <ComboBox />
    <Button Content="Go!"/>
</StackPanel>


Now we can rotate the image in 3D-space in a real time! :))) Here is how the application looks.





Download an example of the given application you can using reference below.



Use of hyperlinks inside text at Silverlight 3

Insert of a hyperlink in the text – absolutely usual task for web-applications. Frequently we do it when makes HTML documents. Unfortunately, default controls in Silverlight do not allow to insert a hyperlink in the text. Let’s consider an example of how it is possible to bypass this restriction.

If to be fair in Silverlight 3 there is an control HyperlinkButton which all the same allows to insert hyperlinks into Silverlight applications. The problem of such control consists that by default it is impossible to insert it in the text. Construction of a new control can be one of the decision of the given problem.

First, we will split our statement into words. The blank or punctuation marks can be a divider, for example. After that it will be necessary to understand what of words should be hyperlinks. For these purposes it is possible to use regular expressions, for example.

Secondly, for each word we will create own instance of control. If the word is not a hyperlink we will create for it an control TextBlock. If the word is a hyperlink we will create for it an control HyperlinkButton.

At last, we will place all our controls in WrapPanel container.

The own control can be realised in several ways. As base it is possible to use UserControl or any other types of controls. However, it is more convenient to choose as base object WrapPanel because any additional logic in our case it is not required.

Let’s consider process of construction of such control step-by-step.

1) Let’s create the control and we will inherit it from WrapPanel.

public class LinkTextBlock : WrapPanel
{
//...
}




2) Let’s create property which contains the text.



public class LinkTextBlock : WrapPanel
{
    public static DependencyProperty TextProperty;
 
    static LinkTextBlock()
    {
        TextProperty = DependencyProperty.Register("Text", typeof(string), typeof(LinkTextBlock), new PropertyMetadata(String.Empty, TextChangedCallback));
 
        // ...
    }
 
    private static void TextChangedCallback(DependencyObject d, DependencyPropertyChangedEventArgs e)
    {
        var control = (LinkTextBlock)d;
        control.BuildControls();
    }
 
    public string Text
    {
        get { return (string)GetValue(TextProperty); }
        set { SetValue(TextProperty, value); }
    }
 
    // ...
}


3) Let’s define a method for statement’s splitting on words. Let’s start this method every time when the text is updated (method TextChangedCallback).



private void BuildControls()
{
    Children.Clear();
 
    foreach (UIElement control in from word in Text.Split(' ')
                                  select BuildWordControl(word))
    {
        Children.Add(control);
    }
}


4) We define a method for construction of control for each word.



private UIElement BuildWordControl(string text)
{
    UIElement result;
    string url, displayText;
 
    if ((CheckLinkMethod != null) && (CheckLinkMethod(text, out url, out displayText) == true))
    {
        Uri navigateUri = new Uri(..);
 
        result = new HyperlinkButton() { Content = displayText, Tag = url, NavigateUri = navigateUri };
        ((HyperlinkButton)result).Click += delegate(object sender, RoutedEventArgs e)
                                               {
                                                    // do something
                                               };
    }
    else
    {
        result = new TextBlock() { Text = text };
    }
 
    return result;
}


Now the control is ready to the use :)





In a final code I have inserted delegates who allow to set logic of definition of hyperlinks, styles for words, tool tips and other elements. You can download source code by using following link.





Resharper 4.5 Released

ReSharper 4.5 New version of ReSharper has released! As announced, the new version features major improvements in performance and memory usage. In addition to focusing on performance enhancements, JetBrains also added a number of intelligence features and improvements.

Also, you can see small flash movie about new features in ReShareper 4.5.

ReSharper it is a great tool and it is cool that new version is released.

You can download it here: http://www.jetbrains.com/resharper/download/

Tooltip in Silverlight 3 – part 2

Recently we have talked about how it is possible to redefine appearance of the tool tip in Silverlight applications. The tool tip has taken more interesting form after that. However, the effect of show and remains sad :) Let’s try change a way of show of this tool tip by animation addition.

However, I wish to warn at once that the task of animation demands use of triggers, and them, unfortunately, it is impossible to set from styles. For this reason we will refuse use of styles.

So, most simple that we can animate it is Opacity property. Let’s make it.

<Button Content="Click me!" Width="100" Height="100">
    <ToolTipService.ToolTip>
        <ToolTip Name="RootLayout" Width="100" Height="100" Style="{StaticResource TooltipStyle}">
            <ToolTip.Triggers>
                <EventTrigger>
                    <BeginStoryboard>
                        <Storyboard>
                            <DoubleAnimation Storyboard.TargetName="RootLayout" Storyboard.TargetProperty="Opacity" From="0" To="1" Duration="0:0:00.2"/>
                        </Storyboard>
                    </BeginStoryboard>
                </EventTrigger>
            </ToolTip.Triggers>
            <TextBlock Text="123"/>
        </ToolTip>
    </ToolTipService.ToolTip>
</Button>




From this example you can see that in the course of animation the transparency of the main element changes. However similar animation a little than differs from standard behaviour. Let’s add more dynamics. We will implement a showing of the tool tip in the form of a pendulum.



For these purposes we will need to add two transformations – ScaleTransofrm and RenderTransform. After that it is possible to change parametres of these transformations and to model behaviour of a pendulum.



<DoubleAnimation Storyboard.TargetName="ScaleMe" Storyboard.TargetProperty="ScaleX" From="0" To="1" Duration="0:0:00.1"/>
<DoubleAnimation Storyboard.TargetName="ScaleMe" Storyboard.TargetProperty="ScaleY" From="0" To="1" Duration="0:0:00.1"/>
<DoubleAnimationUsingKeyFrames Storyboard.TargetName="RotateMe" Storyboard.TargetProperty="Angle">
    <DoubleAnimationUsingKeyFrames.KeyFrames>
        <DoubleKeyFrameCollection>
            <LinearDoubleKeyFrame KeyTime="0:00:00.1" Value="-15" />
            <LinearDoubleKeyFrame KeyTime="0:00:00.2" Value="15" />
            <LinearDoubleKeyFrame KeyTime="0:00:00.3" Value="-11" />
            <LinearDoubleKeyFrame KeyTime="0:00:00.4" Value="11" />
            <LinearDoubleKeyFrame KeyTime="0:00:00.5" Value="-3" />
            <LinearDoubleKeyFrame KeyTime="0:00:00.6" Value="3" />
            <LinearDoubleKeyFrame KeyTime="0:00:00.7" Value="0" />
        </DoubleKeyFrameCollection>
    </DoubleAnimationUsingKeyFrames.KeyFrames>
</DoubleAnimationUsingKeyFrames>


Source code:



Tooltip in Silverlight 3 – part 1

Frequently in our appendices we need to create tool tips. Class ToolTip exists in Silverlight for these purposes. We can create such tool tips more easily by using this class.

<Button Content="Click me!" Width="100" Height="100">
    <ToolTipService.ToolTip>
        <ToolTip Width="100" Height="100">
            <TextBlock Text="123"/>
        </ToolTip>
    </ToolTipService.ToolTip>
</Button>


As we can see this code is very simple. However, tool tips which we see thus can seem the boring.





Ok. Let’s look at how it is possible to define behaviour of these tips in more interesting kind. Also as well as in WPF we can redefine the control template for object ToolTip and essentially change its appearance.



<Button Content="Click me!" Width="100" Height="100">
    <ToolTipService.ToolTip>
        <ToolTip Width="100" Height="100">
            <ToolTip.Template>
                <ControlTemplate TargetType="ToolTip">
                    <Border CornerRadius="5" Background="Red">
                        <ContentPresenter Margin="5" Content="{TemplateBinding Content}"/>
                    </Border>
                </ControlTemplate>
            </ToolTip.Template>
            
            <TextBlock Text="123"/>
        </ToolTip>
    </ToolTipService.ToolTip>
</Button>




Now our help became more beautiful.





It is clear that to define ControlTemplate each time is ungrateful action, therefore we will define tool tips style.



<Button Content="Click me!" Width="100" Height="100">
    <ToolTipService.ToolTip>
        <ToolTip Width="100" Height="100">
            <ToolTip.Style>
                <Style TargetType="ToolTip">
                    <Setter Property="Template">
                        <Setter.Value>
                            <ControlTemplate TargetType="ToolTip">
                                <Border CornerRadius="5" Background="Red">
                                    <ContentPresenter Margin="5" Content="{TemplateBinding Content}"/>
                                </Border>
                            </ControlTemplate>                            
                        </Setter.Value>
                    </Setter>
                </Style>
            </ToolTip.Style>
            
            <TextBlock Text="123"/>
        </ToolTip>
    </ToolTipService.ToolTip>
</Button>




After that it is possible to take out this style in resources and to use it repeatedly.



<UserControl.Resources>    
    <Style x:Key="TooltipStyle" TargetType="ToolTip">
        <Setter Property="Template">
            <Setter.Value>
                <ControlTemplate TargetType="ToolTip">
                    <Border CornerRadius="5" Background="Red">
                        <ContentPresenter Margin="5" Content="{TemplateBinding Content}"/>
                    </Border>
                </ControlTemplate>                            
            </Setter.Value>
        </Setter>
    </Style>
</UserControl.Resources>
 
<!-- .... --->
 
<Button Content="Click me!" Width="100" Height="100">
    <ToolTipService.ToolTip>
        <ToolTip Width="100" Height="100" Style="{StaticResource TooltipStyle}">
            <TextBlock Text="123"/>
        </ToolTip>
    </ToolTipService.ToolTip>
</Button>


Now our tool tip became more pleasant visually.



However, it is necessary to tell, that removal in styles not always is possible, but about it we will talk next time.