Control Customization

The whole idea behind WPF architecture was that the presentation layer is completely separate from the functionality. This means a button may look like an image or a circle but still have all the functionality of a button.

Custom Controls

  • Create a new project named CustomControls

  • Before we start customizing a control let’s talk about style and template as this will be required for control customization.
    • Styles – A style is a resource that contains a set of property setters. To see how this works lets create a rectangle on to the design surface. Right click on the rectangle and select Edit Style à Create Empty.

  • Give the style a name and select its location and click on okay

 

  1. The left breadcrumb shows the Layout Root. As we are working with a rectangle we see a rectangle here
  2. The next breadcrumb shows us that we are working with Style. This is represented by an icon that looks like a painter’s palette.
  3. The scope that we are working on has changed to RectangleStyle and the name of the style is RectangleStyle1.
  4. We see only one element as of now which is the style.
  5. All asset creation tools have greyed out as when we work in a style we are restricted to the property of that element which is a rectangle in this case.

 

 

  • Now let us set some the properties of the rectangle which we will be able to see in the style later on. The properties that are changed are highlighted as red.

 

  • Now let us switch to the XAML of the style and we could see a set of setters as a part of the style of the rectangle which contains the name of the property of the rectangle and its value. Also it has a target type which would specify as to which Element type to target to. You can also see how the rectangle refers the style.

 

  • Now just click on the Rectangle in the Breadcrum bar to go back to the Root Document.

 

  • When we right click on the rectangle,we would see option to Edit the current style of the rectangle or edit a copy that style or create a completely new style or apply resource which can be any other style already created.

 

  • Now just create a rectangle onto the design surface and you would see that the Fill is not set for the rectangle the way it is when create a rectangle by default the reason is that blend expects you apply a style to this rectangle as the last rectangle you were working with had a style. So just right click the rectangle and go to Apply resource and select RectangleStyle1.

 

 

 

 

  • Now close your document and open it again and create a rectangle and you would see that the rectangle Fill is set by Blend to default White. Even when you apply the style this white Fill is still there, this is because this fill is set on the rectangle level along with the style and hence overrides the style Fill whereas all the other properties are inherited from style.

 

  • Now just click on the property marker next to the Fill property of the rectangle and select reset and you would be able to the Green Fill of the rectangle again.

 

  • Templates– The limitation of styles is that style can set properties on the element you are working with. This means that if you are working with a rectangle you can apply that style only on a rectangle. Whereas the template property is on the control which sets the entire Visual Tree. All of the visual states and entire stuff that makes the control.
    • Let’s create a button on the panel. When I right click it instead of the edit style option I have Edit template option in which I see option of Edit a copy which will create a copy of the existing default template of the Button and give us to edit and a Create Empty will create a new empty template for us to edit.

 

  • Now when click on Edit a Copy you would see a dialog box like below asking to give a name to the style, its asking to create a style and not a template because you can only apply a style to a control and the template is a part of the style. You can also see the option of apply to all. This option will actually create the style with no name nad apply to all the button in its scope.

 

  1. We are working with the template within the style within the button. You can have a look at the xaml and see that the style has a target type set as button and the setter property template has visual states, border, grid, rectangle, etc which the complete visual tree of the button and will decide how the button looks and behaves.
  2. You can see the Button Visual Tree here.

 

  • Now just right and delete all the elements inside the grid so that we can create the visual of our button from scratch. And then press ctrl + 9 to zoom into the grid we are working on.

 

  • Now add an ellipse and set the alignments to stretch and margins to 0

 

  • Now Go to the assets library and add a couple of rigs to the corners of ellipse. Also now add a textblock on the ellipse and rotate it and make the text as button. Now run the application and you would be able to the button.

 

  • Now go over to the states and we would see how the button looks at various states like mouse over and mouse pressed, which is the same as of now as we have not added any effects. Now let’s change what the button does on mouse over and Pressed. Just select MouseOver in the states and change the color of one of the rings and then select Pressed state and change the color of the other ring. Now run the application and see if the effects work at runtime as well.

 

  • Now let’s add some transition speed. Now select Mouse Over and change the textblock foreground to white and ellipse fill to black and also change the Default Transition speed from 0s to 3s and when we run the application we will see that all the animation states  transition very smoothly.

 

  • Now let’s add a new transition. Click on the Arrow+ in mouse over and we could see the transitions we could use. Select the 1st option.

 

 

  • We can also set the transition effects.

 

 

  • Now you can add new button and apply this style we have created.

 

  • Now if you set the background on the button it will not be applied to the button because it is taking its values from the template. Now we need to modify the template

So that the value is picked up from the control. So go ahead and edit the current template and select the ellipse. Now go to the property marker of the fill and select Template Binding à Background

 

  • When we change that the value will be coming from the parent and not the template as we have template binded the control to parent. Now if we go to the Mouse Over transition we will see that background color is not changed. So we need to decide as to do we want to template bind it to parent of Control Template.
  • Let’s Template Bind the Text of the TextBlock to Button Content. So select the TextBlock in the template and goto Common Propertiesà Text and click on the PropertyMarker and select Content as button being the Content Control we need to bind to the Content of the Button. But this work fine only till our content of the button is text.

 

  • So we have any other content then we should use content presenter for it. So add one to the template and align it to center and reset all the margins and rotate it the way you want.

 

 

Any Comments, feedback or suggestions are most welcome.

 

 

Hope you guys had a look at my other F# posts

In this post i am going to talk about how we can create a Hello World program in WPF using F#.

We would need to manually create and include XAML files in WPF projects, they could also be loaded from code at runtime. We would also need to write the code to hook up event handlers. Let’s get started.

  • Create a new F# application named HelloWorldWPF

 

Create WPF F# Project

Create WPF F# Project

  • There is no way add a xaml file to a console application so either you would need to create an xml file and start editing it or use any other tool (Like Expression Blend) to create a xaml file and then include it in the project. i have used the 2nd option
F# Add XAML File

F# Add XAML File

  •  You can have a look at the xaml file below:
F# XAML File

F# XAML File

  • Lets add the references required by the WPF application. Add a reference to PresentationCore, PresentationFramework, System.Data, System.Deployment
  • Open namespace System, System.Windows and System.Windows.Controls. The let keyword is used for simple values.
  • Create a function that will load my main windows. So lets create a function named loadMyWindow().
  • Then define a new Uri for loading our MainWindow.xaml. This is the standard .Net specification. We don’t need any line terminatio as F# terminaties lines automatically.
  • Then we create a window using the resource loaded in the resourceLocator and then we need to cast this to Window using the F# cast operator.
  • The we find Element which is our clickButton and and we add a function to the Click Event of the Button. In F# we need to also handle all the return vales and hence we have used F# helper function ignore to ignore the values. In F# the last keyword in the function is the return type of the fuction which in our case is a window.
  • Now we would pass this window to the Application.Run and we ignore the retun value as well. We also then apply the STAThread attribute.
WPF HelloWorld

WPF HelloWorld

  •  Now we run the application and this is what we see.
WPF HelloWorld

WPF HelloWorld

 

Any Feedback, comments or questions were most welcome.

 

Hope you guys had a look at my previous F# post

In this post i would be talking about using F# in a Windows Forms application. You should know that there is no designer support for F# so our necessity is to construct Form from  code. Standard Mechanishm like Data Binding work well with F# types.

  • Create a new F# application using Visual Studio named WinFormsHello
F# Project

F# Project

 

  • Go to the references of the application and add a reference to System.Windows.forms and System.Drawing
F# Add Reference

F# Add Reference

 

  • Lets open a namespace System.Windows.Forms. This will have the members of this namespace available for me here without having to reference them again and again.
Open Winforms Namespace in F#

Open Winforms Namespace in F#

 

  • Declare a simple datatype to work with. This particular data types are called as record in F# and when F# recognizes a data type it would use it just like a system data type.
  • Now we create an array of this record type that we just declared. You would see that semi colons are used as separators here. And if you would have worked in C# this declaration might seem a little different to you, so bear with it. The array starts with opening square bracket and a pipe [| and ends with pipe and a closing Square Bracket |].
  •  Now lets create a new form. Now you should keep in mind that F# wants you (as a convention) to use the new keyword for a type if that type implements iDisposable interface. Else we can leave the new keyword. Also you could see that i have passed a named parameter in Form instantiation. Now what this will do is create an instance of Form for me and then try to assign value to the Text Property of the form.
  • Now let’s create a new DataGrid and make its source as myEmployees collection. Also lets add the datagrid to the forms controls.
  • Now let’s pass the form as a parameter to Application.Run command.
WinForms HelloWorld

WinForms HelloWorld

 

  • When we run this application we are able to see our Form with the DataGridView
WinForms HelloWorld

WinForms HelloWorld

 

Any Feedback, comments or questions are always welcome.

 

Hey guys,

I am always exited to learn something new and hope you guys feel the same way. Today i am going to share as to how we can write a Hello World console application in F#. Hope you have VS 2010 installed.

  • Go to File –> New Project

  • Navigate to Other languages –> F# –> Windows –> F# Application
    New F# Project

    New F# Project

     

  •  If you open the references tab you could see a reference to FSharp.Core

 

FSharp.Core

FSharp.Core

  • Now write the following code in program.fs file. You will see that i have added comments along all the lines to explain what each line does.

    Code for F# Hello World Console App

    Code for F# Hello World Console App

  • Press control F5 and you would see the following screen

    Console Screen

    Console Screen

  • Enter some text and press Enter Key and you would see the screen below:

    Console Screen

    Console Screen

Any comments, feedback or questions are more than welcome.

 

Resources in Expression Blend

We will be using Microsoft Expression Blend 4 for this tutorial.

Resources are integral part of WPF and Silverlight. A resource in nothing but a name and value pair. Say for ex  – If I talk to a 2nd grade student and say my phone’s color is #FF000000, he would not understand what’s that that but when I say my phone’s color is black, he might or might not know what I am talking about.

This is the concept used by Microsoft behind using resources. This enables us to think in terms of names and labels as opposed to talking about the values. Let see this working in Expression Blend.

  • Create a new project in Expression Blend and name in Resources.

  • Create a rectangle on to the design surface.

 

  • Go to the properties tab and select the color green. Now when you work for any clients or customer designing applications for them they would have specification of color coding standards they want you to follow. Resources follow the same trend so that you can name your resource and use it at multiple places by just referring its name. We will see how that happens a little later.

 Click on the PropertyMarker as shown in the Image and select ConvertToNewResource. Every property in Blend has a property marker that means we can convert all the property in blend into a resource.   

  • Just name the property as MyGreen and click ok.

  • Now as would notice a couple of things have changed. Instead of the ColorPicker now we see Color resources and the also the list of resources available. Also as you can see the MyGreen is highlighted It is the Color that I am using currently.

 

  • Now just create a Ellipse and by default you would see that the color selected is the MyGreen color as Blend figures out that MyGreen is the color I am working and probably that’s the color I need.

 

  • Now Select the Fill as Gradient Brush

 

  • Now go to the Property Marker for the Gradient Brush and Go To local resource and select MyGreen. As you see are using MyGreen as both a SolidColor and a Gradient Color. The Color is the same but we are using it at different places.

 

  • Now go to the resources tab at the top and expand that user control and you would see that the MyGreen resource is available in the UserControl Scope.

 

  • Now if we change the color here we are able to change the color at all the controls using this resource. So using resource you don’t have to go to each and every control and change the color.

  • Now go back to selection tool and select the Ellipse. Now go to the Fill property marker of the Ellipse and select ConvertToNewResource.

  • Name it as BlackToMyGreen.

  • Now we see a Local Brush resource is available. You should know that a color is just is a 24bit value that probably represents some transparent color in the spectrum but a brush can be a single color or a set color or something else.

 

  • Now let’s go back to the Resources tab and expand the UserControl again and change the MyGreen to some other value. Now you would see that not only MyGreen has changed but also the BlackToMyGreen has also changed, so this implies that resources can use other resources as well.

              

 

Scope of Resources in Expression Blend

Now let’s talk about Scope of resources. Scope of a resource simply means where are we going to look when we are getting a concept. Let’s talk about a 2nd grader to whom we say my phone is black. Now he might know what is black, if that’s the case he is going immediately know what color you are talking about. Let’s say he doesn’t know what is black so he’s going ask his parents. Maybe his parents are able to answer it or they then go to their parents and ask what does black mean? This is exactly what scope means. You can define a concept at any level – object level, on a parent, on a document, in an application or a resource dictionary. Now when we say MyGreen then Silverlight or WPF will be able to figure out what is MyGreen. 

Let’s see this with the help of an example: 

  • Delete the rectangle and grid in the application we are working on and draw 2 identical Grids as shown below:

 

  • Now select the left grid and go to its properties. And select the background as Green.

 

  • You can click on the shortcut key and convert a color to resource.

 

  • And we will name it Grass and we will define it in the grid instead of the usercontrol. 

  

  • Now give a background to the other grid and create a new color resource in that grid named as Grass.

 

  • Clear the brush on both the grids using the shortcut below: 

 

  • Create a rectangle in one of the two grids. And using the color resources make the Fill of the rectangle as Grass. 

 

  • Now using the selection tool drop the rectangle from one grid to another by keeping the alt key pressed. 

 

  

  • What you see now is that the rectangle is using the local Resource Grass. Whenever an element is trying to figure out the meaning of the defined resources, it first looks into its own defined resources, then its parent resources and if it still is not able to find it will look further up till the root of the UserControl. And if still it is not able to find it there it will look for it in the application resources. But if a resource is defined at multiple levels then the closest one is adopted by the element. i.e. the resource is defined at a parent level as well as the application level then one the parent returns the meaning of the resource then the element stops looking and uses the same.

 

  • Let’s take another rectangle and drop it on the panel and this rectangle also uses the Fill as Grass but is not able to find it. That’s because the Rectangle does not know what Grass is, it asks LayoutRoot but LayoutRoot also does not know what Grass is, then it asks the UserControl which still does not know what grass is. So the unresolved resource gives us a blank fill.

 

  • Let’s go ahead and give it a SolidColorBrush and set the alpha value of it to 100 as whenever we get an unresolved resource blend gives it a transparent white brush. 

  

  • Now convert this to resource and select it to save at the application level.

 

  • Let’s go the resources tab and we see that Grass is defined as different color for different levels.

 

 

Resource Dictionary in Expression Blend

 

Let’s again talk about our 2nd grader who went to his parents to ask what is black, who in turn ask their parent as to what is black. Say their parent also does not know what is black so what they would do is grab one of the reference guides or resource dictionary and look for black color, if that resource dictionary does not have an answer for blue then they will check in other available resource dictionaries. In this case a Resource Dictionary is a single xaml file that contains key value pairs in it.

Let’s have a look at this with the help of an example:

  • Create a new solution in Blend named ResourceDictionaries and create a rectangle in it.

  • Convert that into a resource. But we will define it in a new ResourceDictionary.

 

  • As Soon as we do that a new xaml is added to the project. The reason for giving description of MyGreen here instead of the application level is the same as printing all the information in the book in the 2nd grader example. We can very easily transfer this dictionary to a different application.

 

  • Let’s just create a couple of more dictionaries. Right click the project and select Add new item and select Resource Dictionary and click ok.

 

  • Now we go the rectangle and change the fill color and save it into the resource dictionary 2. Change the color again and save it to the resource dictionary 3.

 

  • Now Delete the rectangle and just drag and drop a new one. What you will see is that this rectangle’s fill is yellow i.e. the color from the last resource dictionary. This happens because Blend creates a merged dictionary. So when a resource is found in a resource dictionary the element will look for any other occurrences of the same resource in all the resource dictionaries and will override the previous values with the new one. Below is how the resource dictionaries look like.

 

  • We can add or remove reference to a resource dictionary using the interface below.

 

  • And when we do the colors will follow a fallback mechanism.

 

I would like to state here that as of now i.e. Silverlight 4 all the resources are static resource and will take the value at the time instantiation. Where as in WPF we do have Dynamic Resources and at runtime everything will update.

Please find the source sode for the soultions at location below:

http://i.minus.com/1337680217/iM-3YUH7dLJB6ELGpiplpQ/dbuofcNvmgf7Uz.zip

http://i.minus.com/1337680215/Uq65IIajg7rV01b2c715dQ/dbvtJW3hnSasrW.zip 

Any comments, feedbacks or question are most welcome.