Embedding Windows Forms Applications directly in a WebBrowser

"In the past, Web developers often used ActiveX controls to provide rich client-side functionality in their Web applications. Now developers can easily build objects using the Microsoft .NET Framework that are more compact, lightweight, secure and can be hosted within Internet Explorer. By hosting .NET Windows Forms controls in Internet Explorer, developers can accomplish many client-side Web development goals..." 

This is an excellent introduction from Thiru Thangarathinam article in CodeGuru 

 In the rest of this article he provides great details on how to accomplish this task.   

 

Figure 1: Example of simple Hello Word Windows Forms App embedded in Browser

 

 

Figure 2: Example of a more complex Windows Forms App consuming data from a Web Service

 

" However before using Windows Forms controls in IE, you need to be aware of the benefits and limitations. The main benefits include: 

  •          The ability to deliver dynamic rich user experience through the Web 

  •          Automatic caching of compiled code on the client 

  •          Seamless integration with .NET Code Access Security that allows you to leverage the .NET security model from within the client side 

  •          Improved performance over Java applets 

The constraints include: 

  •           It requires Windows operating system on the client side 

  •           Internet Explorer 6.0-9.0 is the only browser that provides support for this type of hosting 

  •           It requires .NET runtime to be installed on the client machine. 

  •           It also requires Windows 2000 and IIS 5.0 or above on the server side" 


Currently my tests indicate that this technique does not apply for Windows 8. Also issues with .NET code security should be reviewed or additional configuration might be needed in order for restricted operations to be available. (This article from Dino Esposito provides more insight on these security aspects http://devcenter.infragistics.com/Articles/ArticleTemplate.Aspx?ArticleID=1264) 

Using ClickOnce deployment over the web to simplify Windows Form Application deployment

 

Artinsoft\Mobilize.Net helps legacy application to be modernized using the Windows Forms technology. Doing this upgrade revitalizes your application code and allows you to take advantage of the new platforms features like ClickOnce deployment. 

What is ClickOnce deployment?   

 
"ClickOnce is a deployment technology that enables you to create self-updating Windows-based applications that can be installed and run with minimal user interaction. Visual Studio provides full support for publishing and updating applications deployed with ClickOnce technology if you have developed your projects with Visual Basic and Visual C#.

ClickOnce deployment overcomes three major issues in deployment: 

  •          Difficulties in updating applications. With Microsoft Windows Installer deployment, whenever an application is updated, the user can install an update, an msp file, and apply it to the installed product; with ClickOnce deployment, you can provide updates automatically. Only those parts of the application that have changed are downloaded, and then the full, updated application is reinstalled from a new side-by-side folder. 

  •          Impact to the user's computer. With Windows Installer deployment, applications often rely on shared components, with the potential for versioning conflicts; with ClickOnce deployment, each application is self-contained and cannot interfere with other applications. 

  •          Security permissions. Windows Installer deployment requires administrative permissions and allows only limited user installation; ClickOnce deployment enables non-administrative users to install and grants only those Code Access Security permissions necessary for the application. 

In the past, these issues sometimes caused developers to decide to create Web applications instead of Windows-based applications, sacrificing a rich user interface for ease of installation. By using applications deployed using ClickOnce, you can have the best of both technologies."


Click Once Deployment Strategies 

 

There are 3 deployment strategies: 

  • Install from Web or a Network Share 
  • Install from a CD 
  • Start from the Web or Network share 


Quick Overview 


 

For a quick overview of how to use the ClickOnce deployment take a look at Shahar Gvirtz's post http://weblogs.asp.net/shahar/archive/2008/01/29/how-to-use-clickonce-to-deploy-your-applications.aspx

 

Crystal Reports in Windows Azure

10. October 2012 08:52 by Mrojas in Crystal Reports, Printing, SQL Server, VB6 Migration, Visual Studio, WinForms  //  Tags:   //   Comments (0)

If you ever wonder, if Crystal Reports can be used on the cloud in Windows Azure, well the answer is you can.

These two links provides some guidance on this matter:

http://scn.sap.com/people/coy.yonce/blog/2011/05/02/sap-crystal-reports-and-microsoft-sql-azure (this one is in English)

http://blogs.msdn.com/b/luispanzano/archive/2011/04/11/crystal-reports-en-windows-azure.aspx (this one is in Spanish but Bing and Google Translate do a nice work here ;) )

CommandBarControl Click Event is not Working!!!!

2. September 2012 00:15 by Mrojas in Visual Studio  //  Tags: , , , , ,   //   Comments (0)

Today I was doing a VS extention as part of my weekend relaxation activities ;)

Everything was great until succendly something was not happening as I expected.

 I was adding a context menu to the code window with a dynamic list of options.

And each option had a different click delegate, but my click events were

disrespectfully discarted.

 Luckily I found this post:  http://www.rauchy.net/blog/?cat=4&paged=2

 And now for a tricky part: since you ge\t your instance of CommandBarEvents inside the scope of a method, when the method ends, the Garbage Collector collects it, leaving all the event handlers orphaned. Unless you keep your instance safe from the jaws of the mighty Garbage Collector, your buttons will not respond to clicks.

To do so, just keep your CommandBarEvents instance(s) as member fields of your class. Once your class is disposed, they will be disposed as well.

 Thanks Rauchy you saved my day! (And my wife is happy because I'm finally getting out of the bathroom :P)

Binding problem when Sending JSON object to MVC3

25. May 2012 16:59 by Mrojas in ASP.NET, HTML5, JSON, Razor, Visual Studio  //  Tags: , , ,   //   Comments (0)

After a frustrating couple of hours trying to determine WHY WHY my object did not bind with MVC3 I finally found why.

The story began like this.

I have a very simple method in a controller. Something like this:

 

public class Form1Controller : Controller
    {
        //
        // GET: /Form1/

        public ActionResult Index()
        {
            return View();
        }

        [HttpPost]
        public ActionResult DoButton1(Person zzz)
        { 
            System.Diagnostics.Debug.WriteLine(zzz.Name);
            return Json(data: "Good Test");
        }
   
       

    }
 
And I called that code with a jquery Statement like:
var person= JSON.stringify({ Name: "Mauricio", LastName: "Rojas" });              $.ajax({                                    
                    url: "/Form1/DoButton1/",
                    type: "POST",
                    dataType: "json",
                    data: person,
                    success: function () {
                        alert("OK");
                    },
   
                });
 
But!!! (maybe you already saw the obvious mistake) no matter what I sent, the Person object was not bind.
The action method got called but I was not able to see the sent values. I used Chrome developer tools and the network that show the
values I had modified.
SO WHYYYYY!!!!
I tried to debug the MVC code, but VS studio could not load the pdb, something I get that I still not sure why.
So how could I intercept what was happening? Simple with a ModelBinder.
A ModelBinder is class that is used to bind your request to a model object.
So I went to the Global.asax file and register my binder, and set some breakpoints.
//Code in Global.asax to register a Person Binder
    protected void Application_Start()
        {
            AreaRegistration.RegisterAllAreas();
            ModelBinders.Binders.Add(typeof(Person), new PersonBinder());
            RegisterGlobalFilters(GlobalFilters.Filters);
            RegisterRoutes(RouteTable.Routes);
        }

    public class PersonBinder : IModelBinder
    {
        public object BindModel(ControllerContext controllerContext, ModelBindingContext bindingContext)
        {
            var contentType = controllerContext.HttpContext.Request.ContentType;
            if (!contentType.StartsWith("application/json", StringComparison.OrdinalIgnoreCase))
                return (null);

            string bodyText;

            using (var stream = controllerContext.HttpContext.Request.InputStream)
            {
                stream.Seek(0, SeekOrigin.Begin);
                using (var reader = new StreamReader(stream))
                    bodyText = reader.ReadToEnd();
            }

            if (string.IsNullOrEmpty(bodyText)) return (null);

            var xx = new JavaScriptSerializer().Deserialize<Person>(bodyText);

            return xx;
        }
    }
 
And voila!! the content type I was getting was something like:application/x-www-form-urlencoded
 
So I just added the content type parameter to my javascript code:
$.ajax({                                    
                    url: "/Form1/DoButton1/",
                    type: "POST",
                    dataType: "json",
                    data: viewModelStr,
                    success: function () {
                        alert("inside");
                    }//,
                    contentType: 'application/json; charset=utf-8' 
                });
 

Binding problem when Sending JSON object to MVC3

25. May 2012 16:59 by Mrojas in ASP.NET, Razor, Visual Studio  //  Tags: , , ,   //   Comments (0)

After a frustrating couple of hours trying to determine WHY WHY my object did not bind with MVC3 I finally found why.

The story began like this.

I have a very simple method in a controller. Something like this:

 

public class Form1Controller : Controller
    {
        //
        // GET: /Form1/

        public ActionResult Index()
        {
            return View();
        }

        [HttpPost]
        public ActionResult DoButton1(Person zzz)
        { 
            System.Diagnostics.Debug.WriteLine(zzz.Name);
            return Json(data: "Good Test");
        }
   
       

    }
 
And I called that code with a jquery Statement like:
var person= JSON.stringify({ Name: "Mauricio", LastName: "Rojas" });              $.ajax({                                    
                    url: "/Form1/DoButton1/",
                    type: "POST",
                    dataType: "json",
                    data: person,
                    success: function () {
                        alert("OK");
                    },
   
                });
 
But!!! (maybe you already saw the obvious mistake) no matter what I sent, the Person object was not bind.
The action method got called but I was not able to see the sent values. I used Chrome developer tools and the network that show the
values I had modified.
SO WHYYYYY!!!!
I tried to debug the MVC code, but VS studio could not load the pdb, something I get that I still not sure why.
So how could I intercept what was happening? Simple with a ModelBinder.
A ModelBinder is class that is used to bind your request to a model object.
So I went to the Global.asax file and register my binder, and set some breakpoints.
//Code in Global.asax to register a Person Binder
    protected void Application_Start()
        {
            AreaRegistration.RegisterAllAreas();
            ModelBinders.Binders.Add(typeof(Person), new PersonBinder());
            RegisterGlobalFilters(GlobalFilters.Filters);
            RegisterRoutes(RouteTable.Routes);
        }

    public class PersonBinder : IModelBinder
    {
        public object BindModel(ControllerContext controllerContext, ModelBindingContext bindingContext)
        {
            var contentType = controllerContext.HttpContext.Request.ContentType;
            if (!contentType.StartsWith("application/json", StringComparison.OrdinalIgnoreCase))
                return (null);

            string bodyText;

            using (var stream = controllerContext.HttpContext.Request.InputStream)
            {
                stream.Seek(0, SeekOrigin.Begin);
                using (var reader = new StreamReader(stream))
                    bodyText = reader.ReadToEnd();
            }

            if (string.IsNullOrEmpty(bodyText)) return (null);

            var xx = new JavaScriptSerializer().Deserialize<Person>(bodyText);

            return xx;
        }
    }
 
And voila!! the content type I was getting was something like:application/x-www-form-urlencoded
 
So I just added the content type parameter to my javascript code:
$.ajax({                                    
                    url: "/Form1/DoButton1/",
                    type: "POST",
                    dataType: "json",
                    data: viewModelStr,
                    success: function () {
                        alert("inside");
                    }//,
                    contentType: 'application/json; charset=utf-8' 
                });
 

Problem using ActiveX controls with VS2010

11. May 2012 11:56 by Mrojas in ActiveX, COM Interop, VB6 Migration, Visual Studio, WinForms  //  Tags: , , , , , , , ,   //   Comments (0)

 

Sometimes during migrations from VB6 to VS2010 we have found issues when you tried to add an ActiveX control with the VS2010 winforms designer. The issue is only present in VS2010 not on previous versions.

You usually will see an error in the added Interop references, and messages like a missing VBA or StdLib library.

The error has been reported several times so please vote on Connect to make sure MS will consider fixing it.

 

https://connect.microsoft.com/VisualStudio/feedback/details/557722/errors-utilizing-activex-controls-in-vs-2010

http://connect.microsoft.com/VisualStudio/feedback/details/568769/aximp-error-with-vb6-activex-control

 

And possible workarounds are running the Aximp manually from the command line and the add the references. You will then need to add the control by hand in your forms. Do not use the designer to add the component, this will try to regenerate the references and reproduice the issue.

Share Code between Silverlight, Winforms and even Metro: Portable Library Tools

Maybe you faced the situation where you had code that was to be used on your server side services and also on your silverlight clients. 
Having this situation required some tricks because Silverlight Class libraries could not be used on .NET projects and viceversa.
Common workarounds were to share files and use precompilation directive iack!!

Well VS 2011 has a concept called Portable Class Libraries which allow you to create class libraries that can be use in Windows Phone, Silverlight, .NET framework, etc.

And if you have VS 2010 you don't have to suffer. Just use the Portable Library Tools from from the VS Extensions and start sharing code (see this image form the VS Extensions site)

  

 

For more details about Portable Libraries check the MSDN documentation page: http://msdn.microsoft.com/en-us/library/gg597391.aspx

 

How to create an adding that add context menu for certain files types in Visual Studio

21. October 2010 03:29 by Mrojas in Visual Studio  //  Tags: , , , , , , , , ,   //   Comments (0)

Recently I was looking for a way to create an Adding that will add a Context Menu only when I Right Click on .xaml files.

I know there a many ways now, but I still love using VS studio addins for some simple tasks.

In case you are wondering how to do that 

I found this great article: http://davedewinter.com/2008/03/22/dynamic-menu-commands-in-visual-studio-packages-part-2/