[HTML 5] How to customize the error message for a required field ?

November 16th, 2011 | Posted by Tom in HTML5 - (0 Comments) | Read: 34,720

In HTML 5, it’s possible to use the attribute required attribute of an input field to specify that this field need to be fill otherwise, a validation error is raised:

<label>Username:<sup>*</sup><input name="username" type="text" placeholder="Username" required="true" autofocus="true"/></label>

image

While this is useful and done automatically, you might prefer to customize the message that is displayed. To do that; you can use the setCustomValidity method:

$(document).ready(function () {
    var intputElements = document.getElementsByTagName("INPUT");
    for (var i = 0; i < intputElements.length; i++) {
        intputElements[i].oninvalid = function (e) {
            e.target.setCustomValidity("");
            if (!e.target.validity.valid) {
                if (e.target.name == "username") {
                    e.target.setCustomValidity("The field 'Username' cannot be left blank");
                }
                else {
                    e.target.setCustomValidity("The field 'Password' cannot be left blank");
                }
            }
        };
    }
})

Now, if an error is raised, the previous JQuery code will check the name of the field and display the correct error message:

image image

Again, a simple tip but very useful if you plan to use HTML 5 forms.

 

Happy coding!

[JQuery] How to call a WCF service from JQuery ?

November 14th, 2011 | Posted by Tom in .NET | JQuery | WCF - (2 Comments) | Read: 21,423

Blogging about JQuey/Javascript is a bit new for me but it’s not too late to change :-)

Today, I’ll try to show how you can have a JQuery script that call a simple WCF service.

The first part to achieve this result is to expose your WCF service so it can be accessed using REST and JSON. So apply the WebInvoke attribute to your service:

[ServiceContract(Namespace="http://wcf.runningbarbus.com/2011/")]
public interface IRunningBarbusService
{
    [OperationContract]
    [WebInvoke(ResponseFormat = WebMessageFormat.Json, RequestFormat = WebMessageFormat.Json, Method = "GET", BodyStyle=WebMessageBodyStyle.WrappedRequest)]
    List<RunDto> GetTeamData(int teamId, int weekNumber);
}

Now, modify your web.config’s file to expose the service through enableWebScript, an endpoint behavior that makes it possible to consume the service from ASP.NET AJAX pages:

<system.serviceModel>
    <services>
      <service name="RunningBarbus.Services.RunningBarbusService" behaviorConfiguration="DefaultBehavior">
        <endpoint address="" binding="webHttpBinding" contract="RunningBarbus.Services.IRunningBarbusService" name="RunningBarbus.Services.RunningBarbusService" behaviorConfiguration="AjaxBehavior">
          <identity>
            <dns value="locahost" />
          </identity>
        </endpoint>
        <endpoint contract="IMetadataExchange" binding="mexHttpBinding" address="mex" />
      </service>
    </services>
    <behaviors>
      <serviceBehaviors>
        <behavior name="DefaultBehavior">
          <serviceMetadata httpGetEnabled="true" />
          <serviceDebug includeExceptionDetailInFaults="true" />
        </behavior>
      </serviceBehaviors>
      <endpointBehaviors>
        <behavior name="AjaxBehavior">
          <enableWebScript />
        </behavior>
      </endpointBehaviors>
    </behaviors>
    <serviceHostingEnvironment multipleSiteBindingsEnabled="true" aspNetCompatibilityEnabled="true" />
</system.serviceModel>

Your WCF service is now available using an URL list: http://localhost/YourService.svc/YourMethod?Param=Value, so, in my case, I was able to see the JSON corresponding to the results by browsing the URL:

http://localhost/Services/RunningBarbusService.svc/GetTeamData?TeamId=1&WeekNumber=2

To finish, you just need access this URL, passing the correct parameters, using JQuery:

function GetTeamData(teamId, weekNumber) {
    $.ajax(
    {
        async: true,
        type: "GET",
        contentType: "application/json; charset=utf-8",
        url: "../../Services/RunningBarbusService.svc/GetTeamData",
        dataType: "json",
        data: '{"teamId":"' + teamId + '", "weekNumber":"' + weekNumber + '"}',
        success: function (content) {
            DisplayRun(map, content);
        }
    });
}

And that’s all ! Pretty simple but very useful, you can now access any WCF services from JQuery !

 

Happy coding!

In Windows Phone 7.1, there are 3 new events that can be used by developers to know when users press the buttons of the camera:

  1. CameraButtons.ShutterKeyHalfPressed
  2. CameraButtons.ShutterKeyPressed
  3. CameraButtons.ShutterKeyReleased

Using this events is really simple, as you can see in the following code:

private PhotoCamera _camera;

private void MainPage_Loaded(object sender, RoutedEventArgs e)
{
    CameraButtons.ShutterKeyHalfPressed += CameraButtons_ShutterKeyHalfPressed;
    CameraButtons.ShutterKeyPressed += CameraButtons_ShutterKeyPressed;
    CameraButtons.ShutterKeyReleased += CameraButtons_ShutterKeyReleased;
}

private void CameraButtons_ShutterKeyHalfPressed(object sender, EventArgs e)
{
    if (_camera != null)
    {
        _camera.Focus();
    }
}

private void CameraButtons_ShutterKeyPressed(object sender, EventArgs e)
{
    if (_camera != null)
    {
        _camera.CaptureImage();
    }
}

private void CameraButtons_ShutterKeyReleased(object sender, EventArgs e)
{
    if (_camera != null)
    {
        _camera.CancelFocus();
    }
}

Simple but very useful !

 

Happy coding!

AvalonEdit, a core component of SharpDevelop 4.0,  is a very useful component for anyone who want to re-create, in its application, a code/text editor. It provides some great features like:

  1. Autocompletion
  2. Tooltip
  3. Text highlighting
  4. An much more !

Sample Image

But if you need/want to create your own code editor, there are some steps that you’ll need to do and that be a bit hard to perform. I think, for example, to the following case:

  1. Find the word under the mouse to display it’s documentation on the tooltip
  2. Find the word before a dot (“.”) to display the correct values in the autocompletion box
  3. Add a custom highlighting

To help you in these tasks, I’ve create some extension methods that you can use directly:

public static class AvalonEditExtensions
{
    public static IHighlightingDefinition AddCustomHighlighting(this TextEditor textEditor, Stream xshdStream)
    {
        if (xshdStream == null)
            throw new InvalidOperationException("Could not find embedded resource");

        IHighlightingDefinition customHighlighting;

        // Load our custom highlighting definition
        using (XmlReader reader = new XmlTextReader(xshdStream))
        {
            customHighlighting = HighlightingLoader.Load(reader, HighlightingManager.Instance);
        }

        // And register it in the HighlightingManager
        HighlightingManager.Instance.RegisterHighlighting("Custom Highlighting", null, customHighlighting);

        return customHighlighting;
    }

    public static IHighlightingDefinition AddCustomHighlighting(this TextEditor textEditor, Stream xshdStream, string[] extensions)
    {
        if (xshdStream == null)
             throw new InvalidOperationException("Could not find embedded resource");

        IHighlightingDefinition customHighlighting;

        // Load our custom highlighting definition
        using (XmlReader reader = new XmlTextReader(xshdStream))
        {
            customHighlighting = HighlightingLoader.Load(reader, HighlightingManager.Instance);
        }

        // And register it in the HighlightingManager
        HighlightingManager.Instance.RegisterHighlighting("Custom Highlighting", extensions, customHighlighting);

        return customHighlighting;
    }

    public static string GetWordUnderMouse(this TextDocument document, TextViewPosition position)
    {
        string wordHovered = string.Empty;

        var line = position.Line;
        var column = position.Column;

        var offset = document.GetOffset(line, column);
        if (offset >= document.TextLength)
            offset--;

        var textAtOffset = document.GetText(offset, 1);

        // Get text backward of the mouse position, until the first space
        while (!string.IsNullOrWhiteSpace(textAtOffset))
        {
            wordHovered = textAtOffset + wordHovered;

            offset--;

            if (offset < 0)
                break;

            textAtOffset = document.GetText(offset, 1);
        }

        // Get text forward the mouse position, until the first space
        offset = document.GetOffset(line, column);
        if (offset < document.TextLength - 1)
        {
            offset++;

            textAtOffset = document.GetText(offset, 1);

            while (!string.IsNullOrWhiteSpace(textAtOffset))
            {
                wordHovered = wordHovered + textAtOffset;

                offset++;

                if (offset >= document.TextLength)
                    break;

                textAtOffset = document.GetText(offset, 1);
            }
        }

        return wordHovered;
    }

    public static string GetWordBeforeDot(this TextEditor textEditor)
    {
        var wordBeforeDot = string.Empty;

        var caretPosition = textEditor.CaretOffset - 2;

        var lineOffset = textEditor.Document.GetOffset(textEditor.Document.GetLocation(caretPosition));

        string text = textEditor.Document.GetText(lineOffset, 1);

        // Get text backward of the mouse position, until the first space
        while (!string.IsNullOrWhiteSpace(text) && text.CompareTo(".") > 0)
        {
            wordBeforeDot = text + wordBeforeDot;

            if (caretPosition == 0)
                break;

            lineOffset = textEditor.Document.GetOffset(textEditor.Document.GetLocation(--caretPosition));

            text = textEditor.Document.GetText(lineOffset, 1);
        }

        return wordBeforeDot;
    }
}

To use these methods, it’s really simple:

private void LoadCustomHighlighting()
{
    using (Stream s = typeof(MainWindow).Assembly.GetManifestResourceStream("CustomHighlighting.xshd"))
    {
        textEditor.SyntaxHighlighting = textEditor.AddCustomHighlighting(s);
    }
}

private void textEditor_MouseHover(object sender, MouseEventArgs e)
{
    var pos = textEditor.GetPositionFromPoint(e.GetPosition(textEditor));
    if (pos != null)
    {
        string wordHovered = textEditor.Document.GetWordUnderMouse(pos.Value);

        e.Handled = true;
    }
}

void textEditor_TextArea_TextEntered(object sender, TextCompositionEventArgs e)
{
    if (e.Text == ".")
    {
        var previousWord = textEditor.GetWordBeforeDot();
    }
}

As you can see, the whole difficult part is already managed by the extension methods. Of course, the code can be a bit ugly but, at least, it’s working fine. But feel free to post a comment if you have ideas to improve it !

 

Thanks and happy coding!

[Wix] How to use Wix to create Windows Installer files ?

October 17th, 2011 | Posted by Tom in .NET | Article | Divers | Wix - (1 Comments) | Read: 17,760

Wix is a technology that aims to help developer create Windows Installer file for the projects they’re developing. This is a very complete product but it can be a bit difficult to understand for new users. I’ll try to explain you how to create your first basic installer. I hope to be able to write more about Wix as soon as possible!

First, you need to download and install the latest version of Wix (latest stable version is 3.5, and the beta one is 3.6). Once it’s installed, just start Visual Studio and create a new project:

image

Wix projects are simple XML files (with the wxs extension) which describe the list of files that need to be copied on the target machine. They also define the various actions that can be performed during the installation (registry keys to be created, components that need to be installed, etc.).

A basic Wix file contains, at least, the following XML elements:

  1. Product: it’s used to describe the Windows Installer to be create (name, language, manufacturer, etc.)
  2. Package: this element contains the information that goes in the MSI’s summary information stream
  3. Directory: this is the element that will define in which folder the files need to be deployed.
  4. Component: this represents the component that needs to be deployed/installed. It can be a file, a registry key, a resource, etc.
  5. Feature: Each product is defined using features, which contains the components that have been declared above.

So, let’s take a look at this simple (but working) example:

<?xml version='1.0'?>

<Wix xmlns='http://schemas.microsoft.com/wix/2006/wi'>

   <Product Id="5168aa41-582e-4cb2-948f-cf2a8e5dff28" Name="My Addin Package" Language="1033" 

            Version="1.0.0.0" Manufacturer="Thomas Lebrun" UpgradeCode="e22d0f13-3cfa-4644-a466-807a93103c23" >

      <Package Description='My first Windows Installer package'

               Manufacturer="Thomas Lebrun" InstallerVersion='200' Compressed='yes' />

 

      <Directory Id="TARGETDIR" Name="SourceDir">

         <Component Id="MyComponent" Guid="D9247E78-1CB0-4F71-8D28-9F72581A647B" />

      </Directory>

      <Feature Id="MyFeature" Title="My 1st Feature" Level="1">

         <ComponentRef Id="MyComponent" />

      </Feature>

   </Product>

</Wix>

Then, we need to  define which file we want to add to our installer. Indeed, for now, we have specified that a component will be deployed in the folder specify by user but we haven’t set which files will be in that folder. For that, we have to modify the component element to include a File element, which will define:

  1. Its Id
  2. Its name on the disk
  3. The source of the file to get and include in the installer

Again, here is a working example:

<Directory Id="TARGETDIR" Name="SourceDir">

    <Component Id="MyComponent" Guid="D9247E78-1CB0-4F71-8D28-9F72581A647B">

        <File Id="myDll" Name="Sample.dll" Source="Sample.dll" />

    </Component>

</Directory>

Now, if you compile the project, you can go in the bin\Debug (or bin\Release) folder to see your MSI file! Visual Studio handles the call to the executable files (candle and light) that need to be run to create the file!

If you want to create some entries in the registry, it can also be done simply:

<Component Id="MyRegistryKeys" Guid="4D1643FD-A530-4AA0-9D07-BF0469C3D505">

    <RegistryKey Root="HKCU" Key="Software\Microsoft\Office\Excel\Addins\My Addin" Action="createAndRemoveOnUninstall">

        <RegistryValue Type="string" Name="Description" Value="My first Excel addin." />

        <RegistryValue Type="string" Name="FriendlyName" Value="My Addin" />

        <RegistryValue Type="integer" Name="LoadBehavior" Value="3" />

        <RegistryValue Type="string" Name="Manifest" Value="[INSTALLLOCATION]MyAddin.vsto|vstolocal" />

    </RegistryKey>

</Component>

It’s interesting to note that the RegistryKey element has the attribute Action and its value is createAndRemoveOnUninstall, that allows the installer to remove, during the uninstall process, the registry key that has been create.

But, most of time, you need to perform more complex actions when your application is being installed. As an example, it might be necessary for your installer to check if a registry key exists. To do that, you can use the RegistrySearch action which, as you can guess, can be used to perform a search in the registry to locate a particular key.

<Property Id="VSTORUNTIMEREDIST">

    <RegistrySearch Id="VSTORuntimeRedist" Root="HKLM" Key="SOFTWARE\Microsoft\VSTO Runtime Setup\v4R" Name="Version" Type="raw" />

</Property>

 

<Property Id="OFFICERUNTIME">

    <RegistrySearch Id="OfficeRuntime" Root="HKLM" Key="SOFTWARE\Microsoft\VSTO Runtime Setup\v4" Name="Version" Type="raw" />

</Property>

Here, we use the same action twice to check in the registry if the VSTO 2010 Runtime has been installed (as this one can be installed as part of Office 2010 or as part of Visual Studio 2010, we need to perform 2 checks). Each result of the search is stored in a property and then, it’s possible to use these properties in Conditions element that allow you to display an error message if a specific condition is not satisfied:

<!-- Check if if VSTO 2010 Runtime has been installed by VSTO -->

<Condition Message="The Visual Studio 2010 Tools for Office Runtime is not installed. Please run setup.exe.">

    <![CDATA[Installed OR VSTORUNTIMEREDIST>="10.0.30319"]]>

</Condition>

 

<!-- Check if if VSTO 2010 Runtime has been installed by Office 2010 -->

<Condition Message="The Visual Studio 2010 Tools for Office Runtime is not installed. Please run setup.exe.">

    <![CDATA[Installed OR VSTORUNTIMEREDIST>="10.0.30319" OR OFFICERUNTIME>="10.0.21022"]]>

</Condition>

If you want your installer to look for a specific component, during installation, you can use the ComponentSearch action that will look for the specified product code (identified by a Guid) and let you know if the component is installed or not:

<Property Id="SHAREDPIA">

    <ComponentSearch Id="SharedPia" Guid="64E2917E-AA13-4CA4-BFFE-EA6EDA3AFCB4" />

</Property>

 

<Property Id="EXCELPIA">

    <ComponentSearch Id="ExcelPia" Guid="EA7564AC-C67D-4868-BE5C-26E4FC2223FF" />

</Property>

This time again, we need to use these properties (that allows us to check if the Office Shared PIA and Excel PIA are installed) in a Condition element:

<!-- Search for Office 2010 Shared PIA -->

<Condition Message="A required component for interacting with Excel 2010 is not available. Please run setup.exe.">

    <![CDATA[Installed OR SHAREDPIA]]>

</Condition>

 

<!-- Search for Office 2010 Excel PIA -->

<Condition Message="A required component for interacting with Excel 2010 is not available. Please run setup.exe.">

    <![CDATA[Installed OR EXCELPIA]]>

</Condition>

Now; just compile your project and you’ll get a MSI file that, if you run it, will perform some checks in the registry/components before installing your product. But there is a drawing back using this method. If a prerequisite is missing, you’ll have a MessageBox that will appear and display the message you’ve chosen to show. But users have no way to install the missing components. So we need to find a way to include, in our setup file, the installers of those components.

For that, you can edit the project file of your Wix project, in Visual Studio. Simply right click on your project and choose “Edit Project File”. This will show you the content of the file that is a simple MSBuild file. So, first, inside the Project element, add an ItemGroup element that will define the list of all the prerequisites components that will need to be include in the setup:

<ItemGroup>

    <BootstrapperFile Include="Microsoft.Net.Framework.3.5.SP1">

      <ProductName>.NET Framework 3.5</ProductName>

    </BootstrapperFile>

    <BootstrapperFile Include=".NETFramework,Version=v4.0">

      <ProductName>.NET Framework 4.0</ProductName>

    </BootstrapperFile>

    <BootstrapperFile Include="Microsoft.Windows.Installer.3.1">

      <ProductName>Windows Installer 3.1</ProductName>

    </BootstrapperFile>

    <BootstrapperFile Include="Microsoft.VSTORuntime.4.0">

      <ProductName>VSTO 2010 Runtime</ProductName>

    </BootstrapperFile>

    <BootstrapperFile Include="Microsoft.Office.PIARedist.2007">

      <ProductName>Office 2007 PIA</ProductName>

    </BootstrapperFile>

    <BootstrapperFile Include="Microsoft.Office.PIARedist.2010">

      <ProductName>Office 2010 PIA</ProductName>

    </BootstrapperFile>

</ItemGroup>

Now, we need to tell Wix that these components need to be deployed with our installer. So, at the end of the file, uncomment the target named “After Build” and add the following code:

<GenerateBootstrapper ApplicationFile="$(TargetFileName)"

                      ApplicationName="Intuitive Query Excel Addin"

                      BootstrapperItems="@(BootstrapperFile)" 

                      ComponentsLocation="Relative" 

                      CopyComponents="True" 

                      OutputPath="$(OutputPath)" 

                      Path="C:\Program Files (x86)\Microsoft SDKs\Windows\v7.0A\Bootstrapper\" />

This code is used to generate a bootstrapper, a setup.exe file that will be used to check the conditions and, if they’re not respected, will launch the setup of the appropriate missing component. The most important parts here are:

  1. BootstrapperItems: that matches to the ItemGroup element containing all the BootstrapperFile. Each element in this group will be defined as a requirement needed to be deployed with your application.
  2. Path: this points to the local path of the prerequisites that should be installed with your installer.

As an example, look at this picture that show all the available package that are on my computer:

SNAGHTML10a2feee

Each of these folders contains components that can be part of the installation of your application (but which need to be installed BEFORE your application).

If you compile your project, you’ll see that a lot of files/folders are generated:

image

The folders contains the prerequisites that are mandatory to install your application. The MSI file is your installer, the one you’ve build with your Wix project. And the setup.exe file is a simple bootstrapper, in charge of detecting the prerequisites, installing them if they are not present and launching the MSI once the system is ready !

Your Wix project is now finished but you can go further and decide to use it to build your application during continuous integration. If you are using Team Foundation Server to perform your builds, this is very easy to do because the Wix project you’ve created in Visual Studio, with the wixproj extension, is an MSBuild file. So, during your build, you can just run the MSBuild.exe application, giving it your Wix project:

image

As you’ve seen during this article, Wix files are only XML files so it might not be much fun to modify them in Visual Studio, even if we do get Intellisense. So you can take a look at the tool named WixEdit, that allow you to edit Wix files (with extension wxs) through a graphical interface:

SNAGHTML1464332b

Finally, here is a little tip if you already have a MSI file and want to get the Wix file corresponding to it. You can use the command-line tool Dark.exe’ (located in C:\Program Files\Windows Installer XML v3.6\bin or C:\Program Files (x86)\Windows Installer XML v3.6\bin) to decompile the MSI file.
Be careful, the file might be a quite big and hard to understand but you should be able to get a lot of useful information from it.

 

I hope this article helped you to better understand Wix and how to use it to build your own installers. I’ll try to publish more articles on Wix as soon as possible.

 

Happy coding!

With one of my colleague (and friend), Jonathan ANTOINE, we have just release a new book, in French, on the MVVM Pattern. It targets WPF, Silverlight and Windows Phone technologies.

clip_image001[6]

Its title is “MVVM, De la découverte à la maitrise” and aims to help developers to understand all the principles of the pattern. It is available as an eBook from our publisher: http://www.digitbooks.fr/catalogue/mvvm-antoine-lebrun.html but you can also order it as a paper book !

We hope you’ll appreciate it! Oh and, by the way, don’t hesitate to share the information if you like it!

Thanks and happy coding !

[Quick Tip] A job scheduler component for any .NET applications

September 26th, 2011 | Posted by Tom in .NET - (0 Comments) | Read: 941

Have you ever wonder how you could use a job scheduler in a .NET application ? Yes, it’s still possible to use workflow to get this behavior but, for some little projects, it might be a quite big technology.

So I’ve found Quartz.NET, which is described as “a full-featured, open source job scheduling system that can be used from smallest apps to large scale enterprise systems”.

The documentation is very good, there are a lot of tutorials and the API is pretty simple and consist only in:

  1. Declaring a job (the code that need to be executed)
  2. Declaring a trigger (which specify when the task need to be executed)
  3. Indicate when the trigger need to be executed for the first time
  4. Scheduling the job

So, in a few lines of code:

// construct a scheduler factory
ISchedulerFactory schedFact = new StdSchedulerFactory();

// get a scheduler
IScheduler sched = schedFact.GetScheduler();
sched.Start();

// construct job info
JobDetail jobDetail = new JobDetail("myJob", null, typeof(HelloJob));
// fire every hour
Trigger trigger = TriggerUtils.MakeHourlyTrigger();
// start on the next even hour
trigger.StartTimeUtc = TriggerUtils.GetEvenHourDate(DateTime.UtcNow);
trigger.Name = "myTrigger";
sched.ScheduleJob(jobDetail, trigger);

I strongly recommend that you take a look at this component which is pretty robust and very useful !

 

Happy coding !

Nouvelle URL, nouveau blog !

September 21st, 2011 | Posted by Tom in .NET | Divers | Silverlight | User Experience | VSTO | Windows Phone | WPF - (1 Comments) | Read: 4,833

Bonjour à tous,

J’y pensais depuis un moment, c’est maintenant chose faîte ! J’ai décidé de changer de plateforme de blog pour me lancer dans ma “propre” aventure.

Les activités prévues au programme seront les mêmes que sur mon précédent blog à savoir WPF, Silverlight,  Windows Phone, etc. mais en essayant de varier les plaisirs de temps en temps et surtout, en essayant de retrouver une activité un peu plus dense.

Je tiens à remercier la communauté de CodeS-SourceS, et notamment Nix et Cyril, pour m’avoir hébergé durant toutes ces années !

Vous remarqerez que le design de ce blog n’est, pour le moment, pas tout à fait abouti: j’espère que cela changera rapidement (si d’ailleurs vous souhaitez me filer un coup de main sur la partie  design/logo, n’hésitez pas à me le faire savoir, je risque d’en avoir besoin !)

 

A bientôt pour la suite !