Aspdotnet-Suresh

aspdotnet-suresh offers C#.net articles and tutorials,csharp dot net,asp.net articles and tutorials,VB.NET Articles,Gridview articles,code examples of asp.net 2.0 /3.5,AJAX,SQL Server Articles,examples of .net technologies

WPF (Windows Presentation Foundation) in .NET

May 12, 2010
Windows Presentation Foundation (WPF)
The Windows Presentation Foundation is Microsoft’s next generation UI framework to create applications with a rich user experience. It is part of the .NET framework 3.0 and higher.
WPF combines application UIs, 2D graphics, 3D graphics, documents and multimedia into one single framework. Its vector based rendering engine uses hardware acceleration of modern graphic cards. This makes the UI faster, scalable and resolution independent.



Separation of Appearance and Behavior
WPF separates the appearance of a user interface from its behavior. The appearance is generally specified in the Extensible Application Markup Language (XAML), the behavior is implemented in a managed programming language like C# or Visual Basic. The two parts are tied together by data binding, events and commands. The separation of appearance and behavior brings the following benefits:

  • Appearance and behavior are loosely coupled
  • Designers and developers can work on separate models.
  • Graphical design tools can work on simple XML documents instead of parsing code.
Rich composition
Controls in WPF are extremely composable. You can define almost any type of controls as content of another. Although this flexibility sounds horrible to designers, it’s a very powerful feature if you use it appropriate. Put an image into a button to create an image button, or put a list of videos into a combo box to choose a video file.






 <Button>

    <StackPanel Orientation="Horizontal">

        <Image Source="speaker.png" Stretch="Uniform"/>

        <TextBlock Text="Play Sound" />

    </StackPanel>

</Button>
 Highly customizable
Because of the strict separation of appearance and behavior you can easily change the look of a control. The concept of styles let you skin controls almost like CSS in HTML. Templates let you replace the entire appearance of a control.
The following example shows a default WPF button and a customized button.

Resolution independence
All measures in WPF are logical units - not pixels. A logical unit is a 1/96 of an inch. If you increase the resolution of your screen, the user interface stays the same size - if just gets crispier. Since WPF builds on a vector based rendering engine it's incredibly easy to build scalable user interfaces.

 


Introduction to XAML

XAML stands for Extensible Application Markup Language. It’s a simple language based on XML to create and initialize .NET objects with hierarchical relations. Although it was originally invented for WPF it can be used to create any kind of object trees.
Today XAML is used to create user interfaces in WPF, Silver light, declare workflows in WF and for electronic paper in the XPS standard.

Advantages of XAML

All you can do in XAML can also be done in code. XAML is just another way to create and initialize objects. You can use WPF without using XAML. It's up to you if you want to declare it in XAML or write it in code. Declare your UI in XAML has some advantages:

  • XAML code is short and clear to read
  • Separation of designer code and logic
  • Graphical design tools like Expression Blend require XAML as source.
  • The separation of XAML and UI logic allows it to clearly separate the roles of designer and developer.

XAML vs. Code

As an example we build a simple StackPanel with a textblock and a button in XAML and compare it to the same code in C#.

 

<StackPanel>

    <TextBlock Margin="20">Welcome to the World of XAML</TextBlock>

    <Button Margin="10" HorizontalAlignment="Right">OK</Button>

</StackPanel>

 

 
The same expressed in C# will look like this:

 

// Create the StackPanel

StackPanel stackPanel = new StackPanel();

this.Content = stackPanel;

 

// Create the TextBlock

TextBlock textBlock = new TextBlock();

textBlock.Margin = new Thickness(10);

textBlock.Text = "Welcome to the World of XAML";

stackPanel.Children.Add (textBlock);

 

// Create the Button

Button button = new Button ();

button.Margin= new Thickness (20);

button.Content = "OK";

stackPanel.Children.Add(button);

 

 
As you can see is the XAML version much shorter and clearer to read. And that's the power of XAMLs expressiveness.

 

Properties as Elements

Properties are normally written inline as known from XML <Button Content="OK" />. But what if we want to put a more complex object as content like an image that has properties itself or maybe a whole grid panel? .To do that we can use the property element syntax. This allows us to extract the property as an own child element.

 

<Button>

  <Button.Content>

     <Image Source="Images/OK.png" Width="50" Height="50" />

  </Button.Content>

</Button>

 

 

Implicit Type conversion

A very powerful construct of WPF are implicit type converters. They do their work silently in the background. When you declare a Border Brush, the word "Blue" is only a string. The implicit Brush Converter makes a System.Windows.Media.Brushes.Blue out of it. The same regards to the border thickness that is being converted implicit into a Thickness object. WPF includes a lot of type converters for built-in classes, but you can also write type converters for your own classes.

 

<Border BorderBrush="Blue" BorderThickness="0, 10">

</Border> 

Markup Extensions

Markup extensions are dynamic placeholders for attribute values in XAML. They resolve the value of a property at runtime. Markup extensions are surrounded by curly braces
(Example: Background="{StaticResourceNormalBackgroundBrush}").
 WPF has some built-in markup extensions, but you can write your own, by deriving from Markup Extension. These are the built-in markup extensions:

·         Binding
To bind the values of two properties together.

·         Static Resource
One time lookup of a resource entry

·         Dynamic Resource
Auto updating lookup of a resource entry

·         Template Binding
To bind a property of a control template to a dependency property of the control

·         x: Static
Resolve the value of a static property.

·         x:Null
Return null
The first identifier within a pair of curly braces is the name of the extension. All preceding identifiers are named parameters in the form of Property=Value. The following example shows a label whose Content is bound to the Text of the textbox. When you type a text into the text box, the text property changes and the binding markup extension automatically updates the content of the label.

 

<TextBox x:Name="textBox"/>

<Label Content="{Binding Text, ElementName=textBox}"/>

Namespaces

At the beginning of every XAML file you need to include two namespaces.
The first is http://schemas.microsoft.com/winfx/2006/xaml/presentation.

 It is mapped to all wpf controls in System.Windows.Controls.
The second is http://schemas.microsoft.com/winfx/2006/xaml

It is mapped to System.Windows.Markup that defines the XAML keywords.
The mapping between an XML namespace and a CLR namespace is done by the XmlnsDefinition attribute at assembly level. You can also directly include a CLR namespace in XAML by using the clr-namespace: prefix.


 

<Window xmlns=”http://schemas.microsoft.com/winfx/2006/xaml/presentation”

        xmlns:x=”http://schemas.microsoft.com/winfx/2006/xaml”>

</Window> 
Create simple WPF application
Open Visual Studio 2008 and choose "File", "New", "Project..." in the main menu. Choose "WPF Application" as project type.
Choose a folder for your project and give it a name. Then press "OK"









Visual Studio creates the project and automatically adds some files to the solution. A Window1.xaml and an App.xaml. The structure looks quite similar to WinForms, except that the Window1.designer.cs file is no longer code but it's now declared in XAML as Window1.xaml






Open the Window1.xaml file in the WPF designer and drag a Button and a TextBox from the toolbox to the Window
Select the Button and switch to the event view in the properties window (click on the little yellow lightning icon). Double-click on the "Click" event to create a method in the code behind that is called, when the user clicks on the button.
Note: If you do not find a yellow lightning icon, you need to install the Service Pack 1 for Visual Studio on your machine. Alternatively you can double click on the button in the designer to achieve the same result.






Visual Studio automatically creates a method in the code-behind file that gets called when the button is clicked.

 

private void button1_Click(object sender, RoutedEventArgs  e)

{

    textBox1.Text = "Hello WPF!";

}

 

 
The textbox has automatically become assigned the name textBox1 by the WPF designer. Set text Text to "Hello WPF!" when the button gets clicked and we are done! Start the application by hit [F5] on your keyboard.

 



  Development Tools
Microsoft provides two development tools for WPF applications. One is Visual Studio, made for developers and the other is Expression Blend made for designers. While Visual Studio is good in code and XAML editing, it has a rare support for all the graphical stuff like gradients, template editing, animation, etc. This is the point where Expression Blend comes in. Blend covers the graphical part very well but it has (still) rare support for code and XAML editing.
So the conclusion is that you will need both of them.

Layout of Controls
Layout of controls is critical to applications usability. Arranging controls based on fixed pixel coordinates may work for a limited environment, but as soon as you want to use it on different screen resolutions or with different font size it will fail. WPF provides a rich set built-in layout panels that help you to avoid the common pitfalls.
These are the five most popular layout panels of WPF:

·         Canvas - for specific (X,Y) positioning

·         Stack Panel - for stacking elements horizontally or vertically

·         Wrap Panel - automatically handles wrapping elements to a new row as needed

·         Dock Panel - for familiar docking functionality

·         Grid - for a row and column based layout

·         Uniform Grid - a specialized form of Grid where all cells are the same size

·         Each one is described below, along with a screenshot. I've placed each panel within a group box (not shown in the XAML) in order to demonstrate the boundaries of the panel.

Canvas

              The Canvas panel is used for absolute positioning by specifying pixels relative to the edges of the canvas, In the example below, notice the Canvas.Left and Canvas.Top attached properties on the Textboxes and the and Button.

<Canvas Width="Auto" Height="Auto">

    <TextBox Width="159" Height="26" Text="Name" Canvas.Left="36" Canvas.Top="12"/>

    <TextBox Width="159" Height="26" Text="Password" Canvas.Left="36" Canvas.Top="53"/>

    <Button Width="159" Height="23" Content="Submit" Canvas.Left="36" Canvas.Top="101"/>

</Canvas>
 

 

 

 


StackPanel

The StackPanel, as the name implies, arranges content either horizontally or vertically. Vertical is the default, but this can be changed using the Orientation property. Content is automatically stretched based on the orientation (see screenshot below), and this can be controlled by changing the HorizontalAlignment or VerticalAlignment properties.

<StackPanel Width="Auto" Height="Auto">

    <Button Content="Button" />

    <Button Content="Button" HorizontalAlignment="Left" />

    <Button Content="Button" HorizontalAlignment="Center" />

    <Button Content="Button" HorizontalAlignment="Right" />

</StackPanel>

The StackPanel can also be oriented horizontally.

<StackPanel Width="Auto" Height="Auto" Orientation="Horizontal">

    <Button Content="Button" />

    <Button Content="Button" VerticalAlignment="Top" />

    <Button Content="Button" VerticalAlignment="Center" />

    <Button Content="Button" VerticalAlignment="Bottom" />

</StackPanel>

 

 
 

 



 WrapPanel

The WrapPanel is similar to the StackPanel in that it arranges item sequentially. The WrapPanel will wrap content based on the available space in the panel. Like the StackPanel, the Orientation property controls the primary direction of the layout.

<WrapPanel Width="Auto" Height="Auto">

    <Button Content="Button"/><Button Content="Button"/>

    <Button Content="Button"/><Button Content="Button"/>

    <Button Content="Button"/><Button Content="Button"/>

         <Button Content="Button"/><Button Content="Button"/>

      </WrapPanel>
 

 



DockPanel

The DockPanel is used to anchor elements to the edges of the container, and is a good choice to set up the overall structure of the application UI. Elements are docked using the DockPanel.Dock attached property. The order that elements are docked determines the layout. Here is an example that sets up a typical navigation system: a top menu, a bottom status bar, left and right navigational or informational panes, and a center area that fills the remaining space.

<DockPanel HorizontalAlignment="Stretch" Margin="0, 0, 0, 0" Width="Auto">

    <! -- DOCKED ON BOTTOM TO FILL ENTIRE HORIZONTAL SPACE -->

    <StatusBar Width="Auto" Height="25" Background="#FF451B1B" DockPanel.Dock="Bottom">

        <TextBlock Width="Auto" Height="Auto" Foreground="#FFFEFEFE" Text="Bottom Content"/>

    </StatusBar>

    

    <! -- DOCKED ON TOP TO FILL ENTIRE HORIZONTAL SPACE -->

    <Menu Width="Auto" Height="25" DockPanel.Dock="Top">

        <MenuItem Header="Top Content"/>

    </Menu>

    

    <! -- DOCKED TO LEFT AND RIGHT TO SIMULATE NAVIGATION PANES -->

    <GroupBox DockPanel.Dock="Left" Width="100" Height="Auto" Header="Left Content"/>

    <GroupBox DockPanel.Dock="Right" Width="100" Height="Auto" Header="Right Content" />

    

    <! -- FINAL ELEMENT FILLS REMAINING SPACE -->

    <Canvas Width="Auto" Height="Auto">

        <TextBlock Width="Auto" Height="Auto" Text="Center Content" TextWrapping="Wrap" 

            Canvas.Left="85" Canvas.Top="51"/>

    </Canvas></DockPanel>
 

 

 

 


Grid

The Grid is used to create a table-style layout of rows and columns. If you've ever done any web programming, you'll understand the versatility of a table in organizing the layout. Columns and rows are defined using two property elements: Grid.ColumnDefinitions and Grid.RowDefinitions. The Grid supports column and row spanning, and either absolute, proportional, or auto sizing.
Child elements are assigned to rows and columns using the Grid.Row and Grid.Column attached properties. The following XAML uses a grid to arrange two labels, two textboxes, and a button.

<Grid Width="Auto" Height="Auto">

    <Grid.ColumnDefinitions>

        <ColumnDefinition Width="80" />

        <ColumnDefinition />

    </Grid.ColumnDefinitions>

    <Grid.RowDefinitions>

        <RowDefinition />

        <RowDefinition />

        <RowDefinition />

    </Grid.RowDefinitions>    

    <TextBlock Grid.Row="0" Grid.Column="0" Text="Name:" />

    <TextBox Grid.Row="0" Grid.Column="1" VerticalAlignment="Top" Height="25" />

    <TextBlock Grid.Row="1" Grid.Column="0" Text="Password:" />

    <TextBox Grid.Row="1" Grid.Column="1" VerticalAlignment="Top" Height="25" />

    <Button Grid.ColumnSpan="2" Grid.Row="2" HorizontalAlignment="Center" 

                   VerticalAlignment="Center" Width="100" Height="25" Content="Submit" />

</Grid>

 

 

 


UniformGrid

The UniformGrid is a limited version of the grid where all rows and columns are the same size and where a cell can only hold one control (determined by the grid). Because it's unnecessary to declare each row and column, the UniformGrid contains two properties, Rows and Columns, for setting the number of rows and columns. Controls are added to the grid in the order that they are declared.
The UniformGrid is useful for simple scenarios, but for the most amount of control, you are better off using the Grid.

<UniformGrid Rows="5" Columns="1">

    <TextBlock Text="Name:" />

    <TextBox VerticalAlignment="Top" />

    <TextBlock Text="Password:" />

    <TextBox VerticalAlignment="Top" />

    <Button HorizontalAlignment="Center" VerticalAlignment="Center" Width="100" Content="Submit" />

</UniformGrid>

 
 

Styles
Styles are a means to define a common look and feel to controls. They are similar to CSS style sheets for web pages, but are defined using XAML syntax. Styles are typically defined in the Resources section of a control, panel, or the parent window. They can also be collected into what are known as Resource Dictionaries, and hosted in external files.
To implement a style, follow these steps:

1.      Create a <style> within a Resources collection and give it a key

2.      Create <setter> elements within the style to set properties to specific values

3.      Use the style from an element using the Style attribute

For example, here is a demo which defines two styles as part of a Canvas' resources collection. The style changes the default display of buttons to be 25x100, with a black background and white text. The named style is derived from the first style (style inheritance) and sets the background of the button to Dark Blue instead. The third button references the named style via the Style attribute.

<Canvas>

    <Canvas. Resources>

        <! -- No x: Key specified, so this becomes the default for buttons -->

        <Style TargetType="{x: Type Button}">

            <Setter Property="Background" Value="Black" />

            <Setter Property="Foreground" Value="White" />

            <Setter Property="Height" Value="25" />

            <Setter Property="Width" Value="100" />

        </Style>

        <! -- A style with a key must be referenced explicitly using the Style attribute -->

        <! -- Note also that the BasedOn attribute can be used for style inheritance -->

        <Style x: Key="SpecificStyle" TargetType="{x: Type Button}" BasedOn="{StaticResource {x:Type Button}}">

            <Setter Property="Background" Value="DarkBlue" />

        </Style>

    </Canvas.Resources>

    <Button Canvas.Left="10" Canvas.Top="10">Button 1</Button>

    <Button Canvas.Left="10" Canvas.Top="44">Button 2</Button>

    <Button Style="{StaticResource SpecificStyle}" Canvas.Left="10" Canvas.Top="77">Button 3</Button>

    </Canvas>

 

 

 

 


Effects of TargetType and Key

When creating a style, including or omitting the TargetType and Key have the following effects:

·         TargetType only - style is automatically applied as the default for all elements of that type within scope

·         Key only - style can be applied to different elements. Properties not on the element are ignored. The Setter properties must include "Control." (Eg. Property="Control.Background")

·         Key and TargetType - style can be applied to the target type via explicit use of the Style attribute on the element

Triggers
When applying a style to a control, all properties defined in setter elements are unconditionally applied to the control. If that is not the desired behavior, we can use triggers.

Triggers allow us to define several Setter elements in a style. But, contrary to the previous situation, not all these Setter elements will be applied to the controls using the particular style. The trigger includes a condition, and when that condition is true, the Setters defined in the trigger will be applied. When the condition is false, the Setters are ignored.

There are three types of triggers in WPF:

1.      Property Triggers - run when the value of a dependency property changes

2.      Data Triggers - run when the value of any .NET property changes, using data binding

3.      Event Triggers - run when a routed event occurs

Property triggers

Modern applications make intensive use of interactive UI elements: highlighting buttons when the mouse hovers over them, rollover images. Most of the time, these effects are achieved through the use of some scripting code, like JavaScript in the case of web applications.

In WPF, it’s not necessary to write scripting code. Instead, property triggers can help us create the same compelling effects. Property triggers are, like all triggers defined inside a style, but when applied to a certain object, they fire when a certain property of that object itself changes. This way, one or more properties of the object can be changed.
Let’s take a look at some code examples.

<Style TargetType="{x: Type Button}">
    <Setter Property="Button.Background" Value="AliceBlue" />
    ...
    <Style.Triggers>
        <Trigger Property="IsMouseOver" Value="True">
            <Setter Property="Button.Background" Value="Yellow" />
        </Trigger>
    </Style.Triggers>

</Style>
In this style, we have added the Style.Triggers element, which contains one Setter element, which is not applied by default to the control. The property being checked is the IsMouseOver, and when true, the trigger fires and properties defined in its Setters are applied. In this case, this results in a button that changes color whenever the mouse hovers over it.

There are 2 important things to note. First, we did not have to write any code, it’s all handled by WPF. Secondly, there is no Setter to counteract the first one. When the condition is no longer valid, WPF reverts the control back to its previous state.

We are not limited in the number of triggers included in a Style, and each trigger can have as many Setter elements as we want, like in the next sample.

<Style TargetType="{x: Type Button}">
    <Setter Property="Button.Background" Value="AliceBlue" />
    <Setter Property="Button.Opacity" Value="0.5" /> ...
    <Style.Triggers>
        <Trigger Property="IsMouseOver" Value="True">
            <Setter Property="Button.Opacity" Value="1"></Setter>
            <Setter Property="Button.Background" Value="Green"></Setter>
        </Trigger>
        <Trigger Property="IsEnabled" Value="False">
            <Setter Property="Button.Background" Value="Yellow"></Setter>
        </Trigger>
    </Style.Triggers>

</Style>
Here, we now have 2 triggers, one of which contains 2 Setter elements. The conditions of both triggers are checked and when true, the properties are applied to the control.

So far we’ve had more than one trigger inside a style, but each of them only had one condition to check. What happens when the trigger should only fire when 2 or more conditions are true? For example: only change the background of a button when the mouse is over it AND the button is enabled.

For this purpose, we have so-called
multi-condition property triggers.
Here’s some sample code using a multi-condition trigger.

<Page.Resources>
    <Style TargetType="{x: Type Button}">
        <Setter Property="Button.Background" Value="AliceBlue" />
        ...
        <Style.Triggers>
            <MultiTrigger>
                <MultiTrigger.Conditions>
                    <Condition Property="IsMouseOver" Value="True"/>
                    <Condition Property="IsEnabled" Value="True" />
                </MultiTrigger.Conditions>
                <Setter Property="Button.Background" Value="Yellow" />
            </MultiTrigger>
        </Style.Triggers>
    </Style>
</Page.Resources>
<StackPanel>
    <Button x: Name="WelcomeButton” Content="Welcome user!" ></Button>
</StackPanel>
We used a MultiTrigger element here, in which we specify both the conditions that have to be checked. If needed, more can be added in an analogue manner. One or more normal Setters are applied when all of these conditions are true.

As can be seen, property triggers are a very easy-to-use way to change our application’s interface based on one or more conditions and they help increase the user experience with effects which in the past, cost a lot more effort to create.


Data triggers
As we’ve seen, property triggers are used to check on WPF dependency properties, like the IsMouseOver property. However, there will be times when we have to check the value of a property of a non-visual .NET object, like a self-created User object for example. For this purpose, data triggers come in handy.

In the following sample, we’ll be creating and filling a list box. Each item represents a user, an instance of the User class. Based on the value of the Role property, the user will receive another color. To accomplish this, I’ll use a style with a data trigger that fires whenever the specified condition is true.

Let’s create a User class, with 2 string properties: name and role.

namespace Demo {
    public class User {
        private string name;
        private string role;

        public User(string name, string role) {
            this.name = name;
            this.role = role;
        }

        public string Name {
            get {return name ;}
            set {name = value;}
        }

        public string Role {
            get { return role; }
            set { role = value; }
        }
    }
}
Note the namespace Demo; we’ll need it later on.

Within the same namespace, let’s create a class Users.

public class Users : ObservableCollection<User>
        {
            public Users()
            {
                this.Add(new User("Gill Cleeren", "Admin"));
                this.Add(new User("Steve Smith", "Contributor"));
                this.Add(new User("John Miller", "User"));
            }
        }
This class inherits from ObservableCollection, which represents a dynamic data collection. ObservableCollection provides methods to notify when items are added to or removed from the collection. Since we provide User as type parameter, only User instances can be added to the collection.

Now, let’s get back to the XAML-code. As said earlier, we want to display the users in a list box.

<Page x: Class="Demo.Page1"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    Title="Page1"
    Xmlns: clr="clr-namespace: Demo"
    >
    <Page.Resources>
        <clr:Users x:Key="myUsers" />
        <DataTemplate DataType="{x:Type clr:User}">
            <TextBlock Text="{Binding Path=Name}"/>
            </DataTemplate>
        ...
    </Page.Resources>
    <StackPanel>
        <ListBox Width="200"
                ItemsSource="{Binding Source={StaticResource myUsers}}" />
    </StackPanel>
</Page>
Since we’ll be working with the Users collection in the XAML code, it has to be made available in that context. Therefore, we have to create a mapping between a CLR namespace and a namespace in WPF, using the following syntax.

Xmlns: clr="clr-namespace: Demo"
The namespace Demo is mapped to a namespace in WPF, which is called clr. Note that the name clr is not obligatory.

Within the resources of the Page in the XAML code, we can now use the clr-prefix to have WPF create an instance of the Users class, using the default constructor. The value myUsers, specified in the x:Key attribute, can be used to access the instance.

The DataTemplate is used to tell WPF how it should display a non-visual object like a User. In this case, a TextBlock containing the name will be used.

In the StackPanel, I declare a ListBox. This ListBox will bind its ItemsSource to the Users instance, myUsers, which is a collection of User instances.

Now, let’s add the trigger functionality.

<Style TargetType="{x:Type ListBoxItem}">
    <Style.Triggers>
        <DataTrigger Binding="{Binding Path=Role}" Value="Admin">
            <Setter Property="Foreground" Value="Red" />
        </DataTrigger>
    </Style.Triggers>
</Style>
Here a data trigger is used. The condition whether the trigger should fire is based on the value of the Role property of the specified User object: if it has the value “Admin”, the trigger’s condition will become true, and the property declared within the Setter will be applied.

The TargetType of the Style is ListBoxItem. Whenever the Role property of the User instance to which a ListBoxItem is bound, has the value “Admin”, the foreground will be set to red.

And this is the result, with the first user colored red:






Event triggers
To finish our trigger-tour, we have to make a stop at the event triggers. Event triggers are used to watch for events to happen, like a click-event or a mouse-over event. They are used in combination with animation: whenever the event is raised, the event trigger fires and starts an animation action.
In the sample code, we’ll use an event trigger to react to the mouse-over event for a button.
<Window.Resources>
    <Style TargetType="{x:Type Button}">
        <Setter Property="Width" Value="200" />
        <Setter Property="Height" Value="100" />
        <Setter Property="Margin" Value="20" />
        <Setter Property="HorizontalAlignment" Value="Left" />
        <Style.Triggers>
            <EventTrigger RoutedEvent="Button.MouseEnter">
                <EventTrigger.Actions>
                    <BeginStoryboard>
                        <Storyboard>
                            <DoubleAnimation To="300" Duration="0:0:3"
                  Storyboard.TargetProperty="(Button.Width)" />
                            <DoubleAnimation To="200" Duration="0:0:3"
                  Storyboard.TargetProperty="(Button.Height)" />
                        </Storyboard>
                    </BeginStoryboard>
                </EventTrigger.Actions>
            </EventTrigger>
            <EventTrigger RoutedEvent="Button.MouseLeave">
                <EventTrigger.Actions>
                    <BeginStoryboard>
                        <Storyboard>
                            <DoubleAnimation Duration="0:0:3"
                  Storyboard.TargetProperty="(Button.Width)" />
                            <DoubleAnimation  Duration="0:0:3"
                  Storyboard.TargetProperty="(Button.Height)" />
                        </Storyboard>
                    </BeginStoryboard>
                </EventTrigger.Actions>
            </EventTrigger>
        </Style.Triggers>
    </Style>
</Window.Resources>
<StackPanel>
    <Button x:Name="GrowButton" Content="Hello MSDN" />
</StackPanel>

The style now includes 2 event triggers. The first one will react to the mouse starting to hover over the Button; the second one will react to the mouse leaving the button surface.

When either one of the events is raised, the actions specified for the trigger that reacts to the event, will be executed.
The result is a button that expands both in width and height when hovering over it.


 

Note that we also have to include code that will return the button to its original state here, which wasn’t necessary for the other types of triggers. This is due to the fact that event triggers have no concept of termination of state, so the property won’t be changed back to the state it was in before the trigger fired.
As you can see, using triggers is fairly easy and they make your applications much more interactive, without having to write much code.


If you enjoyed this post, please support the blog below. It's FREE!

Get the latest Asp.net, C#.net, VB.NET, jQuery, Plugins & Code Snippets for FREE by subscribing to our Facebook, Twitter, RSS feed, or by email.

subscribe by rss Subscribe by RSS subscribe by email Subscribe by Email

22 comments :

Anonymous said...

Great tutorial suresh..keep on going...i'm expecting more from you regarding this WPF....

Swati Shelke said...

Hi Suresh! Can you please help me regarding status bar in WPF? how to make it rich looking? and if I want to get a name of object (which is on the User Control)how to do that?

subrat said...

Hi suresh can you please help me some sample with details description on commerce server 2007.I am waiting your responce.

Marthak software solutions. said...

nice article very useful article but if you have any wpf project for learning purpose then post link.
thanks by Software Development>

Anonymous said...

Hey really this is very usefull for me as i am preparing for my interview

Anonymous said...

Hi,
Nice article as I'm new learner of WPF I found it simple & clear to understand. Could it possible to xaml as user control....

Unknown said...
This comment has been removed by the author.
Anonymous said...

very thankful to you for developing this website as so much useful for lot of beginners like me.
Iam raviteja from Bapatla.

Unknown said...

very goooooood.........

Anonymous said...
This comment has been removed by a blog administrator.
Anonymous said...
This comment has been removed by a blog administrator.
Marees said...

Great tutorial Suresh..keep on going...i'm expecting more from you regarding this WPF, Silverlight, MVVM and Prism....

Unknown said...
This comment has been removed by the author.
Anonymous said...

Thnk a lot...I am neophyte..

Rama krishna said...

very nice article for beginners

Anonymous said...

Good one..!!!
could u plz post "Save As" c# code for wpf apps.???

Anonymous said...

Thanks a lot.. Now I understood the basic concept of WPF.
by
Ravi,
Software developer,
Apollo Creative solutions,
Chennai.

Anonymous said...

i am manoj dear suresh great tutorial

Anonymous said...

nbnb

Anonymous said...

good ...

Anonymous said...

Good one

Unknown said...

awesome explanation sir

Give your Valuable Comments

Note: Only a member of this blog may post a comment.

© 2015 Aspdotnet-Suresh.com. All Rights Reserved.
The content is copyrighted to Suresh Dasari and may not be reproduced on other websites without permission from the owner.