Search This Blog

Monday, August 1, 2011

Hosting a WPF control inside a Windows Form

Hosting a WPF content inside a Windows Forms application is very easy. You need to use ElementHost control which takes a FrameworkElement in its Child property. So if you specify a UserControl for Child of an ElementHost, the WPF content will be loaded to the Forms application .

Lets take a look into this in steps :
Step 1 :
Create a Windows Forms application and add a WPF UserControl Library to the project. ( If you are unaware of User Controls, please feel free to check these posts on UserControl and CustomControl, or you can read my WPF Tutorial from here. )
Step 2 :
Add a UserControl to the project and create something. In this sample application, I have just created a ColorAnimation that will be started when a Button is Clicked. Lets look how the code looks like :

             xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
             xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
             xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
             xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
             mc:Ignorable="d"
             d:DesignHeight="300" d:DesignWidth="300">
    
        
            
            
        

    
    
        
            
            
        
        
        
        
    
Step 3:
Lets put the code for the Button Click eventhandler which will start the Animation on Button Click.
public bool IsAnimationStarted { get; set; }
private void Button_Click(object sender, RoutedEventArgs e)
{
    Storyboard sBoard = (Storyboard)FindResource("cAnimBorder");
    btn.Content = "Start";
    sBoard.Stop();

    if (!this.IsAnimationStarted)
    {
        sBoard.Begin();
        btn.Content = "Stop";
    }
    this.IsAnimationStarted = !this.IsAnimationStarted;

}
Step 4 :
Our UserControl is ready. Now it needs to be plugged in to the Forms Application.
Step 5 :
Take Project reference to the controls assembly in the Forms application just shown in the figure below :
clip_image001
Step 6 : Add an ElementHost control in the form and select the UserControl as Child. You will find the ElementHost control in WPF Interoperability section of toolbox.
clip_image002
Step 7 : Select the UserControl as Child. Once you select it, it will be shown in the Window designer too.
clip_image004
Step 8 : Run the sample, and you will see the UserControl Appears on the screen inside ElementHost.
clip_image006
There is a Non WPF button on the form as well as the WPF button and both works perfectly.
Download Sample Code
https://skydrive.live.com/self.aspx/.Public/SampleWPFHoster.zip?cid=bafa39a62a57009c&sc=documents
To do this Programmatically you must create an ElementHost and write like this :
SimpleWpfUserControlLibrary.UserControl1 ucontrol = new SimpleWpfUserControlLibrary.UserControl1();
            this.elementHost1.Child = ucontrol;
Note : Also remember, as there is no synchronization of WPF  content and Windows Forms content, Resizing the ElementHost might  sometimes produce hole in the content. So use it somewhere that never  requires any resizing for better user experience.

Releasing Single / Multiple Files To Pre Compiled ASP.net Web Site

We most the time run into the issue where we need to release a patch which requires a change in one or multiple code behind files and since your site is compiled, you are put into the state that you have to do a deployment instead of releasing those files. But, fortunately you can do that on a ASP.net website.

If your site is a ASP.net web application, then there is no shortcut since the application is compiled into a single class library and you have no option but to publish the site and this article will not help you. However, if you are using a web site, well here you go.

I created a default web site and published it. Remember to check the option which allows to update the site after compilation.

image

Now let me assume that I need to change the Default.aspx.cs file for some fix after publishing, and if I get into the published folder, I will not be able to see any code behind files. Below is how I see the aspx file.

image

As you can see, the “inherits” value is changed to get the class “_Default” from a assembly called "App_Web_yqoiawao" which was generated while publishing. You can find all these dlls inside the “bin” folder. If you have selected “Use fixed naming and single page assemblies” option you will see seperate assemblies for every page. Now lets not disturb them and concenterate on making a release on the code behind file “Default.aspx.cs” where we made the change.

All you have to do is copy the “Default.aspx.cs” file to the same location of “Default.aspx” and edit the “Default.aspx” and change the page tag to have as

CodeFile="Default.aspx.cs" Inherits="_Default"

Well thats it, you have made a release for a single file. Remeber now the Default page is no more precompiled and it will compile for every request made. Don't use this option unless you cannot really afford to make a release and you need a quick fix.

Raising Server side event from JavaScript in ASP.NET (Tweaking the existing bits)

Well, knowing internal structure of an ASP.NET event system can always be an element of fun and interests. Recently I came across to a requirement to generate a server side event on a page directly from Javascript. There are a couple of approaches available with the existing models (like ICallbackEventHandler etc) but these will put additional pressure to the page and also does not use the existing code already present. So I thought to put a script that could use all the existing code and work similar to what happens in background.

You might know when a page is processed, it generates two hidden controls. viz. EventName and EventValue. The eventName is used to send the name of the event that the client is going to generate in the server side. As you know, ASP.NET is a stateless protocol. Hence everything that is genenrated in the server side to produce your page, will be disposed once it is done. Hence you need to postback the whole page again to communicate and during this phase, the ASP.NET server side page generates the respective events on various controls which is specified on the eventName.

The eventValue on the other hand will hold additional arguments that you need to send to the server for the particular event. The ASP.NET page will generate the event automatically during the rendering of the page in the server side.

Now here, I am going to build my own event so I need to do this myself. Lets see how :

public delegate void CustomEventHandler(string message);
public event CustomEventHandler public void OnCustomEventRaised(string message)
{
if (this.CustomEvent != null)
this.CustomEvent(message);
};

Say I have to generate this event from the client side. As this event is created totally by me, I need to configure it myself, such that it generates it when passed with special attribute. I personally thought it would be easier to understand this for a newbie if I write it under Page_Load, but you are free to generate this event as your wish (following your own pattern I guess). Now lets look the code to understand

First of all, I create two hidden field in the page with runat =”server”




This will ensure that the hiddenfields will be available from server side. Now inside Page_Load, I write code to raise the event :

public void Page_Load(…)
{
if (hidEventName.Value == "CustomEvent")
{
hidEventName.Value = ""; //It is essential reset it and remove viewstate data
OnCustomEventRaised(hidEventValue.Value);
}
}

public void OnCustomEventRaised(string message)
{
if (this.CustomEvent != null)
this.CustomEvent(message);
}

So eventually I am raising the eventhandler once the page is posted back from the client side. Now to raise the event from the client side, let me add a javascript :

function RaiseEvent(pEventName, pEventValue) {

document.getElementById('<%=hidEventName.ClientID %>').value = pEventName;
document.getElementById('<%=hidEventValue.ClientID %>').value = pEventValue;

if (document.getElementById('<%=MyUpdatePanel.ClientID %>') != null) {
__doPostBack('<%=MyUpdatePanel.ClientID %>', '');
}
}

So basically I am posting back the whole page from the client side using the __doPostBack method already present for every page. Here I have used my UpdatePanelId to ensure that postback is generated from my UpdatePanel.

Now from javascript if I call :
RaiseEvent(‘CustomEvent’, ‘Hello from server’);
It will eventually call the server with my custom message.

I hope the code snippet will come handy.

Creating Custom HTML Helpers in ASP.NET MVC

ASP.NET MVC provides many built-in HTML Helpers.  With help of HTML Helpers we can reduce the amount of typing of HTML tags for creating a HTML page.
For example we use Html.TextBox() helper method it generates html input textbox. Write the following code snippet in MVC View:
<%=Html.TextBox("txtName",20)%>
It generates the following html in output page: 
List of built-in HTML Helpers provided by ASP.NET MVC.
  • ActionLink() – Links to an action method.
  • BeginForm() – Marks the start of a form and links to the action method that renders the form.
  • CheckBox() – Renders a check box.
  • DropDownList() – Renders a drop-down list.
  • Hidden() – Embeds information in the form that is not rendered for the user to see.
  • ListBox() – Renders a list box.
  • Password() – Renders a text box for entering a password.
  • RadioButton() – Renders a radio button.TextArea() – Renders a text area (multi-line text box).
  • TextBox () – Renders a text box.
How to develop our own Custom HTML Helpers?
For developing custom HTML helpers the simplest way is to write an extension method for the HtmlHelper class. See the below code, it builds a custom Image HTML Helper for generating image tag.
using System;
using System.Web.Mvc;
namespace MvcHelpers
{
    public static class CustomHtmlHelpers
    {
        public static TagBuilder Image(this HtmlHelper helper, string imageUrl, string alt)
        {
            if (!String.IsNullOrEmpty(imageUrl))
            {
                TagBuilder imageTag = new TagBuilder("img");
                imageTag.MergeAttribute("src", imageUrl);
                imageTag.MergeAttribute("alt", alt);
                return imageTag;
            }
            return null;
        }
    }
}
The next step is in order to make it available to Views, we should include the name space of out custom HTML helper class into Web.config
Build the solution to make sure the helper method is available to views. Goto any view in the solution access the newly created HTML image helper method.
<%@ Page Language="C#" Inherits="System.Web.Mvc.ViewPage" %>


      Home


      

<%= Html.Encode(ViewData["Message"]) %>

<%=Html.Image("/Images/logo.png","logo") %>

<%=Html.Image(“/Images/logo.png”,”logo”) %>
The image HTML helper generates the following HTML.
”logo”/
Image Tag Helper is simple example of HTML helpers, we can put any sort of complex logic into HTML Helpers & access them with in the views with a simple method call. in turn which makes the view simpler.

How To Create Session-less Controller in MVC3

How to manage the controller’s session state?
Simply we can decorate the controller class with “SessionState” attribute. [SessionState()] attribute accepts SessionStateBehaviour enumeration.
SessionStateBehaviour enumeration has the following constants.
  • SessionStateBehavior.Default - ASP.NET default logic is used to determine the session state behavior for the request.
  • SessionStateBehavior.Required – Full read-write session state behavior is enabled for the request.
  • SessionStateBehavior.ReadOnly – Read only session state is enabled for the request.
  • SessionStateBehavior.Disabled – Session state is not enabled for processing the request.

Sessionless Controller
We decorated controller class with [SessionState(SessionStateBehaviour.Disabled)] to disable the session. Important point to remember when we are disabling session of the controller, we should n’t use TempData[] Dictionary to store any values with action method controller, it uses session to store it’s values. If you use TempData[] Dictionary when session is disabled on controller it will throw an exception “The SessionStateTempDataProvider class requires session state to be enabled“.
Note: In earlier release of MVC3 (Beta) [SessionState()] attribute was refereed as  [ControllerSessionState()]

How to return 404 Http status code from ASP.NET MVC Application?

ASP.NET MVC3 includes a new class HttpNotFoundResult in  System.Web.Mvc namespace.
HttpNotFoundResult: Instance of HttpNotFoundResult class indicates to client(browser) that the requested resource was not found. It returns a 404 HTTP status code to the client. Generally we return 404 status code if a requested webpage is not available. In case of MVC applications we return 404 status code is in terms of resources, for example we are searching for particular user profile in the portal, if the user profile is not found, we can return 404.

How to return 404 status code from a MVC application?
First way is to instantiate HttpNotFoundResult class and return the object.
public ActionResult Index()
{
var result = new HttpNotFoundResult();
return result;
}
Next alternative is to makes use of HttpNotFound() helper method of the Controller class which returns the HttpNotFoundResult instance.
public ActionResult Index()
{
return HttpNotFound();
}
we can return 404 along with custom status code description,using the overloded version of HttpNotFound(string statusDescription).
public ActionResult Index()
{
return HttpNotFound("can not find requested resource");
}

Difference between a UserControl and a CustomControl

If you are thinking to build a control and apply the same to more than one place, you can take two kinds of approaches. Either you can create an User control inheriting from UserControl and adding a XAML for your control or use CustomControl to write yourself. Either one of them you choose they have their own pros and cons. Here in this post I will define what are the differences between the two approaches so that you can choose either one of them based on your requirement.

Before we start lets define both the terms:
UserControl : A usercontrolis a reusable chunk of user interface that is built up as a composition of other UIElement in the same style the main UI is built. In other words, a user control is just like a normal application block that can be used as Reusable component, and can be defined both using XAML and code together. It gives you a fresh UI canvas where you can define your custom reusable component that can be used widely in the application. In WPF, UserControl acts as a base class for any reusable component, but if you are looking for inheriting some other base, you can look into this.
Limitation of UserControl :
1. Appearance of an UserControl cannot be changed using a Template. Even though it has a property for Template, but it is of no use, as you cannot change the appearance of UserControl through this property.
2. UserControl is derived from ContentControl, thus if you change the Content of an usercontrol the entire UI will be replaced with that content.
3. As UserControl has both XAML and code behind. But as XAML can be used only once for entire inheritance hierarchy, you cannot use XAML for any class that inherits from your userControl. This is actually because Application.LoadComponent loads up the XAML once and is incompatible with inheritance. Thus when loading the XAML, the IComponentConnector interface is used to hook events and fields from XAML, hence you cannot replace XAML from your base class.
Custom Control: A customcontrol is a User interface element that has a distinct behaviour. A CustomControl is just a class that has one default appearance defined in Generic.xaml style which can be replaced by Template and Style at runtime but the behaviour you define for the control remains the same. So choose a CustomControl only when you need a certain kind of behaviour which is not there with the existing controls you have.
Note: Please don’t create a new custom control just to change the UI appearance as you can do this with any control available using custom Template
Limitation :
1. You have to define each behaviour for your control using Code. So it is hard way of achieving a behaviour.
2. Generic style is needed to be defined with your custom control to ensure that your control has a default look and feel.
Hence, based on your own requirement, if you are looking for a new behaviour which is different from existing userinterfaces available with WPF, you go for a Custom Control. A customControl can be styled and templated and best suited for a situation when you are building a Control Library.
On the contrary, a UserControl gives you an easy way to define reusable chunk of XAML which can be reused widely in your application and when you don’t need to use it as a Control Library.
I hope this gives you a brief idea on the differences between the two.
Happy Coding.