Showing posts with label XMAL. Show all posts
Showing posts with label XMAL. Show all posts

Tuesday, May 10, 2011

Transformation in WPF


In this article i am going to explain some basics about transformations in WPF. 

List of different transformation available in WPF

  • Rotate Transform
  • Scale Transform
  • Skew Transform
  • Translate Transform
  • Matrix Transform

Rotate Transform

Rotate transform rotates an element to the specified Angle. To rotate an element to specific degree you can specify value to Angle property of Rotate Transform class. You can also set negative value to rotate an element anticlockwise. You can use CenterX and CenterY properties to specify center point of rotation. By default it takes top left corner of an element as center point and relatively rotation will apply.

    <Canvas>
        <Rectangle Fill="blue" Height="75" Width="75" 
                   Canvas.Left="10" Canvas.Top="50" />
        <Rectangle Fill="blue" Height="75" Width="75" 
                   Canvas.Left="150" Canvas.Top="50">
            <Rectangle.RenderTransform>
                <RotateTransform Angle="25" />
            </Rectangle.RenderTransform>
        </Rectangle>
        <Rectangle Fill="blue" Height="75" Width="75" 
                   Canvas.Left="275" Canvas.Top="50">
            <Rectangle.RenderTransform>
                <RotateTransform Angle="-25" 
                                 CenterX="50" CenterY="50" />
            </Rectangle.RenderTransform>
        </Rectangle>
    </Canvas>



Scale Transform

Scale Transform scales an element by specified ScaleX and ScaleY values. ScaleX and ScaleY value resize the element. If you specify ScaleX to 1.5 then it will scales an element horizontally to 150 percent and same applies to ScaleY. You can also specify CenterX and CenterY properties to specify center point of Scale Transform.

    <Canvas>
        <Rectangle Fill="blue" Height="75" Width="75"
                   Canvas.Left="10" Canvas.Top="50" />
        <Rectangle Fill="blue" Height="75" Width="75"
                   Canvas.Left="150" Canvas.Top="50">
            <Rectangle.RenderTransform>
                <ScaleTransform ScaleX="0.5" ScaleY="0.5" />
            </Rectangle.RenderTransform>
        </Rectangle>
        <Rectangle Fill="blue" Height="75" Width="75" 
                   Canvas.Left="250" Canvas.Top="50">
            <Rectangle.RenderTransform>
                <ScaleTransform ScaleX="1.5" ScaleY="1.5" />
            </Rectangle.RenderTransform>
        </Rectangle>
    </Canvas>



Skew Transform

Skew Transform skews an element by specified AngleX and AngleY values. You can specify AngleX and AngleY properties to skew an element to the angle of x-axis and y-axis. You can also specify CenterX and CenterY properties to specify center point of Skew Transform.

    <Canvas>
        <Rectangle Fill="blue" Height="75" Width="75"
                   Canvas.Left="10" Canvas.Top="50" />
        <Rectangle Fill="blue" Height="75" Width="75"
                   Canvas.Left="120" Canvas.Top="50">
            <Rectangle.RenderTransform>
                <SkewTransform  AngleX="20" AngleY="20" />
            </Rectangle.RenderTransform>
        </Rectangle>
        <Rectangle Fill="blue" Height="75" Width="75"
                   Canvas.Left="250" Canvas.Top="50">
            <Rectangle.RenderTransform>
                <SkewTransform  AngleX="-20" AngleY="-20" 
                                CenterX="75" CenterY="75" />
            </Rectangle.RenderTransform>
        </Rectangle>
    </Canvas>





Translate Transform

Translate transform moves an element based on two X and Y property. It doesn’t move based on center position.  It simply moves an element horizontally(X) and vertically (Y) based on current position.

    <Canvas>
        <Rectangle Fill="blue" Height="75" Width="75" 
                   Canvas.Left="10" Canvas.Top="50" />
        <Rectangle Fill="blue" Height="75" Width="75" 
                   Canvas.Left="120" Canvas.Top="50">
            <Rectangle.RenderTransform>
                <TranslateTransform  X="30" Y="30" />
            </Rectangle.RenderTransform>
        </Rectangle>
    </Canvas>





Matrix Transform


It can be used to create custom 2D transformation. You can create custom transformation using Matrix Transformation which is not provided by above mentioned basic transformation (like Rotate, Scale, Skew and Translate Transformation). You can create Matrix Transformation by using M11, M12, M21, M22, OffsetX and OffsetY parameters. Where M11 and M22 are used to stretch an element, M12 and M21 are used to skew an element and OffsetX and OffsetY are used to position an element.

<Canvas>
        <Button Content="Matrix" Canvas.Top="20" Canvas.Left="20" >
            <Button.RenderTransform>
                <MatrixTransform>
                    <MatrixTransform.Matrix>
                        <Matrix M11="3" M22="3" M12="0.5"
M21="-0.5" OffsetX="20" OffsetY="1" />
                    </MatrixTransform.Matrix>
                </MatrixTransform>
            </Button.RenderTransform>
        </Button>
</Canvas>

You can also create Matrix Transformation by assigning simple string to RenderTransform like this (this applies to only Matrix Transformation).

<Button RenderTransform="3,0.5,-0.5,3,20,1"  
        Content="Matrix" Canvas.Top="20" Canvas.Left="20" />

Where the sequence of comma separated list will be M11, M12, M21, M22, OffsetX and OffsetY.






Multiple Transformations

You can apply multiple transformations to single element. To apply multiple transformations you need use TransformGroup class and inside TransformGroup you can add multiple Transform in it.

    <Canvas>
        <Button Content="Multiple Transformation" 
                Canvas.Top="40" Canvas.Left="20" Width="150" />
        <Button Content="Multiple Transformation"
                Canvas.Top="60" Canvas.Left="20" Width="150">
            <Button.RenderTransform>
                <TransformGroup>
                    <ScaleTransform ScaleX="1" ScaleY="-1" 
                                  CenterX="25" CenterY="12" />
                    <SkewTransform AngleX="10" />
                </TransformGroup>
            </Button.RenderTransform>
        </Button>
    </Canvas>

Hope, you like this post and also helps you to understand more about WPF Transformations. 


Please post your suggestion/queries/feedback in comments if any.

Friday, May 6, 2011

Virtualizing Stack Panel in WPF



To understand Virtualizing Stack Panel first we should understand about what is Virtualization in WPF.

Virtualization in WPF

In Virtualization, elements are created and maintained when they are visible. This also called as UI Virtualization in WPF. Let’s understand with an example.
Let’s assume we have Listbox control with 1 million items and we can see only 10 items at a time. So the only 10 items which are currently visible will get created and maintained by the Listbox. So instead of 1 million items loaded at a time on listbox control it loads only 10 items which are visible. This concept is called as UI Virtualization in WPF. By using Virtualization you will get better performance. In our example you can find performance improvements in loading of data and scrolling of items in listbox. 

VirtualizingStackPanel in WPF

The feature of Virtualization is implemented in VirtualizingStackPanel. It will work similar to the StackPanel and also virtualized its child items too.

By default VirtualizingStackPanel is implemented on ListBox, ListView and TreeView. You can manually enable or disable virtualization on Listbox control by setting VirtualizingStackPanel.IsVirtualizing property. Internally VirtualizingStackPanel creates item container for each visible item. When item is not visible it destroys that item container. So some times with huge data it is very expensive task to create and destroy item container for each visible item.

In dotnet framework 3.5 SP1 Microsoft introduced VirtualizationMode. If you set VirtualizingStackPanel.VirtualizationMode = “Recycling” then each container will get reuse instead of destroy. You will get better performance by specifying VirtualizationMode to Recycling then basic default virtualization. If you don’t specify VirtualizationMode then it will use default basic virtualization.

If you want to create your own Virtualization panel then you can use VirtualizingPanel class available in WPF. But in this case you have to write your own custom logic for creating and maintaining items inside your panel and also need to write logic to remove item once it goes out of scope.

<ListBox Name="ListBoxWithVirtualization" Height="100" Margin="5"
         VirtualizingStackPanel.IsVirtualizing="True"
         VirtualizingStackPanel.VirtualizationMode="Recycling" />


for (int i = 0; i < 1000000; i++)
    ListBoxWithVirtualization.Items.Add("Item - " + i.ToString());

As per above example, you can measure performance when items are loading into Listbox and after loading check scrolling performance of Listbox items as well. Now set IsVirtualizing property to false and measure the same. You will get better performance when IsVirtualizing property set to True.