Friday, 5 September 2014

Difference between Free and FreeAndNil in Delphi: What to use when?

Difference between Free and FreeAndNil in Delphi: What to use when?

Free and FreeAndNil are the main concepts of memory management in Delphi. FreeAndNil is a function declared in the SysUtils unit and was introduced in Delphi 5. Below is the implementation of FreeAndNil:

procedure FreeAndNil(var Obj);
var
  Temp: TObject;
begin
  Temp := TObject(Obj);
  Pointer(Obj) := nil;
  Temp.Free;
end;

Difference between Free and FreeAndNil: 

FreeAndNil first sets the object reference to nil and then frees the object. 

When to use FreeAndNil instead of Free?

If you want a rational answer, the question to ask is, why would you want to set an object reference to nil once you’re done with it?  And there’s only one good reason to ever do that: If you want to reuse the variable later.  There are some times when you’ll have an object that may or may not be initialized. If it’s not, then the variable will be nil, and if you find it’s nil, then you create it before using it.  This is a pretty common pattern.  It’s called “lazy creation”.  But every once in a while, you want to use lazy creation on an object, then destroy it and create it again. This is when FreeAndNil comes in handy.

Use FreeAndNil for Defensive Programming

You can compare FreeAndNil with seat (safety) belts in cars: if you application runs normally - then FreeAndNil won’t be useful. But if your code mess up with something - then FreeAndNil (as seat belts too) will protect you from consequences. By clearing the reference, FreeAndNil will help you to catch your wrong access immediately. Without it (i.e. by using Free only), your code may continue to run (even without raising an exception) and will give the wrong results or damage global state. It is quite dangerous situation and may lead to corrupt your data too. By not setting it to nil (in case of Free)- you're lying to the compiler. You're telling that there is allocated memory at this location, and the truth is that it isn't. And lying to machine just isn't good. FreeAndNil is very strict in these situation will immediately give you Access Violation error which I think is good thing and you can fix the problem on the spot because you know the problem!! Compare this with case, when your code silently produce wrong results! By always using FreeAndNil you’ll make your code bullet-proof for modifications.

Example of FreeAndNil

var
  myList : TList;
begin
  try
    myList := TList.Create;
    ....
    ....
  finally
    FreeAndNil(myList);
  end;
end;

Sunday, 31 August 2014

Difference between Override and Reintroduce in Delphi

Difference between Override and Reintroduce in Delphi

When you decide to declare a method as virtual, you are giving permission to derived classes to extend and override the method with their own implementation.

Use the reintroduce keyword to introduce a new implementation of a parent method (this hides the parent method). You can hide a method without using reintroduce but you will get a compiler warning. Using reintroduce will suppress the warning.

You tell the compiler that you know that you hide the ancestor function and replace it with this new function and do so deliberately.

Difference between Override and Reintroduce

1. The reintroduce and override modifiers have different meanings. The reintroduce modifier creates a new member with the same name, signature, and visibility and hides the original member. The override modifier extends the implementation for an inherited member and allows you to implement inheritance-based polymorphism.

2. Override is used in conjuction with Virtual/Dynamic methods of parent class but for Reintroduce, parent method should not be necassarily Virtual/Dynamic. 

The only reason to override an ancestor method is that you can call inherited from within the descendent method. If you don't intend to call inherited from within a descendent method, the descendent method should be declared with Reintroduce rather than Override.

Avoid Reintroduce

Sometimes there are clear reasons to introduce a new method with the same name, signature, and visibility of a parent method. In those clear cases, introducing a new member is a powerful feature. However, if you do not have a clear reason, then avoid using Reintroduce.

Saturday, 30 August 2014

Difference between Virtual, Dynamic and Abstract methods in Delphi

Difference between Virtual, Dynamic and Abstract methods in Delphi

Virtual and Dynamic methods are the strong concepts of Polymorphism in Delphi. Dynamic is semantically equivalent to Virtual. Both Virtual and Dynamic directives allows a class method to be override (replaced) by a same named method in a derived class. 

You would mark a function or procedure as Virtual or Dynamic when you allow a programmer who creates a class based on your class to replace its functionality. 

Virtual and Dynamic may be followed by the Abstract directive. This modifies the effect of the Virtual and Dynamic directives. It means that the current class must not code the method - it is there only as a placeholder to remind and ensure that derived classes implement it.

Difference between Virtual and Dynamic methods in Delphi

Although Virtual and Dynamic methods appear same but there is some differnce in their internal implementation. Virtual methods are implemented with a Virtual Method Table (VMT). There is one VMT for each class. The VMT contains one entry for each virtual method in the class. And that entry is the address of the method.

This allows for very efficient calling. You simply get the address of the VMT which is located at a fixed offset from Self. Then you look up the method pointer by index and call the method.

What this does mean is that if you have a class with a lot of virtual methods, and you derive a sub-class, you will make a brand new VMT with all the virtual methods. And if you have not overridden many of them, then you'll find that the VMTs have a lot of overlap.

This used to matter in the days of 16 bit. The VMTs could take up a lot of space in the executable image (that's what is meant by code size) and you could run out of space for the VMTs. So dynamic methods were introduced. The analogue to the VMT is the dynamic method table, DMT. This is implemented differently to avoid the repetition when methods are not overridden. The downside is that calling dynamic methods is more expensive.

In modern times, since 32 bit, and especially with the very fat executables that Delphi produces, these size issues don't matter. And so all sound advice is to use virtual methods exclusively.

Abstract methods must be virtual or dynamic

Any abstract method should be virtual or dynamic. For example:

function Age: Integer; Abstract;

will not work and throw following error:

E2167 Abstract methods must be virtual or dynamic

Conclusion: Virtual methods are optimized for speed and dynamic methods are optimized for size. In most of the situations, speed is more crucial than size, so I would prefer to use Virtual methods.

Friday, 29 August 2014

Difference between Owner and Parent in Delphi

Difference between Owner and Parent in Delphi

Parent is the Window control where the control is displayed. Owner is the component responsible for making sure it's destroyed. Parent refers to the component that another component is contained in, such as TForm, TGroupBox or a TPanel. If one control (parent) contains others, the contained controls are child controls of the parent.

Example of Owner and Parent

Whenever we try add a button on a panel in a form, we try to make an invisible connection between the components. When a component is dropped on a form at design time, the owner is the form and the parent is the container on which it is dropped.

As we add the button on the panel, the panel automatically is set as the parent of the button while the form becomes the owner.  

Another example, drop a group box on a form. Its owner and parent are both the form. Drop a check box on the group box. Its owner is the form and its parent is the group box.

Parent is required to make a control visible

For a component to be visible, it must have a parent to display itself within. Controls that appear on the screen need to know where to paint themselves, hence the parent property. It specifies the visual container for the control. This property must be specified before a control can be displayed. When you want to create a TButton at run-time, it is important that we remember to assign a parent - the control that contains the button. 

The Parent component on the other end determines how the child (i.e. contained component is to be displayed). All the properties like left, top etc are relative to the parent component.

Owner is Readonly while Parent can be changed

Owner property is a read only property and cannot be modified, however parent for a control can be assigned and chagned easily at runtime. The Owner is being set while invoking the create constructor and becomes a read-only property so can't be changed later on.

Allocating and Freeing the memory

The Owner component is responsible for freeing the allocated memory of the owned components. Form is the owner of all the components residing inside it. So whenever the form is destroyed, all the components memory is freed automatically. This is the purpose of ownership.

HasParent Property

Not all components have the Parent. Many forms do not have a Parent. For example, forms that appear directly on the Windows desktop have Parent set to nil. A component's HasParent method returns a boolean value indicating whether or not the component has been assigned a parent.

Parent Property

We use the Parent property to get or set the parent of a control. If we try to create a new control, then we need to set the parent property of the control to make it visible. For example, 

Button1.Parent := Panel1;

Above code has set Panel1 as the parent of Button1.

Difference between Components and Controls in Delphi

Difference between Components and Controls in Delphi

Controls are the visible elements on the Delphi Forms to which you can focus and interact. All the controls are components and vice versa is not true. So we can say that Controls are the subset of Components in Delphi.

TComponent is the common ancestor of all component objects in Delphi. TControl is the abstract base class for all visual components. Everything that goes into the component palette is a Component. Everything that goes into the component and is something that the user of the program can control by using mouse or keyboard is a Control.

For example: TTimer component is a component that you can place on a form, but it is not visible to the end-user. So TTimer is only the component but not a control in Delphi. Other examples like TTimer are TXMLDocument, TDatabase, TQuery, TTable, TDataSet, TDataSource etc. These all components play a vital role but never appear in front of the end user.

A TEdit or TButton is visible and can be controlled by the user (you can add events to TEdit and TButton and with those events a user can actually focus/select/click on the TEdit and TButton components). So both TEdit and TButton are the components as well as controls in Delphi. 

A control takes up more resources than a component because a control needs extra info about how to draw itself.

Thursday, 21 August 2014

How to create and extract ZIP files in Delphi XE6?

How to create and extract ZIP files in Delphi XE6?

Delphi provides System.Zip unit for creating ZIP files. System.Zip unit contains a simple ZIP extractor and creator class named TZIPFile. TZIPFile class mainly has three methods which are used to create and extract zip files:

ZipDirectoryContents: Creates the zipped file
IsValid: Validates the zip file
ExtractZipFile: Extracts the zip file

Following is the code snippet in Delphi to create a zip file.

uses System.Zip;

TZIPFile.ZipDirectoryContents('C:\FolderToZip', 'C:\ZippedFolder.zip');

Following is the code snippet in Delphi to extract a zip files. 

uses System.Zip;

ZipFile := 'ZippedFolder.zip'; //This is my zip file
if TZipFile.IsValid(ZipFile) then //Validate zip file
begin
  TZipFile.ExtractZipFile(ZipFile, 'C:\DestinationDirectory'); //Extract the zip file
end
else
begin
  ShowMessage('Zip File is not valid');
end;

Friday, 1 August 2014

How to create XML document in Delphi XE4 using IXMLDOCUMENT and IXMLNODE?

How to create XML document in Delphi XE4 using IXMLDOCUMENT and IXMLNODE?

Following is the self explanatory code in Delphi XE4 to create XML document using IXMLDOCUMENT and IXMLNODE interfaces. You should have XMLIntf and XmlDoc units in your uses section. Following CreateXMLinDelphi Delphi procedure creates an XML named MyXML in D drive.

procedure CreateXMLinDelphi;
var
  XML : IXMLDOCUMENT;
  RootNode, CurNode : IXMLNODE;
begin
  XML := NewXMLDocument;
  XML.Encoding := 'UTF-8';
  XML.Options := [doNodeAutoIndent];
  RootNode := XML.AddChild('ParentNode');
  CurNode := RootNode.AddChild('ChildNode1');
  CurNode.Text := 'ChildNode Text 1';
  CurNode := RootNode.AddChild('ChildNode2');
  CurNode.Text := 'ChildNode Text 2';
  XML.SaveToFile('D:\MyXML.xml');
  ShowMessage('XML created successfully');
end;

The above code generates following XML document:

<?xml version="1.0" encoding="UTF-8"?>
<ParentNode>
  <ChildNode1>ChildNode Text 1</ChildNode1>
  <ChildNode2>ChildNode Text 2</ChildNode2>
</ParentNode>

How to create an XTR file from XML in Delphi XE4 using XML Mapper?

How to create an XTR file from XML in Delphi XE4 using XML Mapper?


By using Delphi XE4 RAD Studio, you can create an XTR file from the given XML file using XML Mapper. XML Mapper Tool is provided in RAD Studio XE4 under Tools -> XML Mapper.

Following are the steps to create an XTR file from XML in Delphi XE4 using XML Mapper:

1. Open the XML Mapper Tools from RAD Studio. 


Now load an XML. In my case I am loading following simple XML:

<?xml version="1.0" encoding="UTF-8"?>
<Parent>
  <Child1>ABC</Child1>
  <Child2>XYZ</Child2>
</Parent>

All the nodes will appear on the left section of XML Mapper.

2. Right click on left section and select "Select All Children" option. Transformation will be created on the middle section.

3. Right click on left section again and select "Create Datapacket from XML". You will see the generated datapacket on the right section of the XML Mapper.

4. Hit "Create and Test Transformation" button in the middle section of XML Mapper.

5. Right click on the right section and select "Clear". A popup will appear asking you "Save changes to Transformation to Datapacket?".

6. Click Yes and save that XTR file.

I got following XTR file corresponding to the above XML file:

<XmlTransformation Version="1.0"><Transform Direction="ToCds" DataEncoding="UTF-8"><SelectEach dest="DATAPACKET\ROWDATA\ROW" from="\Parent"><Select dest="@Child1" from="\Child1"/><Select dest="@Child2" from="\Child2"/></SelectEach></Transform><XmlSchema RootName="Parent"><![CDATA[<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema">
  <element xmlns="http://www.w3.org/2001/XMLSchema" name="Parent" type="ParentType"/>
  <complexType xmlns="http://www.w3.org/2001/XMLSchema" name="ParentType">
    <sequence>
      <element name="Child1" type="Child1Type"/>
      <element name="Child2" type="Child2Type"/>
    </sequence>
  </complexType>
  <element xmlns="http://www.w3.org/2001/XMLSchema" name="Child1" type="Child1Type"/>
  <simpleType xmlns="http://www.w3.org/2001/XMLSchema" name="Child1Type">
    <restriction base="xs:string"/>
  </simpleType>
  <element xmlns="http://www.w3.org/2001/XMLSchema" name="Child2" type="Child2Type"/>
  <simpleType xmlns="http://www.w3.org/2001/XMLSchema" name="Child2Type">
    <restriction base="xs:string"/>
  </simpleType>
</xs:schema>]]></XmlSchema><CdsSkeleton/><XslTransform/><Skeleton><![CDATA[<?xml version="1.0"?><DATAPACKET Version="2.0"><METADATA><FIELDS><FIELD attrname="Child1" fieldtype="string" WIDTH="3"/><FIELD attrname="Child2" fieldtype="string" WIDTH="3"/></FIELDS><PARAMS/></METADATA><ROWDATA/><METADATA><FIELDS><FIELD attrname="Child1" fieldtype="string" WIDTH="3"/><FIELD attrname="Child2" fieldtype="string" WIDTH="3"/></FIELDS><PARAMS/></METADATA><ROWDATA/></DATAPACKET>
]]></Skeleton></XmlTransformation>

Friday, 4 July 2014

EOleException error raised with message catastrophic failure or access is denied in Delphi

EOleException error raised with message catastrophic failure or access is denied in Delphi

While calling DLLs from my application using safecall, I was getting EOleException error raised with message catastrophic failure. When I switched to stdcall, I started getting EOleException error raised with message access is denied for some calls. So, I thought to dive deep into the root cause of the error and tried to understand what exactly EOleException is in Delphi?

As per documentation:

EOleException is the exception class for OLE automation errors that occur in methods or properties of an object.

EOleException is the exception class for errors specific to the OLE IDispatch interface.

EOleException is raised when an error occurs in the middle of a method call from IDispatch. EOleException is generated when a server receives a failure return value from a property or method that was called with the IDispatch interface Invoke method.

When an error occurs, objects invoked through IDispatch can return essential information about the exception, including the source of the error, error code, description, help file, and ID number for context-sensitive help. EOleException captures this information, and the error description and ID number (if available) are included in a message generated by the constructor; the other information is stored in the Source and HelpFile properties defined for EOleException and the ErrorCode property inherited from EOleSysError.

Solution:

1. Try catching the error

try
  ....
  ....
except 
  on e: EOleException do
  begin
    ....
    .... 
  end;  
end;

2. Ignore the error

To stop Delphi from breaking, you will need to configure Delphi to ignore the exception by telling it that the application will handle the exception. Go to Tools > Debugger Options, on the "Language Exceptions" tab add "EOleException". Ensure that it is ticked, which tells the Delphi environment to ignore the exception (and let the code run).

Wednesday, 25 June 2014

WPF Page Hosted Windows Applications and XAML Browser Applications (XBAPs)

WPF Page Hosted Windows Applications and XAML Browser Applications (XBAPs)

In WPF, you can also make page based applications. These page based applications are of two types:

1. Pages Hosted in Windows Application
2. Stand-alone XAML Browser Application(XBAPs)

Lets try to understand these WPF Page based applications:

1. Pages Hosted in Windows Application

In this approach, you create your windows application and host some of the pages in that Windows application using NavigationWindow or Frame. This approach is generally used in WPF applications to integrate some kind of wizard in your application, to show some help contents and documentation.

Hosting Pages in Navigation Window

System.Windows.Controls.Page class is used as top level container instead of Windows. 

<Page...>
...
...
</Page>

But actually, there is one more top level container known as NavigationWindow (derives from Windows class) in which Page container is hosted. The NavigationWindow looks like an ordinary window aside from the backward and forward buttons that appear in the bar at the top. Page class is derived directly from FrameworkElement class. You can add a page to any WPF project. Just choose Project --> Add Page in visual studio.

Hosting Pages in other Window

You have to use Frame class to host your page inside other windows. You can use several frames in your window. You have to use the Source property of the Frame class to point to the page which you want to host.

<Window...>
  ....
  ....
  <Frame Source="Page2.xaml"></Frame>
  ....
  ....
</Window>

Hosting Pages in other Pages

You can also host your page into another page. Again you have to use Frames for this task. Just keep a frame container in other page where you want to host your page.

Ways to move from one page to another:

1. Forward and Back Button:

Set Page.ShowNavigationUI property set to true to show the forward and back button. By default, the property is set to true. There is also one more property called NavigationUIVisibility property which you can use to hide/show the Navigation buttons. By default its value is Automatic. But you can set it to Hidden or Visible as per your need.

2. Hyperlinks

Hyperlinks include NaviageUri property using which you can jump from one page to another.

Example: 

Navigating to other page: 

<Textblock>Click <Hyperlink NavigateUri="Page2.xaml">here</Hyperlink></TextBlock>

Fragment Navigation: Navigating to other page and at specific control on that: 

<Textblock>Click <Hyperlink NavigateUri="Page2.xaml#myTextBox">here</Hyperlink></TextBlock>

You will land on Page2.xaml and scroll up to the myTextBox control. But myTextBox control will not have any focus.

Navigating to websites:

<Textblock>Click <Hyperlink NavigateUri="http://theprofessionalspoint.blogspot.com">here</Hyperlink></TextBlock>

2. Stand-alone XAML Browser Application(XBAPs)

Page Based Applications run directly on IE or Firefox and you don't have to install this application. Just point your browser to correct location. This model is called XBAP. Client system must have .NET framework installed to run the XBAP application. The XBAP applications have limited permissions like XBAP applications cannot write files, cannot interact with system resources and registry, cannot connect to databases etc. But you can give permissions to XBAP applications when required.

To create XBAP application, you have to choose WPF Browser Application template in Visual Studio. After that if you see csproj file, you will find these four elements which point that it is a XBAP application:

<HostInBrowser>True</HostInBrowser>
<Install>False</Install>
<ApplicationExtension>.xbap</ApplicationExtension>
<TargetZone>Internet</TargetZone>

Related Article: To know the difference between Windows and Page Controls, visit my previous post.

Saturday, 7 June 2014

Localization and Satellite Assemblies in WPF: How to support Localization in your WPF application?

Localization and Satellite Assemblies in WPF: How to support Localization in your WPF application?

In WPF applications, the unit of localization is the XAML file (technically, the compiled BAML resource that is embedded in your application). If you want to support three languages, you need to include three BAML resources. Satellite assemblies play an important role in localization of WPF applications. When you create a localized WPF application, you place each localized BAML resource in a separate satellite assembly.

To add localization support to your WPF application, just go to your .csproj file and add <UICulture>en-US</UICulture> under <PropertyGroup> element. Now Build your project and you will get a folder named en-US created where your exe is placed. 

If you go inside this folder, you will get an assembly with the same name as that of your exe but with different extensions. For example, if your application exe name is MySampleApplication.exe, its name would be MySampleApplication.resources.dll. This is called satellite assembly.

Now if you closely examine the size of your exe, it would be reduced because the BAML file is not embedded to it, but it is now contained in the satellite assembly which you just created.

When you run this application, the CLR automatically looks for satellite assemblies in the correct directory based on the computer's regional settings and loads the correct loacalized resource.

For example, if you are running in the fr-FR culture, the CLR will look for an fr-FR subdirectory and use the satellite assemblies it finds there.

Note: Extension for satellite assembly is .resources.dll.

How to localize your WPF application?

Step 1 (msbuild and Uid)

Add UID attribute to all the elements in your WPF application, you want to localize. You can use MSBUILD for adding the UID attribute to all elements used in your all the XAML files througout the application.

msbuild /t:updateuid MySampleApplication.csproj

Step 2 (LocBaml)

To extract the localizable content of all your elements, you need to use the LocBaml command-line tool. To extract the localizable details, you point LocBaml to your satellite assembly and use the /parse paramenter as shown here:

lcobaml /parse en-US\MySampleApplication.resources.dll

A .csv file will be generated named MySampleApplication.resources.csv

Step 3 (Build Satellite Assembly for other cultures e.g. fr-FR)

Again use locbaml tool with /generate parameter to create a satellite assembly with culture fr-FR.

locbaml /generate en-US\MySampleApplication.resources.dll
               /trans:MySampleApplication.resources.French.csv
       /cul:fr-FR /out:fr-FR

Friday, 6 June 2014

WPF Elements and Controls: Basic Concepts and Questions

WPF Elements and Controls: Basic Concepts and Questions

In this article, I have covered very basic concepts of WPF Elements and Controls in the form of questions and answers like the difference between elements, controls, content controls, headered content controls and layout containers, difference between tooltip and popup, difference between radiobutton and checkboxes, lexicon file etc. Last question illustrates the difference between resource files and content files in WPF (this question is out of the blog post title as these files are not WPF elements).

1. What is the difference between WPF Elements and WPF Controls?

There is a difference between WPF Elements and WPF Controls. All the WPF Controls are WPF Elements but vice-versa is not true. Any WPF element which can receive focus and accepts inputs from keyboard or mouse is called WPF Control.

For example: Textbox, Button are WPF Controls.

Exceptions: Tooltip and Label are also considered as WPF Controls because Tooltip appears and disappears depending on user's mouse movement. Similarly, Labels support mnemonics (shortcut keys), that's why Labels are also considered as WPF Controls.

Note: All the WPF Controls are derived from System.Windows.Control class.

2. What is the difference between WPF Controls and WPF Content Controls?

A WPF Content Control is the Control that can hold and display a piece of content.

For example: Button, RadioButton, CheckBox, Label, Tooltip, ScrollViewer, UserControl, Window etc.

Note: All the WPF Content Controls are derived from System.Windows.ContentControl Class.

3. What is the different between WPF Content Controls and Headered Content Controls?

Headered Content Controls are the Content Controls which have both content region and header region which can be used to display some sore of title.

For example: GroupBox, TabItem and Expander

Note: All the WPF Headered Content Controls are derived from HeaderedContentControl class.

4. What is the difference between WPF Content Controls and WPF Layout Containers?

WPF Content Controls can contain only a single nested element while layout containers can contain as many nested elements. You can also take a lot of elements in Content Controls but the condition is that all the elements should be wrapped in a single parent layout container like stackpanel or grid.

5. What is the difference between Label and Textblock in WPF?

Label and Textblock are used to display the content on the screen. The basic difference is that Label support mnemonics (shortcut keys) while Textblock does not. If you do not want shortcut features, you can simply use Textblock as it is lightweight and also supports text wrapping which label does not.

6. What is the different between RadioButton and CheckBox in WPF?

You can do grouping in RadioButton but not in CheckBoxes.

For example: If you place 3 radio buttons in a stack panel, all the radio buttons in that stack panel are grouped i,e you can select any one of them but that feature is not there in CheckBoxes.

Note: Button, RadioButton and CheckBox are derived from ButtonBase class. Further, RadioButton and CheckBox are derived from ToggleButton class.

7. What is the different between Tooltip and Popup in WPF?

There are many differences between WPF Tooltip and Popup:

A) You cannot put user interactive controls in Tooltip as it cannot accept focus but same is possible in Popup.

B) Tooltip is opened and closed automatically when mouse is hovered but Popup does not.

8. How will you get the list of all the fonts installed on your system in WPF?

I will use static SystemFontFamilies collection defined in the System.Windows.Media.Fonts class.

foreach (FontFamily fontFamily in Fonts.SystemFontFamilies)
{
  lstFonts.Items.Add(fontFamily.Source);
}

9. What is the lexicon file in WPF? What is its use?

Lexicon file with exetension .lex is used to create customize the dictionary which is used for spell checking feature in WPF. In your WPF application, when you enable spell checking feature, WPF uses its default dictionary to recognize the words. If you want to add some extra words to that dictionary, you will have to create a lexicon file and add your words there. WPF supports dictionaries in English, German, Spanish and French.

10. What is the difference between Resource Files and Content Files in WPF?

1. Resource files are embedded into the assembly (exe or dll) while content files do not embed with assembly.

2. Content files are used instead of resource files in following scenarios:

A) You want to change the resource file without recompiling the application.
B) The resource file is very large.
C) The resource file is optional and may not be deployed with the assembly.
B) The resource file is a sound file.

How to make a resource file? Just add a file (say any image file) and set its Build Action to Resource (which is by default) in Properties Window.

How to make a content file? Just add a file (say any image file) and set its Build Action to Content in Properties Window. Set Copy to Output Directory to Copy Always.

For example: Suppose you have added a .jpg file of 30KB to your application as a resource. After you Build your application, you will notice an increase of approximately 30KB size in your exe. But if you use same file as content, there will be no increase in the size of exe, but you will notice that same file will be copied in the exe directory.

Related articles: I have written two posts on commonly asked WPF questions and answers. If you are looking for something like that, you can visit Part 1 and Part 2.

Tuesday, 3 June 2014

WPF XAML: Property-Attribute and Property-Element Syntax for Simple and Complex Properties

WPF XAML: Property-Attribute and Property-Element Syntax for Simple and Complex Properties

Property-Attribute and Property-Element are the two approaches in WPF XAML to set the properties of the elements. I will take a very simple example to clear the concepts of both of the Property-Attribute and Property-Element approaches. Lets try to set the background property of the grid. I want to fill the background of the grid with some gradient color. Lets see how can we do this using XAML in WPF?

Suppose I have to set the background of the grid to Green. I will set it like this:

<Grid Name="MyGrid" Background="Green">
....
....
</Grid>

In the above case, I have used Property-Attribute syntax for setting the Background property. WPF has used default brush and painted the area with solid color. But what if you want to use some complex brush and want to paint the background with gradients instead of simple solid color? 

In this scenario, you will have to use Property-Element syntax defined in WPF XAML. Property-Element syntax is represented as ElementName.PropertyName. For example, you have to use Background property in this case as Grid.Background.

So, to introduce gradients in my example, I will have to use LinearGradientBrush instead of the default brush used by WPF for solid fill.

<Grid Name="MyGrid">
  <Grid.Background>
    <LinearGradientBrush>
     <LinearGradientBrush.GradientStops>
       <GradientStop Offset="0.00" Color="Red" />
<GradientStop Offset="0.50" Color="Indigo" />
<GradientStop Offset="1.00" Color="Violet" />
     </LinearGradientBrush.GradientStops>
</LinearGradientBrush>
  </Grid.Background>
</Grid>

In the above example, I have chosen different gradient colors (Red, Indigo and Violet) to paint the background of the Grid.

With this, I think I have cleared the concept of Property-Attribute and Property-Element syntax used in WPF XAML.

Monday, 2 June 2014

WPF XAML Namespaces, Prefixes and Conventions

WPF XAML Namespaces, Prefixes and Conventions

In WPF, XAML contains namespaces for defining controls for your XAML document. You can also map other .NET namespaces to XML namespaces and use them in XAML document. There are some conventions for using prefixes with these namespaces in XAML. Lets go point to point to explore everything about XAML namespaces, prefixes used with namespaces and conventions for using prefixes in XAML.

<Window x:Class="SampleApplication.MainWindow"
  xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
  xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
  Title="MainWindow" Height="350" Width="525">
  <Grid>       
  </Grid>
</Window>

1. xmlns attribute is a specialized attribute in the world of XML that is reserved for declaring namespaces.

2. The above default XAML code contains two XAML namespaces. 

http://schemas.microsoft.com/winfx/2006/xaml/presentation contains all the WPF classes, including the controls you use to build your user interface. This namespace is declared without any prefix, so this is the default namespace for the entire XAML document. Every element in XAML document, is automatically placed in this namespace unless you specify otherwise.

http://schemas.microsoft.com/winfx/2006/xaml includes various XAML utility features. This namespace is mapped to the prefix "x". That means you can apply it by placing prefix "x" before the element name.

3. The above namespaces are not URI unlike in XML.

4. You can also include .NET namespaces like System in XAML for string manipulation. Syntax for including external namespaces in XAML is:

xmlns:Prefix="clr-namespace:Namespace;assembly=AssemblyName"

For example, you can include System namespace in XAML like this:

xmlns:sys="clr-namespace:System;assembly=mscorlib"

Now you can use sys in your XAML document like this:

<sys:DateTime>10/30/2014 5:30 PM<sys:DateTime>

Similarly you can include you custom namespace that you have created in your project like this:

xmlns:local="clr-namespace:MyWPFApplication"

5. Prefix Conventions: In the above examples, I have take x, sys and local prefixes for declaring namespaces. You can take any prefix of your choice, but you should not do it because WPF says to follow this convention for prefixes while declaring XAML namespaces.

Saturday, 31 May 2014

WPF XAML, Loose XAML and BAML Files: Approaches to create WPF applications with XAML

WPF XAML, Loose XAML and BAML Files: Approaches to create WPF applications with XAML

There are four approaches to create WPF application with XAML. You can use XAML directly to in WPF application or can convert XAML into the BAML for improving its performance or you can use loose XAML or do not use XAML at all. Lets try to understand these approaches of creating WPF applications with XAML.

Code and compiled markup(BAML): This is the preferred approach for WPF applications. This approach is used by Visual Studio. You can create XAML template for each window, and this XAML is compiled into BAML and embedded in a final assembly. At runtime, the compiled BAML is extracted and is used to generate the user interface.

Code and uncompiled markup(XAML): You can use this approach when you are creating highly dynamic user interface. In this approach, you load the user interface from a XAML file at runtime using the XamlReader class from the System.Windows.Markup namespace.

Code only: This is the traditional approach used in Visual Studio for Windows Forms application. It generates the user interface through the code statements.

XAML only (Loose XAML): Loose XAML is the file which only contains XAML code without any .NET namespaces, classes, properties, event handlers etc. Loose XAML can be used to stand alone user interface which includes WPF declarative features like animations, triggers, data binding, and links (which can point to other loose XAML files). You can compare loose XAML files with static HTML files. You can open loose XAML files in the Internet Explorer. 

Following points should be considered while creating a loose XAML file:

A) Remove the Class attribute on the root element.
B) Remove any attribute that attach event handlers.
C) Change the name of the opening and closing tag from Window to Page. Internet Explorer can show only hosted pages, not stand-alone windows. 

WPF Layout Controls/Containers, Layout Process, Properties and Tips

WPF Layout Controls/Containers, Layout Process, Properties and Tips

All the WPF Layout containers are panels that derive from the abstract System.Windows.Controls.Panel class. Mainly, there are five layout containers in WPF:

1. StackPanel
2. WrapPanel
3. DockPanel
4. Grid
5. Canvas

I am not going to explain working of all these panels as it is already very well explained here. I will add some extra details about these layout controls in WPF. I will go through WPF Layout Process Stages (Measure Stage and Arrange Stage), how can we create our custom layout containers using MeasureOverride() and ArrangeOverride() methods, different WPF layout properties and some tip and noteworthy points about WPF layout containers.

WPF Layout Process

WPF Layout takes place in two stages:

A) Measure Stage: The container loops through its child elements and asks them to provide their preferred size.
B) Arrange Stage: The container places the child elements in the appropriate position.

Creating WPF Custom Layout Containers

The Panel class also has a bit of internal plumbing you can use if you want to create your own layout containers. Most notably, you can override the MeasureOverride() and ArrangeOverride() methods inherited from FrameworkElement to change the way the panels handle measure stage and arrange stage when organizing its child elements.

WPF Layout Properties

1. Layout Properties of Layout Containers are HorizontalAlignment, VerticalAlignment, Margin, Width, Height, MinWidth, MinHeight, MaxWidth and MaxHeight

2. Default HorizontalAlignment for a Button is Stretch and for a Label is Left.

3. You can set margin for each side of a control in the order left, top, right and bottom. For example:

<Button Margin="1,2,3,4">OK</Button>

In this case, Left Margin = 1, Top Margin = 2, Right Margin = 3 and Bottom Margin = 4.

4. DesiredSize Property: You can find out the size that button wants by examining  the DesiredSize property, which returns the minimum width or the content width, whichever is greater.

5. ActualWidth and ActualHeight Properties: You can find out the actual size used to render an element by reading the ActualHeight and ActualWidth properties. But those values may change when window is resized or the content inside it changes.

6. SizeToContent Property: You can create automatically sized window in WPF if you are creating a simple window with dynamic content. To enable automatic window sizing, remove the Height and Width properties of Window and set the Window.SizeToContent property to WidhtAndHeight. The window will make itselft just large enough to accommodate all its contents. You can also allow a window to resize itself in just one dimension by using the SizeToContent value of Width or Height.

7. Border CornerRadius Property: CornerRadius property allows you to gracefully round the corners of your border. The greater the corner radius, the more dramatic the rounding effect is.

8. WPF Elements should not be explicitly sized.

9. There are three values for visiblity enumeration for elements:

A) Visible: Element is visible
B) Hidden: Element is invisible but the space occupied by it is still reserved.
C) Collapsed: Element is invisible and it also does not take up any space.

WPF Layout Containers - Tips and Noteworthy Points

1. Default orientation of StackPanel is Vertical while default orientation of WrapPanel is Horizontal.

2. DockPanel LastChildFill Property: LastChildFill when set to true, tells the DockPanel to give the remaining space to the last element.

3. DockPanel, Grid and Canvas uses Attached Properties. DockPanel has one attached property: DockPanel.Dock. Grid has two attached properties: Grid.Row and Grid.Column. Canvas has four attached properties: Canvas.Top, Canvas.Left, Canvas.Right and Canvas.Bottom.

4. Grid ShowGridLines Property: ShowGridLines property when set to true, shows all the border of cell and rows.

5. If you don't specify Grid.Row property to the child elements, those child elements are placed on row number 0. Same is the case with Grid.Column.

6. The Grid supports three sizing categories:

A) Absolute Sizes: <ColumnDefination Width="100"></ColumnDefination>
B) Automatic Sizes: <ColumnDefination Width="Auto"></ColumnDefination>
C) Proportional Sizes: <ColumnDefination Width="*"></ColumnDefination>

You can also add weight to proportional sizes: 

<ColumnDefination Width="*"></ColumnDefination>
<ColumnDefination Width="2*"></ColumnDefination>

It means, the second column is twice as bigger as the first one.

7. You can also span rows and columns in a grid.

<Button Grid.Row="0" Grid.Column="0" Grid.RowSpan="2">RowSpannedButton</Button> 

<Button Grid.Row="0" Grid.Column="0" Grid.ColumnSpan="2">RowSpannedButton</Button>

8. You can add GridSplitter to a Grid to give the user ability to resize rows and columns.

9. You can also create uniform grids in WPF. Uniform Grids don't require any row and column definition. Example:

<UniformGrid Rows="2" Columns="2">
<Button>Top Left</Button>
<Button>Top Right</Button>
<Button>Bottom Left</Button>
<Button>Bottom Right</Button>
</UniformGrid>

10. All the layout containers can be nested.

11. Canvas is the most lightweight layout container. 

12. Canvas allows you to place elements by using exact coordinates which is a poor choice of designing rich data-driven form.

13. Canvas.ClipToBounds property is used to clip the contents which fall outside the canvas.

14. Canvas.ZIndex property is used when there are overlapping elements in Canvas. The child element having greater ZIndex value will be shown above other child elements.

15. InkCanvas is used to allow stylus input. InkCanvas lets the user annotate contents with strokes.