Archive

Posts Tagged ‘C#’

Customize SpellCheck in WPF textbox

June 22nd, 2010 Anuraj P No comments

While working on a personal project (fleetIt). I worked on Textbox spell check option. I enabled it, it was working fine, until I added a context menu to to the textbox, for custom commands of my application. It was displaying the spelling errors but the suggestions and correction options was not available. Then I tried to customize the context menu such a way that it can display both my custom options as well as the system default spell check options. Here is a simple implementation, which helps to customize the context menu and display the spell check suggestions options.

<Window x:Class="dotnetthoughts.net.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:sys="clr-namespace:System;assembly=System"
Title="WPF SpellCheck Demo" Height="350" Width="525" Loaded="Window_Loaded">
<DockPanel>
<TextBox Name="txtEdit" SpellCheck.IsEnabled="True"
                AcceptsReturn="True"
ContextMenuOpening="txtEdit_ContextMenuOpening"
                VerticalScrollBarVisibility="Visible">
<TextBox.ContextMenu>
<ContextMenu Name="ctxMenu" />
</TextBox.ContextMenu>
</TextBox>
</DockPanel>
</Window>

And here is the code behind

namespace dotnetthoughts.net
{
    using System;
    using System.IO;
using System.Linq;
    using System.Windows;
    using System.Windows.Controls;
    using System.Windows.Documents;
    using System.Windows.Input;

public partial class MainWindow : Window
    {
public MainWindow()
        {
InitializeComponent();
        }

private void txtEdit_ContextMenuOpening(object sender, ContextMenuEventArgs e)
        {
            int index = 0;
this.txtEdit.ContextMenu.Items.Clear(); //Clearing the existing items
            //Getting the spellcheck suggestions.
SpellingError spellingError = this.txtEdit.GetSpellingError(this.txtEdit.CaretIndex);
if (spellingError != null && spellingError.Suggestions.Count() >= 1)
            {
                //Creating the suggestions menu items.
foreach (string suggestion in spellingError.Suggestions)
                {
MenuItem menuItem = new MenuItem();
                    menuItem.Header = suggestion;
menuItem.FontWeight = FontWeights.Bold;
menuItem.Command = EditingCommands.CorrectSpellingError;
                    menuItem.CommandParameter = suggestion;
menuItem.CommandTarget = this.txtEdit;
this.txtEdit.ContextMenu.Items.Insert(index, menuItem);
                    index++;
                }
Separator seperator = new Separator();
this.txtEdit.ContextMenu.Items.Insert(index, seperator);
                index++;
//Adding the IgnoreAll menu item
MenuItem IgnoreAllMenuItem = new MenuItem();
                IgnoreAllMenuItem.Header = "Ignore All";
IgnoreAllMenuItem.Command = EditingCommands.IgnoreSpellingError;
IgnoreAllMenuItem.CommandTarget = this.txtEdit;
                this.txtEdit.ContextMenu.Items.Insert(index, IgnoreAllMenuItem);
                index++;
            }
            else
            {
//No Suggestions found, add a disabled NoSuggestions menuitem.
                MenuItem menuItem = new MenuItem();
menuItem.Header = "No Suggestions";
                menuItem.IsEnabled = false;
this.txtEdit.ContextMenu.Items.Insert(index, menuItem);
                index++;
            }
//.Net 4.0 Supports CustomDictionaries, Option for Adding to dictionary.
int selectionStart = this.txtEdit.GetSpellingErrorStart(this.txtEdit.CaretIndex);
            if (selectionStart >= 0)
            {
                Separator seperator1 = new Separator();
this.txtEdit.ContextMenu.Items.Insert(index, seperator1);
                index++;
MenuItem AddToDictionary = new MenuItem();
                AddToDictionary.Header = "Add to Dictionary";
                //Getting the word to add
this.txtEdit.SelectionStart = selectionStart;
this.txtEdit.SelectionLength = this.txtEdit.GetSpellingErrorLength(this.txtEdit.CaretIndex);
                //Ignoring the added word.
AddToDictionary.Command = EditingCommands.IgnoreSpellingError;
AddToDictionary.CommandTarget = this.txtEdit;
AddToDictionary.Click += (object o, RoutedEventArgs rea) =>
                {
this.AddToDictionary(this.txtEdit.SelectedText);
                };
this.txtEdit.ContextMenu.Items.Insert(index, AddToDictionary);
                index++;
            }

//Common Edit MenuItems.
            Separator seperator2 = new Separator();
this.txtEdit.ContextMenu.Items.Insert(index, seperator2);
            index++;
            //Cut
MenuItem cutMenuItem = new MenuItem();
cutMenuItem.Command = ApplicationCommands.Cut;
this.txtEdit.ContextMenu.Items.Insert(index, cutMenuItem);
            index++;
            //Copy
MenuItem copyMenuItem = new MenuItem();
copyMenuItem.Command = ApplicationCommands.Copy;
this.txtEdit.ContextMenu.Items.Insert(index, copyMenuItem);
            index++;
            //Paste
MenuItem pasteMenuItem = new MenuItem();
pasteMenuItem.Command = ApplicationCommands.Paste;
this.txtEdit.ContextMenu.Items.Insert(index, pasteMenuItem);
            index++;
            Separator seperator3 = new Separator();
this.txtEdit.ContextMenu.Items.Insert(index, seperator3);
            index++;
            //Delete
MenuItem deleteMenuItem = new MenuItem();
deleteMenuItem.Command = ApplicationCommands.Delete;
            this.txtEdit.ContextMenu.Items.Insert(index, deleteMenuItem);
            index++;
            Separator seperator4 = new Separator();
this.txtEdit.ContextMenu.Items.Insert(index, seperator4);
            index++;
            //Select All
MenuItem selectAllMenuItem = new MenuItem();
selectAllMenuItem.Command = ApplicationCommands.SelectAll;
            this.txtEdit.ContextMenu.Items.Insert(index, selectAllMenuItem);
            index++;
        }
        //Method to Add text to Dictionary
private void AddToDictionary(string entry)
        {
using (StreamWriter streamWriter = new StreamWriter(@"D:\WPF\MyCustomDictionary.lex", true))
            {
streamWriter.WriteLine(entry);
            }
        }

private void Window_Loaded(object sender, RoutedEventArgs e)
        {
//Assigning custom Dictionary to TextBox
this.txtEdit.SpellCheck.CustomDictionaries.Add(new Uri(@"D:\WPF\MyCustomDictionary.lex"));
        }
    }
}

The .Net Framework 4.0 supports CustomDictionaries, which helps to create your own Dictionary.

//.Net 4.0 Supports CustomDictionaries, Option for Adding to dictionary.
int selectionStart = this.txtEdit.GetSpellingErrorStart(this.txtEdit.CaretIndex);
if (selectionStart >= 0)
{
    Separator seperator1 = new Separator();
this.txtEdit.ContextMenu.Items.Insert(index, seperator1);
    index++;
MenuItem AddToDictionary = new MenuItem();
    AddToDictionary.Header = "Add to Dictionary";
    //Getting the word to add
this.txtEdit.SelectionStart = selectionStart;
this.txtEdit.SelectionLength = this.txtEdit.GetSpellingErrorLength(this.txtEdit.CaretIndex);
    //Ignoring the added word.
AddToDictionary.Command = EditingCommands.IgnoreSpellingError;
AddToDictionary.CommandTarget = this.txtEdit;
AddToDictionary.Click += (object o, RoutedEventArgs rea) =>
    {
this.AddToDictionary(this.txtEdit.SelectedText);
    };
this.txtEdit.ContextMenu.Items.Insert(index, AddToDictionary);
    index++;
}

Here is the screenshot of Demo Application.

WPF Spell Check Demo - Screenshot

WPF Spell Check Demo - Screenshot

Categories: .Net, .Net 3.0 / 3.5, WPF Tags: , , , ,

ASP.Net Default button and Master Pages

June 21st, 2010 Anuraj P 3 comments

Last few days I was(am) busy with one pure ASP.Net application(why its pure because we are not using any 3rd party controls, ajax nothing. Everything is postbacking ;) ). Today I got a weird bug from one of my QC team saying when ever they presses ENTER button, focus is on any textbox, it popups Help window from our application. In our application, end users can open the Help window, by clicking on some help images icons provided in the application. These images are displayed using ASP Image button controls (If you are using ASP Image controls this problem will not occur, but in our application, we need to disable it some scenarios, so can’t use ASP Image). After searching I found the issue with the default button property of ASP.Net, which helps us to submit the form using Enter Key. In my page ASP.Net considering the Help image button as default button for the Page. We can set the default button to our submit button using various methods. Set the default button property of the FORM, or create a Panel control over the controls and set the default button property of the Panel.

<form id="form1" runat="server" defaultbutton="cmdSubmit">
<asp:Panel runat="server" ID="plMain" DefaultButton="cmdSubmit">

Form tag also supports “defaultfocus” this property allows to focus to control, on Page Load.

<form id="form1" runat="server" defaultbutton="cmdSubmit" defaultfocus="txtUser">

If you are using Master Pages, there will be some slight difference because, the Form tag will not be available in the content Pages. It can fix using code behind, using FindControl method.

(Page.Master.FindControl("Form1") as HtmlForm).DefaultButton = this.cmdSubmit.UniqueID;

Also you can do something like this

Page.Master.Page.Form.DefaultButton = cmdSubmit.UniqueID;

Happy Coding :)

Deploying WCF Service in IIS : no svc MIME Type

April 23rd, 2010 Anuraj P No comments

Few days back I developed a Silverlight application, which uses a WCF Service to communicate to Database. After the development when I tried to deploy the WCF Service on my IIS, it was displaying some error like

Server Error in Application “Default Web Site/SampleApp”
HTTP Error 404.3 – Not Found
Description: The page you are requesting cannot be served because of the Multipurpose Internet Mail Extensions (MIME) map policy that is configured on the Web server. The page you requested has a file name extension that is not recognized, and is not allowed.
Error Code: 0×80070032
Notification: ExecuteRequestHandler
Module: StaticFileModule
Requested URL: http://localhost:80/SampleApp/CoreService.svc
Physical Path: C:\Users\Documents\Visual Studio 2005\Projects\SampleApp\SampleApp\CoreService.svc
Logon User: Anonymous
Logon Method: Anonymous
Handler: StaticFile

I tried IIS MimeTypes and I couldn’t found an application mapping for SVC file. After doing some searching I found the fix. It is happening because of not registering the WCF in IIS. You can resolve this using WCF Installation utility which comes with .Net Framework 3.0. Run the command prompt as Administrator, go to the Windows Communication Foundation folder in c:\Windows\Microsoft.NET\Framework\v3.0\ folder. Execute the servicemodelreg.exe with -i or /i switch. After the installation try reloading the Page. It will fix this issue.

Convert string to enum

April 19th, 2010 Anuraj P No comments

Sometimes we may need to read a Config value using ConfigurationSettings.AppSettings and assign it to a Enum. This function helps to convert a string to Enum.

/// <summary>
/// Function to retrive Enum value by giving the corresponding string value.(This method is case sensitive)
/// </summary>
/// <typeparam name="T"></typeparam>
/// <param name="value">The value.</param>
/// <returns>Enum value</returns>
public static T ToEnum<T>(string value)
{
    //This method will throw error if the case of the value is different from the
    //enum value.
    if (Enum.IsDefined(typeof(T), value))
    {
        return (T)Enum.Parse(typeof(T), value, true);
    }
    throw new ArgumentException("Value doesn't exists in the Enum");
}
Categories: .Net, .Net 3.0 / 3.5, ASP.Net Tags: , , ,

How To Convert XMLNodeList To DataTable

April 14th, 2010 Anuraj P No comments

After doing an XPath selection using .Net, using XmlDocument.SelectNodes(), it will return XMLNodeList class, sometimes we required to convert the XMLNodeList to Data Table for binding purposes. I couldn’t find a direct way, only way is using looping through the Nodes.

/// <summary>
    /// Converts an XMLNodelist object to data table.
    /// </summary>
    /// <param name="xmlNodeList">The XMLNodeList to convert to DataTable.</param>
    /// <param name="Columns">The columns required for the DataTable, using this parameter the
    /// data will be fetched from xmlnodelist.</param>
    /// <returns>DataTable with columns specified in the Columns parameter</returns>
    public DataTable XmlNodeListToDataTable(XmlNodeList xmlNodeList, string[] Columns)
    {
        //Creating the DataTable.
        using (DataTable dataTable = new DataTable("DataTable"))
        {
            //Adding data Table columns based on the columns parameter
            foreach (string column in Columns)
            {
                dataTable.Columns.Add(column);
            }
            //Adding rows with values.
            DataRow dataRow;
            foreach (XmlNode node in xmlNodeList)
            {
                dataRow = dataTable.NewRow();
                foreach (string column in Columns)
                {
                    dataRow[column] = node.SelectSingleNode(column).InnerText;
                }
                dataTable.Rows.Add(dataRow);
            }
            return dataTable;
        }
    }

You can also create the columns dynamically, but you need to check for duplicate Data Columns.

How to check network available

April 5th, 2010 Anuraj P No comments

Sometimes we require to check whether the network is available or not, normally when are trying to do an Updated version check from our application or invoking a third party web service or any looking for any licence information / registration details from website etc.

This is a simple function which will return Network status using Ping Class.

using System.Net.NetworkInformation;
public bool IsNetworkAvailable()
{
	using (Ping ping = new Ping())
	{
		PingReply pingReply = ping.Send("www.google.com", 200);
		return pingReply.Status == IPStatus.Success;
	}
}