Thursday, March 11, 2010

Another article Published @WindowsClient.net

It is always nice to see an article published in Windowsclient.net. And if it happens so quickly, it is even better. I have just demonstrated the use of Multilingual applicaiton using WPF. It is just the login screen, where you can give user id and password. The static elements are fetched from Resource files.

The figure in the right shows how the UI looks like, when you run the application. The static elements are dependent on the Current UI culture. If we make the current regional settings as French, the UI elements will look as french.

The resources will be loaded dynamically using Thread.CurrentThread.CurrentCulture.

You can read the complete article from

Simplest Way to Implement Multilingual WPF Application



I would also like to Congratulate all my followers, Mr Sheo Narayan, Abhijit Jana, who always appreciated my work all the time.


Thanks for reading.

Sunday, March 7, 2010

“Article of the day” @ Microsoft’s official website www.windowsclient.net

Guys, I am very thankful to Mr Sheo Narayan (The Founder of DotNetFunda), and Dotnetfunda team, to nominate my article to be published in MS Official Site www.windowsclient.net.




Today, it is selected as "Article of the Day" in the site. The article is describes how we can implement Asynchronous Call to methods using Delegates. I have used BeginInvoke and EndInvoke which implicitly creates a new Thread from ThreadPool and invokes the method.

You can see the article from here. Dont forget to put your feedback.


Asynchronous Method Invocation

Multilingual Application using WPF

Creating a multilingual application using WPF is a very common issue to everyone. While creating an application, it is quite natural to create an application that has Multilingual Support and which would respond to Current Culture settings in the client computer. In this article, I am going to discuss how to implement a multilingual application.


In the above snapshot you can see a login screen that I have implemented to demonstrate the application.
Try out the sample application from here.

Read Full Article.

Thursday, March 4, 2010

Try Text to Speech for your application

It is really easy and fun to create applications that speaks out for you. With the introduction with System.Speech, it seems to look like even better. It is to be noted, that Windows Environment comes with a unique feature that converts your voice commands to text equivalent long before the introduction to this in .NET. I will discuss now how you can easily use this in your application and get the work done quickly.

Background

Windows Speech Recognization Engine and Narrator utility comes with Windows XP service pack 2 or Office applications. Windows Narrator uses various windows items and speaks instantly. If you have never tried with it, it is time to try it first.

Open Start - > Programs -> Accessories - >Accessibility -> Narrator


After opening you will hear that a person is speaking out some weird terms. Actually this is nothing but your narrator speaking to help you. Actually the checkboxes determines various options like, reading events, Read typed characters etc. You can even change the narrator just by clicking on the Voice Button.
Here you can see Microsoft Sam is listed. This is the default .NET narrator. You can adjust speed, volume, pitch etc of the listed Narrators. You can also add some external Narrators for you if you wish. Now I am going to show you how you can invoke Narrator to be used in your own application.

Old Way
If you are not using .NET Framework 3.0 or above, this must be your only way to do this. First in this case you need to install Speech SDK 5.1. The speech SDK gives you the interface to work with SPVoice commands. The Speech SDK provides you two interfaces. One is for Text to Speech Conversion, while the other is for Speech Recognisation. In this article I am going to discuss only Text  to Speech Conversion.

To do this, first create the Interop to the COM dll that comes with SAPI named speechlib.dll. You need to right click on your project, add Reference and add "Microsoft Speech Object Library" from COM tab.
After you add Interop.Speechlib.dll in your application you need to use some simple lines of code as below to run your application :

using SpeechLib;
SpVoice speech = new SpVoice();
speech.Speak("Hello World",SpeechVoiceSpeakFlags.SVSFlagsAsync);
speech.WaitUntilDone(Timeout.Infinite);

Thus if you run the above application, you will find that Microsoft Sam will say you "Hello World".

NEW Way

With the Introduction of .NET Framework 3.0, Microsoft released Managed API to handle these through your program and it doesnt need anything to be installed. Let us look how we can invoke using the new way.

First Add Reference to System.Speech.dll. You will find that in GAC if you have installed .NET 3.5 to your system.
As shown in the figure, after you add the dll you need to use some simple methods to invoke Speech To Text for your application. 

To invoke this, you need to know about a class called SpeechSynthesizer. This is the main class to handle speech requests from the application and invokes the Narrator utility itself with configured narrator. 
You can configure voice, speech, pitch of the narrator, and change the Narrator voice itself using the object of SpeechSynthesizer class.

Let us see how the code look like :
using System.Speech.Synthesis;

SpeechSynthesizer spsynthesizer = new SpeechSynthesizer();
List<voiceinfo> lstVoice = this.LoadSelectVoiceMenu();
Now when you want to invoke the Speaking utility just call :
spsynthesizer.SelectVoice(lstVoice[0].Name); //Invoke the one which you want
spsynthesizer.Volume = 50; // Can be 1 - 100
spsynthesizer.Rate = 3; // can be 1 - 10 
spsynthesizer.SpeakAsync("Hello World");

The SelectVoice method is used to choose the appropriate Narrator. If you have more than one narrator, you can use this method to SelectVoice. I have used lstVoice[0] which should point to Microsoft Sam. The volume determines the volume of the voice, and Rate determines how fast the narrator speaks.

To Speak out the text, you have two method. I am using SpeakAsync, to call it asynchronously. You can also use Speak itself, which will wait until the text is spoken. While the text is been spoken using SpeakAsync, you can all SpeakAsyncCancel or SpeakAsyncCancelAll anytime to end the narrator instantly.

spsynthesizer.SpeakAsyncCancel(new Prompt("Lets End"));

if invoked will end the SpeakAsync and prompt Lets End.

Conclusion

Thus invoking a Text to Speech for your application become easiest like never before. You can use this without any heck.

In my next entry, I will be discussing about Speech Recognisation. So stay tune.

Monday, January 11, 2010

How to : Expose events from UserControl

In ASP.NET, web user control is used very often to implement modular coding. We replace the repeating blocks of code into an User Control which we add in our web page when required. Technically speaking, ASP.NET web user control is just a subset of a Web Form. You have designer where you can declare controls that comprise the user control, you can even manipulate the code from the code-behind class. The only think that you need is to handle appropriate events within the User Control and add that in the aspx page.

The problem


Generally we place all the controls that comprises the user control private, so that we disallow the pages to access the controls within the user control directly. Thus, we cannot access any events that is associated with any child control within the user control. We have to rely only on the OnLoad event of an user control which most of the time could not be used properly.
To help in such a situation we need to create our custom events and expose them from the user control so that we can handle them easily to the page and do appropriate tasks.
In this article I am going to discuss how to do this :
To make the example most simple, I have create a country/state selection box as an user control. The Usercontrol contains 2 DropdownList items which are placed one after another. There are a few behaviours of the dropdownlist controls. The second dropdown is actually populated from the data of the first one.

Thus when I choose Canada from the first dropdown, I can choose the other states from the second. To do this, I need to handle the SelectedIndexChanged event and populated the second dropdown. Just see the code below (I used XML data for better understanding):
protected void drpCountry_selectedIndexChanged(object sender, EventArgs e)
{
string selecteditem = drpCountry.SelectedValue;
PopulateDropStates(selecteditem);
}


The PopulateDropStates clears all the items in the 2nd dropdown and recreates the items.
private void PopulateDropStates(string p)
{
this.drpState.Items.Clear();
XElement container = doc.Descendants("country").FirstOrDefault(
item => item.Attribute("code").Value.Equals(p));
var elements = container.Descendants();
foreach (XElement elem in elements)
{
ListItem item = new ListItem(elem.Attribute("name").Value
, elem.Attribute("code").Value);
this.drpState.Items.Add(item);
}
if (this.drpState.Items.Count > 0)
this.drpState.Items[0].Selected = true;

}
I have made the dropdownlist private and which lets me to access only the part of the control that I want to expose. Now let say I want to do something when my 2nd dropdown is changed. Aah, I cant do that because as the control is not public, I cant handle the events. So I need to formulate a proxy event from the control and generate that event whenever the selectedindex of the second DropDownlist is changed.

Declaring an Event

Event is an object which raises itself whenever some other behavioral change of the class is made. When an event is raised, we need to pass the actual delegate that it calls. So to work with event, we need to create a delegate which will define the signature of the event handler and the event itself.
public delegate void DropDownSelectionDelegate(
object sender, SelectionChangedEventArgs e);
protected event DropDownSelectionDelegate _drp1selectionChanged;
public event DropDownSelectionDelegate DropDownCountrySelectionChanged
{
add
{
if(this._drp1SelectionChanged == null)
this._drp1selectionChanged += value;
}
remove
{
if(this._drp1SelectionChanged != null)
this._drp1selectionChanged -= value;
}
}
public virtual void OnDropDownCountrySelectionChanged()
{
SelectionChangedEventArgs evt = new SelectionChangedEventArgs(this.drpCountry);
if (this._drp1selectionChanged != null)
this._drp1selectionChanged(this, evt);
}

We have created an instance of a delegate DropDownSelectionDelegate which is the signature of the event _drp1selectionChanged. Thus if you want to handle the event, I need to declare an event handler same to the signature of the delegate.
The event accessor is the public property which exposes the event to the outside. I have added both add/remove to ensure the event can be added and removed using this and also to ensure only one instance of the event is registered. The virtual method OnDropDownCountrySelectionChanged actually raises the event. Thus whenever the event requires invocation in the class, just use this.OnDropDownCountrySelectionChanged() and the event will be raised.

In order to handle the event inthe page, just register the event in the page_load like this :
this.objCountrySelect.DropDownCountrySelectionChanged += new
DropDownSelectionDelegate(methodname);


Or you can directly add the event to control itself:
<uc1:CountryStateSelectBox runat="server"
   ID="ctrySelectbox"
   OnDropDownCountrySelectionChanged="ctrySelectBox_DropDownCountrySelectionChanged">
</uc1:CountryStateSelectBox>


Thus the event handler ctrySelectBox_DropDownCountrySelectionChanged will get raised automatically whenever the country selection is changed.

In this example I have used a custom class SelectionChangedEventArgs which is basically used to send data.
public class SelectionChangedEventArgs : EventArgs
{
private DropDownList _list;
public SelectionChangedEventArgs(DropDownList list)
:base()
{
this._list = list;
}
public DropDownList DropDown
{
get
{
return this._list;
}

}

}

Thus the class is created just to pass the list object with the event argument.

Conclusion


Thus through events you can easily raise your custom events from the control and pass data. Events comes very handy when you want callbacks for long running applications. You can define an event which you raise after an interval.

Thanks for reading my blog.

Wednesday, November 4, 2009

Weird Error : Unable to Validate Data in ASP.NET website

Have you ever come across a situation where your website which was working for last couple of months gives a weird error "Unable to Validate Data". Yesterday, while working I found that my website which is already published in IIS throws this error. Initially I thought the error might be with my code, but I found that everything is good with the code. So I looked forward to internet and found that this error comes when the viewstate of a page cannot be decrypted when the response received from the client.

When I look where the error is occurring(Target Site) I found:

Unable to validate data at
System.Web.Configuration.MachineKey.GetDecodedData(Byte[] buf, Byte[] modifier,
Int32 start, Int32 length, Int32& dataLength) at
System.Web.UI.LosFormatter.Deserialize(String input)

Actually the problem is with the viewstate. The viewstate is actually decrypted in the server using a secret Machine key which resides on the server. The interesting thing is the key gets regenerated after a certain time. Therefore when the user returns the viewstate, if the machine identified key is changed, the decryption of viewstate fails and thus throws this nasty error.

Solution

The solution is simple. First of all, to solve the issue, I disabled the ViewState for the current page by putting EnableViewState = false. Even I have disabled this for the entire viewstate for the website using Web.config. But still the error.
Finally I have used "EnableViewStateMac =false" in pages section. Voila, this cures the problem.
<pages buffer="true" enableViewStateMac="flase"/>
</pages>
Just place the following between the system.web section and the site starts working.

Another solution that you might use as well is to place the machine key directly on your web.config, so that it always decrypts and encrypts using the static key values. To do this you need to use the following :

<machinekey validationkey="22E995276703B846C4AD0881EE3159FFCB376CD48B27F64
9A074815C83D5C925038938F6943555687582CBC186DB22E552FCDB4D46
124BAADEE85A857CC135BC" decryptionkey="60588EB661A6483348C20F92659775872CB06427AF20733C" validation="SHA1"></machinekey>

You might use this site to Generate your validation key as well.
To get the deep knowledge on what makes this happen, I found some insight from Internet and reading some articles of msdn. Let us talk a little on that note.
Say you made a request for a page in the server. After you place the request the server processes it, encrypts the viewstate that the server receives using the encryption mentioned. Basically it uses the key mentioned in the Machine.config to encrypt the viewstate data. Finally it converts to Base64 and embed into some hidden fields.

We can mention the machine key in Web.config too so that it uses it for the current website. You might use AutoGenerate option too to enable/disable autogeneration of key during the runtime.

Your comments are welcome.

Sunday, September 13, 2009

Grant access to your Assembly from COM objects

This is a very common occasion where we need to expose a .NET assembly to COM applications, so that the COM application can communicate with .NET assemblies. Here I am going to create a .NET Assembly and expose it from COM.

Your COM Exposed .NET class :

Let us create the Class which I need to expose to COM.

using System;
using System.Collections.Generic;
using System.Text;
using System.Runtime.InteropServices;

namespace ComVisibleObject
{
[Guid("EB7F73B0-AF1F-4595-8CE8-849D3745E862")]
public interface IComVisibleObject
{
string GetString();
void SetString(string value);
}

[Guid("DF8B1227-68EC-4F76-8C79-D20574C21B56")]
[ComVisible(true)]
public class ComVisibleObjectEx : IComVisibleObject
{
private string element = string.Empty;

public string GetString()
{
return element;
}

public void SetString(string value)
{
element = value;
}

}
}

Here I have created an Interface called IComVisibleObject which might be used to create the class. Please note, it is not mandatory to create the interface.

To Uniquely Identify each class we placed GuidAttribute to each of them. The class ComVisibleObjectEx is exposed to COM using ComVisibleAttribute set to true.

After your class is created in Class Library, Right click on Project - > Go to Properties and select Register for COM interop.
Again Under the signing Tab Select Sign the Assembly. In the Choose key file combobox select New. Choose Filename, Username and password.. The Strong name key will be created automatically.

Now Build the project. Say the dll produced is ComVisibleObject.dll. Use GacUtil to put it in Global Assembly Cache. Use this :
gacutil -i ComVisibleObject.dll

If its successful it will confirm "Assembly successfully added to the cache”.

To add it from COM applications, you need to register assembly using regasm tool.Use

regasm ComVisibleObject.dll
After registration is successful, it will say "‘Types registered successfully".

Now let us create your COM application. For simplicity I use vbs. You can easily create an original VB application to test this as well

Dim object
set object = CreateObject(”ComVisibleObject.ComVisibleObjectEx”)
MsgBox(”Created the object.”)
defaultText = object.GetString()
MsgBox(”Default text length : ” & Len(defaultText))
object.SetString(”My new string”)
newText = object.GetString()
MsgBox(”New text is ” &amp; newText)

Finally save the file as Example.vbs.
Open Command prompt and type

cscript Example.vbs

You will see the messageboxes show the text.

Author's new book

Abhishek authored one of the best selling book of .NET. It covers ASP.NET, WPF, Windows 8, Threading, Memory Management, Internals, Visual Studio, HTML5, JQuery and many more...
Grab it now !!!