# Sunday, October 23, 2011

There is an less known possibility to easily build Addins to IE in C#. Lets look at the simple sample.

Few starting words

There are few types of addins you can build in IE, lets concentrate on the addins that would help you manipulate with rendered page. These addins are called Browser Helper Objects. They are intended to be developer as COM components, but that’s nothing we cannot handle in C# prety easy.

What we need to do

First, we would like to create some code to register our addin in Internet Explorer addins Registry hive (HKLM\Software\Microsoft\Windows\CurrentVersion\Explorer\Browser Helper Objects). Because we are going to create a managed COM library, we can take advantage of ComRegisterFunction attribute. method with such a decoration will be called during COM registration process.

Sample registration and unregistration methods:

public static string BHOKEYNAME = "Software\\Microsoft\\Windows\\CurrentVersion\\Explorer\\Browser Helper Objects";

[ComRegisterFunction]
        public static void RegisterBHO(Type type)
        {
            RegistryKey registryKey = Registry.LocalMachine.OpenSubKey(BHOKEYNAME, true);

            if (registryKey == null)
                registryKey = Registry.LocalMachine.CreateSubKey(BHOKEYNAME);

            string guid = type.GUID.ToString("B");
            RegistryKey ourKey = registryKey.OpenSubKey(guid);

            if (ourKey == null)
                ourKey = registryKey.CreateSubKey(guid);

            ourKey.SetValue("Alright", 1);
            ourKey.SetValue("NoExplorer", 1);
            registryKey.Close();
            ourKey.Close();
        }

[ComUnregisterFunction]
        public static void UnregisterBHO(Type type)
        {
            RegistryKey registryKey = Registry.LocalMachine.OpenSubKey(BHOKEYNAME, true);
            string guid = type.GUID.ToString("B");

            if (registryKey != null)
                registryKey.DeleteSubKey(guid, false);
        }

Browser Helper Objects basics

Each BHO has to implement COM interface IObjectWithSite, so we need to create such a interface in our project.

IObjectWithSite interface sample:

[
ComVisible(true),
InterfaceType(ComInterfaceType.InterfaceIsIUnknown),
Guid("FC4801A3-2BA9-11CF-A229-00AA003D7352")
]

    public interface IObjectWithSite
    {
        [PreserveSig]
        int SetSite([MarshalAs(UnmanagedType.IUnknown)]object site);
        [PreserveSig]
        int GetSite(ref Guid guid, out IntPtr ppvSite);
    }

The interface has two main methods. SetSite is called when BHO is being created by IE and its passing an instance of WebBrowser object, which we can use to manipulate with dom, or catch various DOM events as we use later. GetSite in the other hand is being called by IE to get the current instance of its WebBrowser.

Here is sample implementation of SetSite and GetSite in a class that inherits from our IObjectWithSite:

public int SetSite(object site)
       {
           if (site != null)
           {
               webBrowser = (SHDocVw.WebBrowser)site;
               webBrowser.DocumentComplete += new DWebBrowserEvents2_DocumentCompleteEventHandler(this.OnDocumentComplete);
           }
           else
           {
               webBrowser.DocumentComplete -= new DWebBrowserEvents2_DocumentCompleteEventHandler(this.OnDocumentComplete);
               webBrowser = null;
           }
           return 0;
       }

       public int GetSite(ref Guid guid, out IntPtr ppvSite)
       {
           IntPtr punk = Marshal.GetIUnknownForObject(webBrowser);
           int hr = Marshal.QueryInterface(punk, ref guid, out ppvSite);
           Marshal.Release(punk);
           return hr;
       }

Working with the DOM

In previous code, we have set up our WebBrowser instance which we are going to work with. We have also setup two DOM events, that we are going to handle. DocumentComplete is being called after document successfully is rendered. (But there might be still some scripts, or AJAX requests on the page running). Second event, BeforeNavigate is being called after you click ENTER when you put a new address in the IE address bar.

public void OnDocumentComplete(object pDisp, ref object URL)
{
    document = (HTMLDocument)webBrowser.Document;

foreach (IHTMLInputElement tempElement in document.getElementsByTagName("INPUT"))
            {
                if (string.IsNullOrEmpty(tempElement.type))
                    continue;

                if (tempElement.type.ToLower() == "text" || tempElement.type.ToLower() == "password")
                {
                    IHTMLElement elem = (IHTMLElement)tempElement;
                    elem.style.border = "1px solid red";
                }
            }
}

In the code above, we have handler the event DocumentComplete. Using our previously obtained WebBrowser object (in SetSite method), we can traverse the DOM of current page and do some funny stuff with it. In this case, I am setting a red border to all text or password input boxes in the page.

Registering the component

Because we are working on a COM component, we need to register it manually. to do this, I use following command:

regasm /codebase BHOHelloWorld.dll

and to unregister just change the parameter to:

regasm /u BHOHelloWorld.dll

After registration, you have to enable the addin in Internet Explorer Addin Manager.

Here is how www.microsoft.com looks with our BHO (notify the ugly red border around the textbox):

image

Download the sample here

 

Further reading

Product Details

A nice book by Matthew Crowley covering new and classic fields of development for IE, including development of Browser Helper Objects discussed in the post.

 http://www.amazon.com/Pro-Internet-Explorer-Development-Applications/dp/1430228539/ref=sr_1_1?ie=UTF8&qid=1319374638&sr=8-1

kick it on DotNetKicks.com Sunday, October 23, 2011 3:53:10 PM (Central Europe Daylight Time, UTC+02:00)  #    Disclaimer  |  Comments [8]  |  Trackback
# Thursday, October 20, 2011

Sometimes you have a PC connected to network, but you need to create a WiFi HotSpot from it. This is an less known tip I guess so I wanted to publish it.

First, we need to open a Windows Command Line under Administrator account.

Then we need to type in there this command:

netsh wlan set hostednetwork mode=allow ssid=NetworkName key=NetworkPassword

Where NetworkName is the name of your new WIFI network and password is obvious. You need to type this as one command seperated by spaces.

Then we need to type another command:

netsh wlan start hostednetwork

Now we have started our new WiFi network. Only remaining step is to allow Internet Connection Sharing between the new network and your PC network connection.

To do this, you need to open Control Panes go to Network and Sharing Center, Click to Change Adapter Settings. Now, look for and Adapter, with Microsoft Virtual Wifi Miniport in the third line. Remember its name. On the Picture its Wi-Fi 3.

image

Then you need to click with Right mouse button to your PC Network Connection, on the Picture its Wired Enternet Connection and select Properties.

On the Properties, go to Sharing, enable Allow other network users to connect throught this computer’s Internet connection. And finally choose the Network which you remembered in step above, which is your new WiFi HotStop Network.

image

After clicking OK, you should have new network with specified password available.

This tip works in Windows 7/8.

kick it on DotNetKicks.com Thursday, October 20, 2011 10:48:31 PM (Central Europe Daylight Time, UTC+02:00)  #    Disclaimer  |  Comments [5]  |  Trackback
# Sunday, July 31, 2011

There are some specifics for calling WebMethods from ExtJS.

By default, ExtJS is passing a call to Ajax WebService as GET, with one default parameter "_dc" of the Get request and request looks like this:

http://localhost:60972/WebService1.asmx/GetJamesBondActors?_dc=1312120714323&myTest=a&bar=foo&page=1&start=0&limit=25

Also, any extraParams, or your operation parameters goes inside Request url.

You can notice that there are some extra parameters that ExtJS is passing in based on what component you are using (page, start, limit)

Don't worry about the _dc parameter, this one is added there automatically unless you disable caching and should be there for better handling of caching of each request.

 

How to read you ExtJS parameters a simple way ?

Without any change, you can read these passed parameters inside your WebService using this code:

        [WebMethod]
        [ScriptMethod( ResponseFormat = ResponseFormat.Json,
            UseHttpGet = true, XmlSerializeString = false)]
        public List<PhoneItem> GetJamesBondActors()
        {
            var test = this.Context.Request.Params["myTest"];
//..

This means that you need to read all your WebService parameters manually and no type control is in here, also your WebService cannot have any parameters by default.

 

How ASP.NET handles ScriptServices parameters and results

ASP.NET ScriptService is a specific WebService, that has Json formatted paraters and also automatically formats all its results into Json. That is a good advantage, but also requires additional setup in ExtJS.

When you try to change your WebService to accept any paramter, it will automatically expect them encoded as Json and that is not what ExtJS does by default.

ExtJs in the other hand by default passes all its parameters either encoded in Get request as Url parameters, or in the body of the Post request formatted as:

myParam=myParameterValue&mySecondParam=mySecondParameterValue

 

How to configure ExtJs to pass in Json formatted parameters which ASP.NET ScriptService is expecting ?

First, I did not want to pass my patameters in Json coming as Get patameters and I wanted to Use Post instead.

How to use Post instead of Get in ExtJS called ScriptService

First I need to disable my ScriptService Get method, which I can specify using Attribute UsetHttpGet over the WebMethod:

        [WebMethod]
        [ScriptMethod( ResponseFormat = ResponseFormat.Json,
            UseHttpGet = false, XmlSerializeString = false)]
        public List<PhoneItem> GetJamesBondActors(string myTest, string bar)        {
// ..

Next step is to setup Ext.data.proxy.Ajax (ExtJS ajax Proxy) action methods to be processed using specified methods (Post), here is my snippet:

                        proxy: new Ext.data.proxy.Ajax({ // 
                            url: 'WebService1.asmx/GetJamesBondActors',
                            actionMethods: {
                            create: 'POST',
                            destroy: 'DELETE',
                            read: 'POST',
                            update: 'POST'
                        }, // ..
This is all, when you compile your code, you should have all operations excepts the delete using Post.

To pass all your request as Json, I have created an class overriding default Ext.data.proxy.Ajax and I can use this new one instead of this default proxy in my configuration.

/// <reference path="/Scripts/ext-all-debug.js" />

Ext.define('Ext.ux.AspWebAjaxProxy', {
    extend: 'Ext.data.proxy.Ajax',
    require: 'Ext.data',

    buildRequest: function (operation) {
        var params = Ext.applyIf(operation.params || {}, this.extraParams || {}),
                                request;
        params = Ext.applyIf(params, this.getParams(params, operation));
        if (operation.id && !params.id) {
            params.id = operation.id;
        }

        params = Ext.JSON.encode(params);

        request = Ext.create('Ext.data.Request', {
            params: params,
            action: operation.action,
            records: operation.records,
            operation: operation,
            url: operation.url
        });
        request.url = this.buildUrl(request);
        operation.request = request;
        return request;
    }
});

Where the important line is "params = Ext.JSON.encode(params);", which will took parameters (either assigned to operation or to the proxy using extraParams and encode them to Json. Whole method is being called each time a request is being created to call Ajax method.

Now my HTML sample for creating ExtJs Grid:

<div id="example-grid"></div>

    <asp:ScriptManager ID="PageScriptManager" runat="server">
        <Scripts>
            <asp:ScriptReference Path="~/Scripts/ext-all-debug.js" />
            <asp:ScriptReference Path="~/Scripts/Ext.ux.AspWebAjaxProxy.js" />
        </Scripts>
    </asp:ScriptManager>

<script type="text/javascript">
    Ext.require([
    'Ext.grid.*',
    'Ext.data.*',
    'Ext.panel.*',
    'Ext.layout.container.Border'
]);

    Ext.namespace('EXT');
       
        Ext.define('Actors', {
            extend: 'Ext.data.Model',
            fields: ['Name', 'Phone']
        });

        
        var store = new Ext.data.Store(
                    {
                        proxy: new Ext.ux.AspWebAjaxProxy({ // 
                            url: 'WebService1.asmx/GetJamesBondActors',
                            actionMethods: {
                            create: 'POST',
                            destroy: 'DELETE',
                            read: 'POST',
                            update: 'POST'
                        },
                            extraParams: {
                              myTest: 'a',
                              bar: 'foo'
                            },
                            reader: {
                                type: 'json',
                                model: 'Actors',
                                root: 'd'
                            },
                            headers: {
                            'Content-Type': 'application/json; charset=utf-8'
                            }
                        })
                    });

        // create the grid
        var grid = Ext.create('Ext.grid.Panel', {
            store: store,
            columns: [
                    { text: 'Name', width: 180, dataIndex: 'Name', sortable: true },
                    { text: 'Phone', width: 180, dataIndex: 'Phone', sortable: true }
                ],
            renderTo: 'example-grid',
            width: 540,
            height: 200
        });

        store.load();

</script>
Now, how does it look my ScriptService:
namespace ExtJSData
{
    [WebService(Namespace = "http://tempuri.org/")]
    [WebServiceBinding(ConformsTo = WsiProfiles.BasicProfile1_1)]
    [System.ComponentModel.ToolboxItem(false)]
    [System.Web.Script.Services.ScriptService]
    public class WebService1 : System.Web.Services.WebService
    {
        public class PhoneItem
        {
            public string Name;
            public string Phone;
        }

        [WebMethod]
        [ScriptMethod( ResponseFormat = ResponseFormat.Json,
            UseHttpGet = false, XmlSerializeString = false)]
        public List<PhoneItem> GetJamesBondActors(string myTest, string bar)
        {
            var list = new List<PhoneItem>(new [] {
                              new PhoneItem() {Name="Sean Connery", Phone="001"},
                              new PhoneItem() {Name= "Pierce Brosnan",Phone= "002" },
                              new PhoneItem() {Name= "Daniel Craig",Phone= "003" }
                              });


            return list;
        }
    }
}

This is all, Sample can be downloaded here

kick it on DotNetKicks.com Sunday, July 31, 2011 5:02:22 PM (Central Europe Daylight Time, UTC+02:00)  #    Disclaimer  |  Comments [9]  |  Trackback
# Sunday, July 24, 2011

Eden Ridgway has created an ASP.NET Ajax Web Services proxy for ExtJS 3 and I like that because it allows developer to use ASP.NET Web Service references and dont need to write url directly in there.

Anyway, the code does not work anymore for ExtJS v. 4, because Sencha has changed their implementation a lot and there are some breaking changes. For example old Ext.data.HttpProxy is just an alias to a different class and above all, the class inheritance is changed a lot. More about this here:

http://docs.sencha.com/ext-js/4-0/#/guide/class_system

So I have created another implementation, what takes advantage of ExtJS inheritance system and inherits Proxy class.

Another advantage is that you can handle your ASP net calls from one place and you get another level of abstraction there.

The code of AspWebServiceProxy looks like this:

/// <reference path="/Scripts/ext-all-debug.js" />

Ext.define('Ext.ux.AspWebServiceProxy', {
    extend: 'Ext.data.proxy.Server',
    require: 'Ext.data',

    config: {
        webServiceProxyMethod: null,
    },

    read: function (operation, callback, scope) {
        var userContext = {
            callback: callback,
            scope: scope
        };
        
        var proxyWrapper = this;
        
        // Actual ASP.NET WS proxy call
        this.webServiceProxyMethod(
            function (response, context, methodName) { // On Success
                proxyWrapper.loadResponse(response, userContext, methodName);
            },
            function (response, context, methodName) { // On Error
                proxyWrapper.handleErrorResponse(response, userContext, methodName);
            }, null);

    },

    handleErrorResponse: function (response, userContext, methodName) {
        alert("Error while calling method: " + methodName + "\n" + response.get_message());
    },

    loadResponse: function (response, userContext, methodName) {
        var result = userContext.scope.reader.readRecords(response);
        
        // encapsulate returned ResultSet data with Operation class
        var operation = Ext.create('Ext.data.Operation', {
            getResultSet: function() { return result; },
            getRecords: function() {return result.records; },
            wasSuccessful: function() {return result.success; }
        });
        
        // result was replaced with operation
        userContext.callback.call(userContext.scope, operation, userContext.arg, true);
    }

});

And you can use this class like this from your ASP.NET Control/Page

<div id="example-grid"></div>

    <asp:ScriptManager ID="PageScriptManager" runat="server">
        <Services>
            <asp:ServiceReference Path="~/WebService1.asmx" InlineScript="false" />
        </Services>
        <Scripts>
            <asp:ScriptReference Path="~/Scripts/ext-all-debug.js" />
            <asp:ScriptReference Path="~/Scripts/Ext.ux.AspWebServiceProxy.js" />
        </Scripts>
    </asp:ScriptManager>

<script type="text/javascript">
    Ext.require([
    'Ext.grid.*',
    'Ext.data.*',
    'Ext.panel.*',
    'Ext.layout.container.Border'
]);

Ext.namespace('Example')
       
        Ext.define('Actors', {
            extend: 'Ext.data.Model',
            fields: ['Name', 'Phone']
        });


        var store = new Ext.data.Store(
                    {
                        proxy: new Ext.ux.AspWebServiceProxy({
                            webServiceProxyMethod: ExtJSData.WebService1.GetJamesBondActors
                        }),
                        reader: new Ext.data.reader.Json({
                                type: 'json',
                                model: 'Actors',
                                root: 'd'
                            })
                    });


        // create the grid
        var grid = Ext.create('Ext.grid.Panel', {
            store: store,
            columns: [
                    { text: 'Name', width: 180, dataIndex: 'Name', sortable: true },
                    { text: 'Phone', width: 180, dataIndex: 'Phone', sortable: true }
                ],
            renderTo: 'example-grid',
            width: 540,
            height: 200
        });

        store.load();

</script>

I haven't handled the secure ASP.NET "d" Json root, but it shouln't be a problem for you to do this in the loadResponse method.

Please also note the first line of the file, the magic comment

/// <reference path="/Scripts/ext-all-debug.js" />

will make JavaScript IntelliSense working inside your VisualStudio 2010 editor.

Sample project is for download here

kick it on DotNetKicks.com Sunday, July 24, 2011 6:51:11 PM (Central Europe Daylight Time, UTC+02:00)  #    Disclaimer  |  Comments [2]  |  Trackback
# Sunday, July 17, 2011

I wanted to show three ways how to set aliases for namespaces, objects and assemblies. Less known are the Assembly External aliases that are supported in Visual Studio.

Check the following snipped, which uses all possible aliases.

Code Snippet

  1. extern alias externsys;
  2. using System.Collections.Generic;
  3. using System.Linq;
  4. using System.Text;
  5. using sys = System;
  6. using con = System.Console;
  7. namespace AliasTests
  8. {
  9. class Program
  10.     {
  11. static void Main(string[] args)
  12.         {
  13. // Full namespace           
  14.             System.Console.WriteLine("Hello");
  15. // Global Namespace alias
  16.             sys::Console.WriteLine("Hello");
  17. // External alias
  18.             externsys::myLib.Writer.WriteText("Hello");
  19. // Object alias
  20. con.ReadLine();
  21.         }
  22.     }
  23. }

Namespace alias is just renaming of an existing namespace to different one.

Type alias is shortcut for a type from its full name (with namespace)

External alias is an identifier of specific assembly, where is the namespace taken from. By default, there is an external alias global for all referenced assemblies.

To set external alias in Visual Studio, you need to go to Solution Navigator, select an assembly.

image

When you select an assembly, you have to look into Properties and look for Aliases property. Specify some concrete external alias (instead of global) for the assembly.

Last step is to recognize the external alias in your code, using "extern alias" keyword.

Links:

Extern alias walkthrough - http://blogs.msdn.com/b/ansonh/archive/2006/09/27/774692.aspx

How to: Use the Namespace Alias Qualifier (C# Programming Guide) - http://msdn.microsoft.com/en-us/library/c3ay4x3d(v=vs.80).aspx

kick it on DotNetKicks.com Sunday, July 17, 2011 1:52:28 PM (Central Europe Daylight Time, UTC+02:00)  #    Disclaimer  |  Comments [5]  |  Trackback
# Monday, July 11, 2011

There has been a bunch of new browsers versions recently and everybody discuss all the time what is this or that browser current overall performance, so lets look at the current results:

image

Well, I am surprised with Opera team's Opera Next state. I was expecting a bit more from FireFox and also from IE 10. But Microsoft is making some progress with these and hopefully they wont stop at some point. Notice that MS is currently third from the traditional "race" leaders (Chrome and Opera).

kick it on DotNetKicks.com Monday, July 11, 2011 11:34:38 PM (Central Europe Daylight Time, UTC+02:00)  #    Disclaimer  |  Comments [16]  |  Trackback
# Tuesday, July 05, 2011

I was excited when I found that the Marketplace content can be downloaded as standard Atom feed. If you are interested how Microsoft uses this for WP7 and what information you can get from there, read on ..

Marketplace is an application displaying Atom content. Atom is a standard that can be easily extended with custom metadata, while its compatibility with Atom feed format will remain. For this extensibility, is for example OData protocol a subset of Atom, but it can be used in any custom application with little effort.

Marketplace requests

Microsoft uses Akamai CDN for distributing the load and that's why I guess you have to pass extra headers to the requests for Atom. The whole code for making requests looks like:

// Forming the requests
WebRequest request = HttpWebRequest.Create(http://catalog.zune.net/v3.2/en-GB/clientTypes/WinMobile%207.0/hubTypes/marketplace/hub?store=Zest&store=&store=HTC);

// Settings the headers
((HttpWebRequest)request).UserAgent = "ZDM/4.0; Windows Mobile 7.0;";
((HttpWebRequest)request).Host="catalog.zune.net";
((HttpWebRequest)request).Headers.Add("Cache-Control", "no-cache");

// Reading the response
var response = request.GetResponse();
StreamReader reader = new StreamReader(response.GetResponseStream());
var content = reader.ReadToEnd();

This sample code reads list of available Hub Types.

Basic structure of Marketplace

Based on the structure of the application, requests are of following types in this order:

- Getting the Hub types
- Getting the applications list
- Getting the application details

Depending on the type of information you need, you need to form following requests:

// Hub Types
WebRequest request = HttpWebRequest.Create("http://catalog.zune.net/v3.2/en-GB/clientTypes/WinMobile%207.0/hubTypes/marketplace/hub?store=Zest&store=&store=HTC");

// Application list
//WebRequest request = HttpWebRequest.Create("http://catalog.zune.net/v3.2/en-GB/apps?orderBy=releaseDate&chunkSize=10&clientType=WinMobile%207.0&store=Zest&store=&store=HTC");

// Application details
//WebRequest request = HttpWebRequest.Create("http://catalog.zune.net/v3.2/en-GB/apps/e56de6d9-3782-e011-986b-78e7d1fa76f8?clientType=WinMobile%207.0&store=Zest&store=&store=HTC");

Please notice possibility of filtering the requests in Application List. For application details you need Application GUID, which you can get from Applications List.

Hub types request returns also some "Featured" applications, basically its the same Application GUID as you can get from Application List.

Getting the Hub Types response

<?xml version="1.0" encoding="utf-8"?>
<a:feed xmlns:a="http://www.w3.org/2005/Atom" xmlns:os="http://a9.com/-/spec/opensearch/1.1/" xmlns="http://schemas.zune.net/catalog/apps/2008/02">
  <a:link rel="self" type="application/atom+xml" href="/v3.2/en-GB/clientTypes/WinMobile%207.0/hubTypes/marketplace/hub?store=Zest&amp;store=&amp;store=HTC" />
  <a:updated>2011-07-05T16:45:14.629257Z</a:updated>
  <a:title type="text">marketplace-US-winMobile7</a:title>
  <a:id>marketplace-GB-WinMobile70-ALL-ALL</a:id>
  <templates>
    <template>
      <mimeType>application/uix</mimeType>
      <templateName>MarketplaceHub</templateName>
    </template>
  </templates>
  <a:entry>
    <a:link rel="alternate" type="application/atom+xml" href="/v3.2/en-GB/music/collection/features/08697005-97fe-4753-8c20-b4bc68dfc4f6" />
    <a:updated>2011-07-05T16:45:14.629257Z</a:updated>
    <a:title type="text">List Of Items</a:title>
    <a:id>urn:uuid:08697005-97fe-4753-8c20-b4bc68dfc4f6</a:id>
    <index>1</index>
    <link>
      <type>FeatureCollection</type>
      <target>08697005-97FE-4753-8C20-B4BC68DFC4F6</target>
    </link>
    <editorialItems>
      <editorialItem>
        <id>urn:uuid:95a33ce4-10ad-497a-9adf-35a289466762</id>
        <link>
          <type>Application</type>
          <target>e4571a02-0b87-e011-986b-78e7d1fa76f8</target>
        </link>
        <title>Angry Birds</title>
        <sequenceNumber>1</sequenceNumber>
        <image>
          <id>urn:uuid:3b32ef92-dba1-4e4f-867a-ee439349f698</id>
        </image>
        <backgroundImage>
          <id>urn:uuid:5a913f81-7e93-47e0-8c54-d58a9b723a29</id>
        </backgroundImage>
      </editorialItem>

... XML has been cut here for better readability

 

Most interesting is the Application Details

This response will return some metadata of the application, its price, and live URL of the application XAP package. (Try to download it from your Browser if you are interested what happens..)

Have some fun with this

kick it on DotNetKicks.com Tuesday, July 05, 2011 7:12:47 PM (Central Europe Daylight Time, UTC+02:00)  #    Disclaimer  |  Comments [9]  |  Trackback
# Sunday, June 26, 2011

Remember that Chevron team's goal was to make some support for sideloading on WP7 ? Now, the team finaly announced that it will be possible soon with new version of ChevronWP7 Labs.

For now, uploading your applications to phone is possible only throught paid Windows Phone developer account. Still, use of new ChevronWP7 Labs would be also charged by some small amount via PayPal to cover team's effort, but I guess, it would be only partial of full dev account price.

After using this new tool, shouldn't be a problem with relocking of your device and the whole tool will be Officially supported by Microsoft. Isn't that just great ?

Check ChevronWP7 labs or their twitter (@ChevronWP7)

http://labs.chevronwp7.com/

http://www.chevronwp7.com/post/6629433362/announcing-chevronwp7-labs

kick it on DotNetKicks.com Sunday, June 26, 2011 11:51:58 PM (Central Europe Daylight Time, UTC+02:00)  #    Disclaimer  |  Comments [11]  |  Trackback
# Tuesday, June 21, 2011

There are lot of chances when you need an background work indicator image. Now you can easily generate them online and download for free for your ajax or thick client applications with Ajaxload.

Try it for yourself here: http://www.ajaxload.info/

image

Some generated samples are here:

Circle ball ajax-loader 

Indicator big ajax-loader (1)

Bar ajax-loader (2)

kick it on DotNetKicks.com Tuesday, June 21, 2011 8:50:55 PM (Central Europe Daylight Time, UTC+02:00)  #    Disclaimer  |  Comments [8]  |  Trackback
# Monday, June 20, 2011

Pluralsight has published some of their MVC and ASP.NET training videos for free on the www.asp.net pages. If you haven't seen them yet, check it out, its a great content not only for beginners from real experts in the field.

Check the links:

http://www.asp.net/mvc and http://www.asp.net/web-forms

They have even more free videos, but if you are interested in the new Microsoft technologies, I recommend to check their page and subscription plan. I couldn't resisted not to subscribe :)

kick it on DotNetKicks.com Monday, June 20, 2011 11:46:16 PM (Central Europe Daylight Time, UTC+02:00)  #    Disclaimer  |  Comments [2]  |  Trackback