Is Excel Present in client machine?

by munnaonc 16. August 2010 21:36
In one of our application we had to make sure that whether client have excel installed or not. We tried few codes and have some experience while resolving the solution. Bello the solution code is given to detect if client have excel 2007 installed or not.
 
The bellow code works fine. But it fails one single time. If the user installed excel but never run it. The registry keys are not built until the user run excel for the first time. so we had to change our message to inform user as “You don’t have excel or you didn’t run it after install, if you have install please run it for the first time and try again” some thing like this.
 
private static bool IsExcelPresent()
{
var key = Registry.CurrentUser.OpenSubKey("Software\\Microsoft\\Office");
if(key!=null)
{
string[] subKeyNames = key.GetSubKeyNames();
if(subKeyNames.Contains("12.0"))
{
var excelKey = key.OpenSubKey("12.0\\Excel\\");
if(excelKey!=null) return true;
}
else
{
return false;
}
}
return false;
}

 
Eventually we got rid of the obstacle and found a very interesting component called SpreadsheetGear and used that component. we bypassed all the excel requirement using this component.
 
There are some more solutions on the web to you guys can also try those. Bellow a yet another code sample is given.
 
private static bool IsExcelPresent()
{
try
{
Type officeType = Type.GetTypeFromProgID("Excel.Application");
return officeType != null;
}
catch (Exception ex)
{
return false;
}
}

Another code sample to detect excel which using registry key search
 
private static bool IsExcelPresent()
{
RegistryKey key = Registry.ClassesRoot;
RegistryKey excelKey = key.OpenSubKey("Excel.Application");
bool excelInstalled = excelKey == null ? false : true;
return excelInstalled;
}



Using the Build event of visual studio 2008

by munnaonc 21. September 2009 20:09

Background

Some times we need to execute some custom task just before we build our solution or project, I have no idea how others IDE do that, but recently we have gathered some experience about Visual Studio 2008, and doing these kind of task became pretty easy.

In one of our project we had to use a custom third-party component, the component is easy to incorporate in the project, but we have a problem, the component uses a d-com component which can not be added in the project, but if we keep the com component in bin directory the program runs okay. so our challenge is to copy the component before build in the bin directory of output project from the other projects bin.

Visual Studio 2008 Build Events

In Visual studio 2008 we have two build event, prebuilt event command and post build event command, post build event can be controlled with various parameters for example, post build event will raise when a successful build is happened.

image  

Figure: Visual Studio 2008 Build tab under Project properties

In our particular case we solved our problem in using pre-build event, now let us discuss a little bit more about pre-built event, you can use almost any kind of command in command line, provided that the commands don't require special permissions for executions.

In our case we have used "xcopy" command to solved the problem, there are lot of macro for execution. we used target directory as output macro, and source directory as solution macro, since its a simple problem we set the relative path of the DLL from solution path. worked okay, when we published the project we found that in publish version also contains the DLL, job done with very good time and in a good way.

Post build is almost similar like pre-build except it has some extra control, user can specify when to raise it, in the above screen shot you can see that there is a large combo at the bottom.

Here is a small example command in the for pre-build command.

If we want to copy all output files of a project to a deployment folder after post build event we have to put down the following command in the post build command line,

""xcopy "$(TargetDir)*.*" "c:\output" /S /I /F <NUL:""

Bellow i have put down a pre-build event command line input window with macro.

image

well that's all for now, please visit the references for more information, best of luck and happy coding.

References

  1. http://msdn.microsoft.com/en-us/library/42x5kfw4.aspx
  2. http://geekswithblogs.net/dchestnutt/archive/2006/05/30/80113.aspx
  3. http://dotnetperls.com/post-pre-build-macros
  4. http://skysanders.net/subtext/archive/2009/09/05/visual-studio-2008-build-event-xcopy-bug.aspx

Web browser control does not display data in WPF window if window's allow transparency is true

by munnaonc 15. September 2009 20:07

Windows from have web browser control since .net 2.0, WPF also introduced a browser control from .net 3.5 sp1, well the controls are very good as far as functionality is concern, i my self prefer windows forms browser since it have more control with the functionality.

Today i encountered with a strange problem, in one of my application i used a modal dialog to present data as light box effect, inside the modal i added a browser control and then populated appropriate data, when i run the application the modal showed up, but the browser was just blank, no data what so ever. Later after few trial and error i found that my modal windows allow transparency property is set to true,  when i turned it to false, browser's content showed up.

Its a small problem perhaps many of you already knew about it, but since it killed almost two hour of my time, i thought its worth sharing. Happy coding..

WPF ItemsControl with alternating item and hover effect

by munnaonc 24. April 2009 19:53

Introduction

In this short article we are going to see few tricks about WPF ItemsControl. ItemsControl is one of the simplest yet powerful control in WPF. ItemsControl is just like the repeater control in asp.net. It supports Binding and supports custom template to display the data. for detail study about power of ItemsControl please read MSDN documentation here. In this article we going to focus on how to display alternating item in ItemsControl and apply few effects on items of ItemsControl.

ItemsControlAlternatingItem

Use Alternating Item Style

Items control can be used to display data both via populating the ItemsControl.Items collection or specify a Items Source in ItemControl.ItemsSource property. In this example we are going to use ItemsSource to display our data. Lets assume we have a custom class called country and we want to display the information about country in a ItemsControl. Bellow a simple code listing is given to get the total idea.

public partial class Window1 : Window
{
public Window1()
{
loadDemoData();
this.DataContext = this;
}

public static readonly DependencyProperty DataListProperty =
DependencyProperty.Register(
"DataList", typeof(ObservableCollection<Country>),
typeof(Window1));

private void loadDemoData()
{
ObservableCollection<Country> data =
new ObservableCollection<Country>();
Country c1 = new Country { ID = "1", Name = "Bangladesh",
Capital = "Dhaka", Continent = "Asia" };
Country c2 = new Country { ID = "2", Name = "India",
Capital = "Delhi", Continent = "Asia" };
Country c3 = new Country { ID = "3", Name = "U.S.A",
Capital = "Washington", Continent = "North America" };
Country c4 = new Country { ID = "4", Name = "Australia",
Capital = "Canbarra", Continent = "Australia" };
Country c5 = new Country { ID = "5", Name = "Kenya",
Capital = "", Continent = "Africa" };
data.Add(c1);
data.Add(c2);
data.Add(c3);
data.Add(c4);
data.Add(c5);
this.SetValue(Window1.DataListProperty, data);
}

public class Country
{
public string ID { get; set; }
public string Name { get; set; }
public string Continent { get; set; }
public string Capital { set; get; }
}
}
 
In few of example given in the online community I have seen that items control is not directly been used to display the idea of alternating items, rather list box or perhaps more higher level control is shown to display alternating items. In this section we will see how we can add styles in items and alternating items of ItemsControl just by using a simple DataTemplate. When we use ItemsControl, items of  ItemsControl are generally rendered inside a ContentPresenter, which have only few basic properties, and we can not assign the background or foreground.
 
Using DataTemplate and use smart use of styles on DataTemplate might just solve our problem. Bellow a complete code listing is give, how to do the intended effect.
 
<Window x:Class="WPFDemo.Window1"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Title="ItemsControl" MinHeight="350"
MinWidth="550" Background="#f5f5f5">
<Window.Resources>
<Style x:Key="alternatingWithTriggers"
TargetType="{x:Type ContentPresenter}">
<Setter Property="Height" Value="25"></Setter>
</Style>
<DataTemplate x:Key="MyItemTemplate">
<Border x:Name="yahoo">
<StackPanel Orientation="Horizontal">
<Label Content="{Binding Name}"></Label>
<Label Content="is in"></Label>
<Label Content="{Binding Continent}"></Label>
</StackPanel>
</Border>
<DataTemplate.Triggers>
<Trigger Property="ItemsControl.AlternationIndex" Value="0">
<Setter Property="Background" Value="#e9e9e9"
TargetName="yahoo"></Setter>
</Trigger>
<Trigger Property="ItemsControl.AlternationIndex" Value="1">
<Setter Property="Background" Value="#d9d9d9"
TargetName="yahoo"></Setter>
</Trigger>
</DataTemplate.Triggers>
</DataTemplate>
</Window.Resources>
<Grid MinHeight="350" MinWidth="550">
<ItemsControl ItemsSource="{Binding DataList}"
ItemContainerStyle="{StaticResource alternatingWithTriggers}"
AlternationCount="2"
ItemTemplate="{StaticResource MyItemTemplate}"/>
</Grid>
</Window>
 
In above code listing we didn't did any style change in item container styles, rather we override the item template and used the item templates style in such a way so that it shows alternate items style. Main engine to make go this trick is AlternatingItemIndex property of ItemsControl. In data template we used trigger to check the index of item and then apply style to DataTemplates one of inner elements.

Hover Effect

Applying hover effect is now easy since we know how to apply styles using trigger. but in this case we wont use AlternatingItemIndex. We want to apply a mouse over effect regardless of whether its item or alternating item. Bellow the code snippet is give for hover effect on items.

<Style x:Key="onmouseover" TargetType="{x:Type StackPanel}"> 
<Style.Triggers>
<Trigger Property="IsMouseOver" Value="True">
<Setter Property="Background" Value="Yellow">
</Setter>
</Trigger>
</Style.Triggers>
</Style>
<DataTemplate x:Key="MyItemTemplate">
<Border x:Name="yahoo">
<StackPanel Orientation="Horizontal"
Style="{StaticResource onmouseover}">
<Label Content="{Binding Name}"></Label>
<Label Content="is in"></Label>
<Label Content="{Binding Continent}"></Label>
</StackPanel>
</Border>
<DataTemplate.Triggers>
<Trigger Property="ItemsControl.AlternationIndex" Value="0">
<Setter Property="Background" Value="#e9e9e9"
TargetName="yahoo"></Setter>
</Trigger>
<Trigger Property="ItemsControl.AlternationIndex" Value="1">
<Setter Property="Background" Value="#d9d9d9"
TargetName="yahoo"></Setter>
</Trigger>
</DataTemplate.Triggers>
</DataTemplate>
 
In above code snippet you can see that we have applied the style on stack panel. Style of hover on border that is the parent control of data template will not work, since we have already added styles using trigger in Data template. so we defined separate style for stack panel and applied to it. And that concludes are mission.
 

Summery

In this short article we have seen how we can use alternating item using ItemsControl. In this demonstration we have used AlternatingItemCount as 2, but user can set grater than two, but to get the alternating item effect it must be larger than 1. The styles must be modified to support according to AlternatingItemCount. for more study on ItemsControl please visit the references.

Reference

A Beginner's Guide for "Using WCF in JavaScript using Asp.net Ajax"

by munnaonc 9. February 2009 18:48

Contents

    1. Development Platform
    2. Introduction
    3. Using Ajax-Enabled WCF Service item template
    4. Using Service Interface defined in a class library
    5. Configure the Web Application To Use TODO Service
    6. Using Service In JavaScript
    7. Summery
    8. References

Development Platform

  • Visual Studio 2008 SP1
  • Dot.net Framework 3.5 SP1
  • Asp.net Ajax
  • IIS7 or VS Integrated Web Server [WCF and SVS file configured]
  • Windows Vista

Introduction

WCF (Windows communication foundation) added lot of new capability in Microsoft application development platform, particularly in case of how applications communicate to each other. In this article we are going to see how WCF can be used directly from clients JavaScript code. Its a very cool future provided by asp.net Ajax. In this article we are not going to cover every theory about WCF internals rather we only remained focused on how to use the service directly from JavaScript. So no behind the scene stuff of how asp.net or dot net runtime manage this feature.

To demonstrate the ideas and facts we are going create a demo solution with two projects. So with no time waste create a blank solution and save it. Now add a class library project to the solution. Name the class library as "ServiceLibrary". Now Add another web application project to the solution and name it as WEBUI. We are going to see two approach to add WCF service that can be consumed from JavaScript.

  1. Using Ajax-Enable WCF Service item template
  2. Using Service Interface defined in a class library

Using Ajax-Enabled WCF Service item template

Its a very strait forward way to use WCF service in JavaScript. Right Click on the web application project and select add new item. Select Ajax-Enabled WCF Service item template name it as "HelloWorldService.svc" and click ok. Wizard will add a HelloWorldService.svc file to solution as expected. This file have a code behind file as well. If you open the HelloWorldService.svc in xml file editor you will see a markup like this

<%@ ServiceHost Language="C#" Debug="true" Service="WebUI.HelloWorldService"

CodeBehind="HelloWorldService.svc.cs" %>

And if you open the code behind file you will se code some thing like this

namespace WebUI
{
    [ServiceContract(Namespace = "")]
    [AspNetCompatibilityRequirements(RequirementsMode = AspNetCompatibilityRequirementsMode.Allowed)]
    public class HelloWorldService
    {
        // Add [WebGet] attribute to use HTTP GET
        [OperationContract]
        public void DoWork()
        {
            // Add your operation implementation here
            return;
        }

        // Add more operations here and mark them with [OperationContract]
    }
}

Visual Studio 2008 automatically add the necessary configuration for you in the web.config file so no need to configure any thing in web.config. Now go ahead and add a method like HelloWorld() which returns a string "HelloWorld" and add [OperationContract] method attribute to the method. we will explain what the attributes are for later in this article. Now add a page to web application project and name it as "HelloWorldTest.aspx". Drag drop a script manager item from visual studio tool box. Inside the ScriptManager tag add service reference of the service. Bellow a example code is give.

<asp:ScriptManager ID="ScriptManager1" runat="server">
            <Services>
                <asp:ServiceReference Path="~/HelloWorldService.svc" />
            </Services>
        </asp:ScriptManager>

Now add a button and a textbox to the page and on button click use a JavaScript function to call the service. when you will write the service call function Visual Studio 2008 Html Editor will provide intellisense to write necessary function call. Full code of html part is give bellow.

<form id="form1" runat="server">
<div>
    <script language="javascript" type="text/javascript">
        function GetValueFromServer() {
            HelloWorldService.HelloWorld(onSuccess, onFailure);
        }

        function onSuccess(result) {
            document.getElementById('txtValueContainer').value = result;
        }

        function onFailure(result) {
            window.alert(result);
        }
    </script>
    <asp:ScriptManager ID="ScriptManager1" runat="server">
        <Services>
            <asp:ServiceReference Path="~/HelloWorldService.svc" />
        </Services>
    </asp:ScriptManager>
    <input id="btnServiceCaller" type="button" value="Get Value" onclick="GetValueFromServer()"; />
    <input id="txtValueContainer" type="text" value="" />
</div>
</form>

Note that when calling the service we have passed two method one is for callback and other one is for error callback. If we need to pass any parameters to the function parameters will go first and then the call back. So if we have a function name getvalue which take two string parameters as argument we are going to call the function as [NameSpaceName].[ServiceName].getvalue("value one","value two",on_success,on_error); where on_sucess and on_error are callback and error callback respectively.

Using Service Interface defined in a class library

So we have looked how to use a Ajax-Enabled WCF Service using item template. Now we are going to see more traditional WCF Service implementation and we are also going to see how we can expose this service for Asp.net Ajax. when we created the class library project by default its not added with the service model and runtime serialization support which is necessary to run WCF. So we got to add the necessary service references. so go ahead and right client on class library project and select add reference and then select the references.

  1. System.Runtime.Serialization
  2. System.ServiceModel

In this phase we are going to use a TODO Management example to demonstrate the whole idea. Add A Service Based Database and then create a TODO Table with ID,Description and Status Field. Now Add A LinkToSQL class file from item template. Drag Drop the table TODO from database to link to SQL Class File designer. Now Click on the designer surface and from property window change the Serialization Mode to Unidirectional. Now our designer generated Link to SQL classes are ready to use for WCF. If you want to use custom user defined types you must set [DataContract] class attribute to your class and you must add [DataMember] property attribute to each property of the class you want to expose to WCF.

Now we are going to add a service interface like this

namespace ServiceLibrary
{
    [ServiceContract(Namespace = "ServiceLibrary")]
    interface IToDoService
    {
        [OperationContract]
        ToDo GetToDo(long ID);
        [OperationContract]
        ToDo AddToDo(ToDo toDo);
        [OperationContract]
        bool DeleteToDo(ToDo todo);
        [OperationContract]
        ToDo UpdateToDo(ToDo todo);
        [OperationContract]
        List<ToDo> GetAllToDo();
    }
}

Note that we have mentioned a name space in side the ServiceContract interface Attribute. This is very important. we are going to use this name as the service name in side the JavaScript to access the services. Now we are going to add the implementation to this service interface the code is given bellow. Please note that in bellow code i have used [AspNetCompatibilityRequirements(RequirementsMode = AspNetCompatibilityRequirementsMode.Allowed)] class attribute, this is must requirement for exposing the service as asp.net Ajax enabled WCF service.

namespace ServiceLibrary
{
    [AspNetCompatibilityRequirements(RequirementsMode = AspNetCompatibilityRequirementsMode.Allowed)]
    public class ToDoService : IToDoService
    {
        #region IToDoService Members
        public ToDo GetToDo(long ID)
        {
            DataClasses1DataContext context = new DataClasses1DataContext();
            var toDos = from p in context.ToDos
                        where p.ID == ID
                        select p;
            List<ToDo> listTodos =  toDos.ToList();
            if (listTodos != null && listTodos.Count > 0)
            {
                return listTodos[0];
            }
            else
            {
                return null;
            }
        }

        //all the methods is not shown

        #endregion
    }
}

Configure the Web Application To Use TODO Service

Now that we have defined all the necessary stuff to run our TODO Application its time to expose the service to the client as a asp.net Ajax enabled WCF service. For this we are going to add a Ajax-Enabled WCF Service .svc file. And we will get rid of the code behind file. or we can add a xml file or text file and then rename it to ToDoService.svc. Open it with xml editor and put directive like bellow

<%@ ServiceHost Language="C#" Debug="true" Service="ServiceLibrary.ToDoService" %>

Now we are going to put necessary configuration to run this service in web.config, the code is given bellow

 

<system.serviceModel>
        <behaviors>
   <endpointBehaviors>
    <behavior name="AspNetAjaxBehavior">
     <enableWebScript />
    </behavior>
    <behavior name="WebUI.HelloWorldServiceAspNetAjaxBehavior">
     <enableWebScript />
    </behavior>
   </endpointBehaviors>
  </behaviors>
        <serviceHostingEnvironment aspNetCompatibilityEnabled="true" />
        <services>
   </service>
   <service name="ServiceLibrary.ToDoService">
    <endpoint behaviorConfiguration="AspNetAjaxBehavior" binding="webHttpBinding"
     contract="ServiceLibrary.IToDoService" />
   </service>
   <service name="WebUI.HelloWorldService">
    <endpoint address="" behaviorConfiguration="WebUI.HelloWorldServiceAspNetAjaxBehavior"
     binding="webHttpBinding" contract="WebUI.HelloWorldService" />
   </service>
  </services>
    </system.serviceModel>

Now right click on the file and select view in browser to see the service is up and running well. Few things must be mentioned before moving to next phase. You must add serviceHostingEnvironment and set its aspNetCompatibilityEnabled="true" to be able to use wcf service in asp.net with its features like httpContext, Session etc.

Using Service In JavaScript

Now use the service just like HelloWorldService we have previously used. Bellow I have given few example code to make things clear. Bellow the ScriptManager Mark up is given. Note that we have added a clientServiceHelper.js file. We have put all the client to WCF communication JavaScript functions in that file.

<asp:ScriptManager ID="ScriptManager1" runat="server">
            <Scripts>
                <asp:ScriptReference Path="~/Script/ClientServiceHeler.js" />
            </Scripts>
            <Services>
                <asp:ServiceReference Path="~/ToDoService.svc" />
            </Services>
        </asp:ScriptManager>

We have used asp.net Ajax client side object oriented model to write bellow JavaScript client code which are the part of clientServiceHelper.js.

Type.registerNamespace("ServiceClients");

ServiceClients.ToDoClient = function() {
}

ServiceClients.ToDoClient.prototype = {

    AddToDo: function(todo, callback, errorCallBack) {
        ServiceLibrary.IToDoService.AddToDo(todo, callback, errorCallBack);
    },

    DeleteToDo: function(todo, callback, errorCallBack) {
        ServiceLibrary.IToDoService.DeleteToDo(todo, callback, errorCallBack);
    },

    UpdateToDo: function(todo, callback, errorCallBack) {
        ServiceLibrary.IToDoService.UpdateToDo(todo, callback, errorCallBack);
    },

    GetAllToDo: function(callback, errorCallBack) {
        ServiceLibrary.IToDoService.GetAllToDo(callback, errorCallBack);
    },

    dispose: function() {
        //disposed
    }
}

ServiceClients.ToDoClient.registerClass('ServiceClients.ToDoClient', null, Sys.IDisposable)

// Notify ScriptManager that this is the end of the script.
if (typeof (Sys) !== 'undefined') Sys.Application.notifyScriptLoaded();

Summery

In this article we have seen how we can use Ajax-Enable WCF Service item template. The we have seen how we can use a service interface based wcf service. we have also seen how to configure web.config to use the services, last of all we have seen how we can add service reference in ScriptManager. Few things must be mentioned before ending this article we can also add service reference in c# code below a simple code example is given.

ScriptManager manager = ScriptManager.GetCurrent(Page);
ServiceReference reference = new ServiceReference("ToDoService.svc");
manager.Services.Add(reference);

If the beginners encounter problem of not understanding any particular portion of the article please drop a message. You can learn the ABC of WCF here. If you have any difficulty configuring WCF in IIS please see this article here.

References

  1. http://msdn.microsoft.com/en-us/library/aa480190.aspx [WCF - ABC]
  2. http://munna.shatkotha.com/Blog/post/2008/07/08/Install-WCF-Aspnet-in-IIS7.aspx [Configure WCF]
  3. http://msdn.microsoft.com/en-us/library/bb514961.aspx [Expose WCF to Client Script]
  4. http://msdn.microsoft.com/en-us/library/bb763177.aspx [Configure WCF in asp.net Environment]
  5. http://msdn.microsoft.com/en-us/library/bb398785.aspx [Web Service in asp.net]
  6. http://peterkellner.net/2008/09/14/wcf-web-service-json-vs2008/ [Article that discussed the same concept]

Improved Resource file project template in vs2008

by munnaonc 22. June 2008 19:32

Visual Studio 2008 resource file project template is now more improved! and more usable.It has very user friendly and easy to edit environment, providing the user with the ease of managing resource better than ever. I have been using resource file since Visual Studio 2003. Previously I got to write code and use resource manager to pull the resources from the embedded resource file. And there are maintenance hassles to load a resource only once. We did lot of engineering previously to resolve the easy management and developer friendly architecture for resource accessibility. Now resource management with Visual Studio 2008 resource file template is a child's job.

 

What can be added in resource file

 

Now we can add different type of resource file just with few mouse click, isn't it great. Okay, here is the list of file type you can add as a resource file in resource file template.

  • String
  • Image
  • Icon
  • Audio
  • Files
  • Other(Virtually every thing!)

 

 

So there is lot to work with resource file. The magic is you can add these files with drag and drop from any location. Adding resources is that much easy. Still you have some traditional way of adding resource, you can add new resource and also add existing file from the disk. for this we have to click on "Add Recourse" button in Resource Management Window.

 

 

Access Modifier

 

Resource file and its type has few access modifier just like our class access modifier. If you set access modifier as "No code generation"  no designer generated code will be generated! ... this means now we don't have to write any manager class to manage and pull the resources from embedded resource file if we choose access modifier other than "No code generation". Here are the options we have in access modifier.

  • Internal
  • Public
  • No code generation

 

Visual Studio 2008 will automatically write a class and code for you so what you can access your files right way. This is one of the major improvement in resource file template of Visual Studio 2008. If you set access modifier as "Internal" your resource can only be accessed from the container project of the resource file, that implies what you can not access resources, that are marked as internal, from out side the project. So of course setting the access modifier to "Public" will made our resource accessible from any where.

 

I have used string file in in couple of my projects and did all custom codes to manage those. Now I use resource file right way because its so easy. Here is a view what designer generates for you.

 

 

Resource File "IntelliSense"

 

Since we have a designer generated code so we can use the class right way in our code and also enjoy the facility of intellisence. A very beautiful feature is that if we will get the object as typed object, means if we added string type it will give use string object, and if we have added image in our resource file it will return a Image Type object. so its pretty smart and we can bind it to a Image Control to display it.

 

 

Well another thing that I want to share, that, its has different type of view in resource manager window. we can switch to thumb nail mode if we are using image and easily locate which image we are looking for. Of Course we can also filter our resource using resource type selector.

NOTE: Each Resource is added against a key so. Key must be unique.

Using Background Process in WPF

by munnaonc 16. June 2008 19:30

WPF applications often needs to call time consuming methods or processes, the time consuming methods or processes can be, huge time consuming calculation or perhaps a web service call. In case of WPF specially XBAP (wpf browser application) which run on remote client machines browser, this sort of calls can make your user interface unresponsive.  I am working with WPF for more than four month. Lot of things come in to way and dealt with nicely. Well in this post I am going to share a simple trick for avoiding unresponsiveness of user interface. We have already used this technique in many cases in our application, but this is for WPF.

 

The "Thread & Invoke"

 

BackgroundWorker is a very smooth and useful tool for our purpose of making more responsive UI(user interface). Before discussing more about BackgroundWorker lets take a flash back of legacy technique (which is pretty smart)  implementation of making  more responsive UI. Previously I used threading for implementing such kind of UI smoothness. What I did is to create a background thread and call expansive operation on that thread. When the job is finished use the "MethodInvoker" method to let know the UI thread that the job is finished. And this model is called asynchronous model. And this is quite smart model and rest of the models are based on this approach. Here is a quick code snippet for demonstration the technique.

//first start the method with tread
System.Threading.ThreadStart ts = new System.Threading.ThreadStart(ExpansiveMethod);
System.Threading.Thread t = new System.Threading.Thread(ts);
t.Start();
protected void ExpansiveMethod()
{
//Very expansive call will go here...
//after the job is finished call method to update ui
MethodInvoker updaterMI = new MethodInvoker(UpdateChange);
this.BeginInvoke(UpdateChange);
}
protected void UpdateChange()
{
//again back to main ui thread
}

 

The "Background Worker"

 

Okay, its time to use the BackgroundWorker. An amazing thing about background worker is, its simple to use.  First, lets see what a background worker is. "BackgroundWorker" is a class under "System.ComponentModel" which executes an operation on a separate thread. Which is introduced from dot net framework 2.0. Things are again pretty simple just like tread, All you have to do is instantiate a BackgroundWorker and subscribe its events, and call the "RunWorkerAsync()" method. Lets put a code snippet. Since we are programmers we understand code better.

void MyMethodToCallExpansiveOperation()
{
//Call method to show wait screen
BackgroundWorker workertranaction = new BackgroundWorker();
workertranaction.DoWork += new DoWorkEventHandler(workertranaction_DoWork);
workertranaction.RunWorkerCompleted += new RunWorkerCompletedEventHandler(workertranaction_RunWorkerCompleted);
workertranaction.RunWorkerAsync();
}
void workertranaction_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e)
{
//Call method to hide wait screen
}
void workertranaction_DoWork(object sender, DoWorkEventArgs e)
{
//My Expansive call will go here...
}

As you can see in above code I have subscribed two event "DoWork" (which is the main function) and "RunWorkerCompleted", In dowork event handler we will put our expansive time consuming operations, as the name imply's RunWorkerCompleted event is fired when the work is finished . BackgroundWorker also has "ProgressChanged" event which is used to let the main UI thread know how much work is completed.

 

The "Dispatcher"

 

In few cases the BackgroundWorker needs to access the main UI thread. In WPF we can use "Dispatcher" which is a class of "System.Windows.Threading" and a delegate to access the main thread. First of all we have to declare a delegate for our candidate methods, and then use the delegate to call the method using Dispatcher. Dispatcher has few thread priority and you can use various priority from DispatcherPriority enum. "Send" has the highest priority in DispatcherPriority.

//delegate for our method of type void
public delegate void Process();
//and then use the dispatcher to call the method. 
Process del = new Process(UpdateMyUI);
this.Dispatcher.Invoke(System.Windows.Threading.DispatcherPriority.Background, del);
void UpdateMyUI()
{
//get back to main UI thread
}

 

For more reading about this Asynchronous Programming please visit the references.

 

Reference

http://msdn.microsoft.com/en-us/library/system.componentmodel.backgroundworker.aspx

http://weblogs.asp.net/justin_rogers/articles/126345.aspx

http://www.eggheadcafe.com/articles/20050926.asp

Wpf Image ,Working with Image Source

by munnaonc 1. June 2008 19:28

Hi after a long time I am back in my blog. In this post I will discuss few things about WPF image object. Recently I have been working in a project whose UI Layer is build entirely with windows presentation foundation.

Background

WPF has another way to display image. That is, using BitmapImage object. You can declare BitmapImage tag and in WPF XAML just like Image tag. But in case of BitmapImage the source property is a Uri name is UriSource. Luckily BitmapImage is the source property of Image. Here is a simple code segment of Image and BitmapImage.

ImageSource & BitmapImage

WPF has another way to display image. That is, using BitmapImage object. You can declare BitmapImage tag and in wpf xaml just like Image tag. But in case of BitmapImage the source property is a Uri name is UriSource. Luckily BitmapImage is the source property of Image. Here is a simple code segment of Image and BitmapImage

<Image Width="200" Margin="5" Grid.Column="1" Grid.Row="1" >
<Image.Source>
<BitmapImage UriSource="sampleImages/bananas.jpg" />
</Image.Source>
</Image>

Mouse hover effect

Bellow I have listed few lines of code when i change the image in mouse enter and mouse out of an image object. Of course I am using Uri to define the location of my image then using the Uri to make a new BitmapImage and finally use BitmapImage to assign Image.Source Property.

   1:  private void btnGoToHome_MouseEnter(object sender, MouseEventArgs e)
   2:  {
   3:      this.Cursor = Cursors.Hand;
   4:      Uri src = new Uri(@"C:/Images/DifferentTransaction_Icon_Active.png");
   5:      BitmapImage img = new BitmapImage(src);
   6:      btnGoToHome.Source = img;
   7:  }
   8:  
   9:  private void btnGoToHome_MouseLeave(object sender, MouseEventArgs e)
  10:  {
  11:      this.Cursor = Cursors.Arrow;
  12:      Uri src = new Uri(@"C:/Images/DifferentTransaction_Icon_Normal.png");
  13:      BitmapImage img = new BitmapImage(src);
  14:      btnGoToHome.Source = img;
  15:  }

Thats it you are done

Reference

http://msdn.microsoft.com/en-us/library/system.windows.controls.image.aspx

No Scroll content of wpf xbap in iframe

by munnaonc 6. March 2008 18:23

In my previous blog post i have discussed about how to hide the navigation ui of xbap while you hosting Xbap ( Xaml browser application) in iframe. Note that xbap can be accessed directly from browsers url address and can also be viewed in a iframe in existing web site. In both case user can have contents that requires scrolling.If user developed the xbap application in such a way that the application will be accessed directly form url address, user can archive the goal by adding a "scrollableview" element in your xmal page. bellow a code sample is provided.

   1:  <Page x:Class="CookieTest.Page1"
   2:        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
   3:        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
   4:        Title="Page1">
   5:      <ScrollViewer>
   6:          <Grid>
   7:              <!--your content will go here–>-->
   8:          </Grid>
   9:      </ScrollViewer>
  10:  </Page>

Next case is if user hosted the xbap application in a iframe. In this case there is a good chance that user will be viewing two vertical scrollbar in user's browser if users existing site's page is long enough to cause view a vertical scroll bar, that is the browser's vertical scrollbar. Xbap host have a defined size, which generally as long and wide as the browser window. So if your content is longer than the size of xbap host, you can loose your content from viewable content area. or you will end up having two scrollbar.Well there is several solutions to this problem. Lets discuss with a simpler version. Make the iframe's height property as long as the xbap that is hosting the xbap. And make sure that your xbap will not grow larger than that. but if your xbap has variable content and has variable height and you got to keep the constant look you need to do some engineering to keep things smooth.Xbap do support get and set of cookie in the site of origin. so do calculate your height for your content in xbap and then set the height as a cookie, make sure you do set the height of the content as a cookie each time the content of xbap has changed, of course in case of the content that cause the xbap to change its size. here is a code example to set cookie for site from xbap.

Application.SetCookie(BrowserInteropHelper.Source, "HEIGHT=" + DemoHeight );

Now in the page, where you hosted your xbap in iframe read the cookie with javascript and the change the height of the iframe. that's it you will have a smooth operation of auto grow or shrink of your xbap and wont cause any extra scrollbar. for reading the cookie do a little engineering for example always track the height cookie with javascript timer based function.

   1:  <script language="javascript" type="text/javascript">
   2:  function getCookie(c_name)
   3:  {
   4:      if (document.cookie.length>0)
   5:      {
   6:        c_start=document.cookie.indexOf(c_name + "=");
   7:        if (c_start!=-1)
   8:          {
   9:          c_start=c_start + c_name.length+1;
  10:          c_end=document.cookie.indexOf(";",c_start);
  11:          if (c_end==-1) c_end=document.cookie.length;
  12:          return unescape(document.cookie.substring(c_start,c_end));
  13:          }
  14:      }
  15:      return "";
  16:  }
  17:  function InCreaseHeight()
  18:  {
  19:      var hight = getCookie('HEIGHT');
  20:      if(hight != "")
  21:      {
  22:          if(document.getElementById('framename')!=null)
  23:          {
  24:              if(hight<600)
  25:              {
  26:                  hight = 600;
  27:              }
  28:              document.getElementById('framename').height = hight;
  29:          }
  30:      }
  31:      setTimeout("InCreaseHeight()",250);
  32:  }
  33:  </script>

one more thing do call the javascript increase height function on body on load event of the page to kick start the process.

   1:  <body onload="InCreaseHeight();">

Reference:

http://www.w3schools.com/js/js_cookies.asp
http://msdn2.microsoft.com/en-us/library/ms750478.aspx#Cookies

Creating web application and web site that run in IIS 7 of windows vista from vs2008

by munnaonc 28. January 2008 18:17

While creating a web site in vs2005 or vs2008 , web site location has three options and the options are 1. File System 2. HTTP 3. FTP

image

Previous version of Visual studio (VS2002,VS2003) supports web application that run only on IIS. User can easily create web applications cause Visual Studio automatically guide the user to create a web application. Since vs2005 come with whole new application suite for example, Web Site template , web application template and mix mode of Ajax templates user had options to chose between many things. I personally used IIS and File System web site and web applications (File System web run on Vs integrated vs development web server ) in windows XP. I have recently moved to windows vista and and VS2008 Team System. I found some interesting stuff regarding windows vista and vs2008 that I thought need little share with the community (might help some one).

Web site in VS2008 on windows vista that run on IIS

image

I wanted to create a web site in IIS so I opened vs2008 selected ASP.net "Web Site" project template and Choose Local IIS but I found a strange message and unable to proceed to create a virtual directory from the wizard. I didn't read the message carefully, I thought my IIS is not installed properly or my IIS is not running. I opened my IIS administration MMC from administrator tool and found that IIS is up and running well, then I got confused and performed the same site creation operation again. This time when the Local Internet Information Server tab got selected I read the message carefully and it says how to create web site from vs2008, and it says I got to run vs2008 with "Run as administrator" :)

image

I closed my IDE and opened IDE from start menu with "Run as administrator" options selected from right click menu and performed the same operation again, this time every thing worked just okay :).

image

Web app in VS2008 on windows vista that run on IIS

While creating a "web application" project (which is created via choosing new project, rather than new web site from File->New menu) user do not have any option to select between File system or IIS hosted project in project creation wizard. By Default a File System based web application is created for the user. Just follow the normal procedure to create a web application, after web application creation is completed select the project properties. When the project properties window appear select the Tab named "Web*". You will see in web tab by default "Use Visual Studio Development Server" option is selected. change it to "Use IIS Web Server" option. After that just click on the Create Virtual Directory button to finish the procedure. save the project and you are good to go.

image

Oh one more thing, for this operation, again you have to run IDE in Run as administrator mode.