I had a situation recently where:

  1. I needed a cascading drop down interface
  2. I needed it to execute on the client
  3. I needed to reload the parent and child items' selection.

The Cascading DropDownList Extender is an excellent control as are its siblings inside the AjaxControlToolkit.  At first I was scouring the outputted JavaScript that it uses inline with the ServiceMethod to find a method by which I could programmatically set the selected index, which in turn should trigger the data retrieval.

"All other things being equal, the simplest solution is the best."

Occam's razor

It was at this point I saw that the Cascading DropDownList extender actually has a SelectedValue property.  I could have kicked myself when i saw it, as really I should have researched the control more and its capabilities and limitations.  Ever heard of the 7 P's - British SAS lol ?

So I integrated it with a control I built.  The control was a Region, County, TownCity and Area selection in respective order, so as to bring more structure to clients addresses for a project I am currently on.  Similar to a previous post where I create a composite control I declare the control extenders inside this custom composite control and control which I render dependant on other properties which are set. 

        private void CreateRegion()
        {
            DropDownListRegion = new DropDownList();
            DropDownListRegion.ID = this.ID + "_DropDownListRegion";
            CascadingDropDownRegion = new CascadingDropDown();
            CascadingDropDownRegion.ID = this.ID + "_CascadingDropDownRegion";
            CascadingDropDownRegion.Category = REGION_CATEGORY;
            CascadingDropDownRegion.EmptyText = REGION_EMPTYTEXT;
            CascadingDropDownRegion.EmptyValue = "0";
            CascadingDropDownRegion.LoadingText = REGION_LOADINGTEXT;
            CascadingDropDownRegion.PromptText = REGION_PROMPTTEXT;
            CascadingDropDownRegion.PromptValue = "0";
            CascadingDropDownRegion.ServiceMethod = REGION_SERVICE_METHOD;
            CascadingDropDownRegion.ServicePath = SERVICE_PATH;
            CascadingDropDownRegion.TargetControlID = DropDownListRegion.ID;
            if (RegionID != 0)
                CascadingDropDownRegion.SelectedValue = RegionID.ToString();
            Controls.Add(DropDownListRegion);
            Controls.Add(CascadingDropDownRegion);


            if (UseAddressLevel == AddressLevel.Region)
            {
                RequiredFieldValidatorRegion = new RequiredFieldValidator();
                RequiredFieldValidatorRegion.ID = this.ID + "_RequiredFieldValidatorRegion";
                RequiredFieldValidatorRegion.ControlToValidate = DropDownListRegion.ID;
                RequiredFieldValidatorRegion.InitialValue = "0";

                ValidatorCalloutExtenderRegion = new ValidatorCalloutExtender();
                ValidatorCalloutExtenderRegion.ID = this.ID + "_ValidatorCalloutExtenderRegion";
                ValidatorCalloutExtenderRegion.TargetControlID = RequiredFieldValidatorRegion.ID;

                Controls.Add(RequiredFieldValidatorRegion);
                Controls.Add(ValidatorCalloutExtenderRegion);
            }
        }

image

So the whole thing above is a control, but the amount of collapsible extenders displayed is control by an enum called AddressLevel.  How it works is simply like this, if you only require the Town and City, it is this level with which you set it, what happens then is that the area will not be displayed and also the TownAndCity will gain validation.

Line 16 of the code above will set selected index based on whether the RegionID has been set.  I find it so handy and useful that I can strongly type my .NET controls to work with the control extenders as it just adds a greater level to the UI experience.  Strongly Typing Javascript is also a good IDEA and something which I want to touch on in later posts aswell.

Cheers,

Andrew

P.S. setting the selected index for multiple cascading dropdownlists will work so its parent gets populated and set's the selected value using client side code, the child cascading dropdownlist will wait for this event, then populate and THEN check for the presence of the selected value in its items and again use client side to set the selected index.  After that it CASCADES!! lol



AJAX | ASP.NET | C# | JavaScript
Tuesday, January 27, 2009 11:07:54 AM (GMT Standard Time, UTC+00:00)  #    Disclaimer

A comparison with other languages to .NET during my programming experiences.

I like to bring a .NET programming naming convention to my other programming in different languages e.g. parameters, local variables, interfaces, functions etc...

Of late I am programming in Java more and more, as an accompaniment to my current programming skill set and by no means a substitution.  What I mean is that I am offering Java now as one of my skill set, if it fits a clients specification, so in essence giving me more tools and the client more options.

I would like to point out one observation though from the outset. 

As my background is from .NET and Microsoft managed languages, I am constantly making adhoc comparisons, judgements, evaluations etc... between the two.

  • Hmmm I like that idea, or
  • Nah that's good but I prefer the way they do it in ... or
  • Hey that's cool, both have opted to go they same way on that one!

So basically my likes, dislikes, wants, unknowns and general observations of equality. so below I have grouped a few observations so far.

Interfaces

I definitely prefer to prefix my interfaces with the uppercase I, i.e. IMyInterface as opposed to simply MyInterface.  So when I am coding I use the I prefix for my interfaces, as I like the immediate and obvious differentiation between an interface and class object.

In Java you have to specify public scope for your methods, where as in C# this is not allowed and it is presumed that the coder understands any methods WILL BE public.  I am on the fence on this one as I can see benefits for both.

Properties

I like the getter and setter convention in C#, including the new shortcuts in .NET 3.5 which describe properties, e.g.

public string MyProperty{get;set;}

or

public string MyProperty{
	get{return myProperty;}
	set{myProperty = value;}
}

Method Overloading

This is a like I had from ActionScript, and one which I have read WILL be implemented in C# 4.0, and I am not sure of its name but i call it Dynamic Method Overloading.  In ActionScript you are able to provide the paramaters of a method's signature with default values.  So for example say you have ONE method with TWO parameters and the second one having a default parameter e.g.

public int MyMethod(int firstArg, int secondArg = 2)
{
	Add(firstArgs,secondArg);
}

I could then call this function like so:

int value1 = MyMethod(10); //Result would be 12
int value2 = MyMethod(10,10) //Result would be 20

So you can see in the first invocation I only supply one parameter, yet what is returned is the first parameter and also the second parameter added together as per the method's instruction.

Namespace Import

This is not a like or dislike but rather an observation of dissimilarity.  If I want to import all classes from the System.Net namespace inside .NET I can do just that by saying using System.Net yet in Java I must suffix with an asterisk, and one of the reason I can understand as to the reason is that you can import single classes as opposed to their namespace or package. For example I could specify an import for a JCheckBox itself in Java i.e.

import javax.swing.JCheckBox;

I could not do the same in C#, for example the following is not correct:

using System.Net.Sockets.Socket;

Again I neither like or dislike both of them but I think the difference is ironically large and small at the same time.

Event Model

I will be publishing a post about this topic individually in which I will describe events using a model a showing the relevant counterparts of C#, Java and ActionScript.  I have not yet got the knowledge to produce a C++ example so if anyone reading could and kindly would not mind, I would greatly appreciate the input.

Each of the following are what I feel I need to focus on in the blog post for each language by way of how they implement an Observer Pattern or Events.

In Java there are a the following to focus on which have slightly different uses but ultimately for the same purpose which is notification of change or action.

  • Observer
  • Observerable
  • EventObject
  • EventListener

In C# I need to focus on:

  • Delegates
  • EventHandlers
  • Event
  • Chaining Invocation

In ActionScript I would focus on:

  • The Event Object
  • The IEventDispatcher Interface

I will use an example for the above languages and a few events a car emits which will show the different implementations of the above.

Class Naming Conventions

Both Java and ActionScript require the name of the file to equal the name of the class.  C# on the other hand does not have this requirement.  I would assume that this is because in C# I am able to put more than one class in a .cs file, and by that I do not mean nesting.  In Java and ActionScript I can nest classes inside others but I cannot start a new class declaration in the same file after one has already been declared.  Personally I agree with the Java implementation and would like to see each class in its own file if not required to nest.

That being said though I think that Partial Classes in .NET are such a good IDEA and a great piece of architectural planning and implementation.

Tis all for now lol.



ActionScript | C# | Java
Tuesday, January 27, 2009 10:56:48 AM (GMT Standard Time, UTC+00:00)  #    Disclaimer

I am currently inside the NetBeans IDE which is my IDE of choice at the moment for my Java development.  I thought I would mention a refactoring feature I would like to see inside Visual Studio "Out of the Box."  It is with regards to the encapsulation of fields. 

  • Yes you can create a class diagram and encapsulate a field
  • Yes you can right click in code view and encapsulate a field
  • Yes you can download, purchase or create a plug in to do the following

BUT, I would like to see two things:

  1. The following functionality out of the box ready
  2. The ability to encapsulate a selection of fields or to be able to select the fields you would like to encapsulate inside a nice GUI Dialogue.

Some may say lazy, others may say more productive.  In NetBeans I can go to the refactor menu and click encapsulate fields and I am presented with a nice dialogue where I can select the fields I would like to encapsulate and also a few more properties to describe the encapsulation I desire for each field.  Just saves time in my view.

image

I am greedy lol, what I would also like to see form the NetBeans dialogue above is also to open it up after refactoring and being able to edit.  That would be really useful.  I am going to download Visual Studio 2010 and see what is new and going on lol.  It can be found here:

http://www.microsoft.com/downloads/details.aspx?FamilyId=922B4655-93D0-4476-BDA4-94CF5F8D4814&displaylang=en

Cheers,

Andrew



C# | Java
Saturday, January 17, 2009 12:59:22 PM (GMT Standard Time, UTC+00:00)  #    Disclaimer

You can download the files here. 

Until a few weeks ago I did not know about a feature called Control State.  I knew of course about ViewState but not Control State.  I would love to know everything about everything in this game i.e. computing, but as you will agree that is extremely difficult to do.  Another ting I have found myself doing in the past is for example using a client side script helper, e.g. calendar date picker, to populate a textbox.  This looks a lot nicer, helps the user and reduces validation errors.  Now getting this value was a case of accessing the Request data for that specific control.  i.e.

Request.Form[MyTextBox.UniqueID]

Because we used a client side script to populate the control the server side TextChanged event would not get fired so we could not unfortunately  do this:

MyTextBox.Text

So, on this occasion a situation arose where by I had to create a few controls, being a custom HierarchialDataSource, a custom HierarchialDataSourceControl and also a nice custom TreeView with valid CSS.  I opted to create my own as opposed to CSS Control Adapters simply because I require some really bespoke features, plus I love learning how to make these things lol.

Now I am not going into these controls on this post but rather features of them, meaning the Control State and IPostBackDataHandler interface.  The control I want to make today involves 4 fields of which one will be a date field which will use the Ajax Control Toolkit Calendar Extender.  The fields will be Title, Firstname, Lastname and Date of Birth.

In title I have also stated  "Method Single Responsibility" and my reason for this is because only the other day I was listening to one of Scott Hanselman's pod casts on which he was speaking to Robert C. Martin or "Uncle Bob" as he is known in the programming world.  He stated that Single Responsibility should also be applied to methods as well or reason for change.  It was stated that lots of methods with smaller amounts of code wrapped around a single responsibility was easier to read, debug and maintain that fewer methods with bloated amounts of code which would undoubtedly contain lots of indentations.  So I am applying this, and wonder why I have never done this before, but this is all a learning curve.

Ok the first thing we will do on this control is create the fields and properties we require.  We will also create another class inside the control with the exact fields and properties as we have for the control, so copy and paste job; this will be used to control the state of the control in a much more strongly typed fashion, in fact truly strongly typed.  So here is the start of the control:

   public class PageInformationControl
    {
        #region Fields and Properties
        private string title;
        /// <summary>
        /// The person's title
        /// </summary>
        public string Title
        {
            get { return title; }
            set { title = value; }
        }

        private string firstname;
        /// <summary>
        /// The person's firstname
        /// </summary>
        public string Firstname
        {
            get { return firstname; }
            set { firstname = value; }
        }

        private string lastname;
        /// <summary>
        /// The person's lastname
        /// </summary>
        public string Lastname
        {
            get { return lastname; }
            set { lastname = value; }
        }

        private DateTime dateOfBirth;
        /// <summary>
        /// The person's date of birth
        /// </summary>
        public DateTime DateOfBirth
        {
            get { return dateOfBirth; }
            set { dateOfBirth = value; }
        }

        #endregion

        #region StateObject

        /// <summary>
        /// An object to store the state of the object between postbacks
        /// </summary>
        [Serializable]
        protected class PageInformationControlControlState
        {
            private string title;

            public string Title
            {
                get { return title; }
                set { title = value; }
            }

            private string firstname;

            public string Firstname
            {
                get { return firstname; }
                set { firstname = value; }
            }

            private string lastname;

            public string Lastname
            {
                get { return lastname; }
                set { lastname = value; }
            }

            private DateTime dateOfBirth;

            public DateTime DateOfBirth
            {
                get { return dateOfBirth; }
                set { dateOfBirth = value; }
            }
        }

        #endregion
    }

Next we need to add the Base Class and also the Interface we are going to be using.

    public class PageInformationControl : CompositeControl,IPostBackDataHandler

Next we want to do the following:

  1. Override the base OnInit method and register a couple of instructions with the page
  2. Implement the IPostBackDataHandler, this relies on the point above, i.e. otherwise the interface methods will not be called.
  3. Override two methods of the base class being
    1. SaveControlState
    2. LoadControlSate

Inside the OnInit method we will tell the ASP.NET Page that this control requires two things:

  1. Control State
  2. It also needs to be informed of PostBacks so it can alter and update its state

Here is the override OnInt event:

        protected override void OnInit(EventArgs e)
        {
            base.OnInit(e);
            //To instruct the page to call the methods require to manage Control State
            Page.RegisterRequiresControlState(this);
            //Required so that the IPostBackDataHandler are invoked.
            Page.RegisterRequiresPostBack(this);
        }

Followed by the overridden methods and implemented ones:

        protected override object SaveControlState()
        {
            return base.SaveControlState();
        }

        protected override void LoadControlState(object savedState)
        {
            base.LoadControlState(savedState);
        }

        #region IPostBackDataHandler Members

        public bool LoadPostData(string postDataKey, System.Collections.Specialized.NameValueCollection postCollection)
        {
            throw new NotImplementedException();
        }

        public void RaisePostDataChangedEvent()
        {
            throw new NotImplementedException();
        }

        #endregion

OK, that is kind of the shell of our control, next we need the interface components which will be the following:

  • A DropDownList for the Title of a person
  • A TextBox for the Person's Firstname
  • A TextBox for the Person's Lastname
  • A TextBox for the Person's DateOfBirth
    • It is this last one which we will use the AjaxControlToolkit and add a calendar extender.  This will populate the textbox from the client side yet you will see how you can strongly type your way to the value.
  • An AjaxControlToolkit TextBoxWatermarkExtender for the Firstname field so the client knows what to enter
  • An AjaxControlToolkit TextBoxWatermarkExtender for the LastName field so the client knows what to enter
  • An AjaxControlToolkit TextBoxWatermarkExtender for the DateOfBirth field so the client knows what to enter
  • An AjaxControlToolkit Calendar extender for the DateOfBirthField so we can get good data.

NOTE: If you have not done so already, you need to add the AjaxControlToolkit assembly to your project as a reference. You can find it here: Ajax Control Toolkit at asp.net/ajax

So we will declare them as protected members.

        #region User interface

        protected DropDownList DropDownListTitle;
        protected TextBox TextBoxFirstName;
        protected TextBox TextBoxLastName;
        protected TextBox TextBoxDob;
        protected AjaxControlToolkit.TextBoxWatermarkExtender WatermarkFirstname;
        protected AjaxControlToolkit.TextBoxWatermarkExtender WatermarkLastName;
        protected AjaxControlToolkit.TextBoxWatermarkExtender WatermarkTextBoxDob;
        protected AjaxControlToolkit.CalendarExtender CalendarDob;

        #endregion

Next is quite a long run.  We want to do the following:

  1. Override the CreateChildControls method
  2. Create a virtual method which starts the control generation
  3. Create virtual methods for handling each part of the user interface, but using the method in the above point to call them in the correct order.
  4. I have also put in a method which generates a CSS friendly wrapper for each control so as to avoid a table layout.

In each method I will specify the ID of each of the controls to get a real feel for the control.  I will also do this so that we can easily follow how i apply the control extenders to the controls.

        protected override void CreateChildControls()
        {
            Controls.Clear();
            CreateControlHierarchy();
            ClearChildViewState();
        }

        protected virtual void CreateControlHierarchy()
        {
            CreateTitle();
            CreateFirstName();
            CreateLastName();
            CreateDateOfBirth();
        }

        #region Single Responsibility UI Creation Methods

        protected virtual void CreateTitle()
        {
            Control wrapper = GetCssFriendlyControlWrapper();

            DropDownListTitle = new DropDownList();

            string[] titles = new string[] { "Mr", "Mrs", "Ms", "Miss", "Dr", "Prof" };

            foreach (string s in titles)
            {
                ListItem titleItem = new ListItem(s);
                DropDownListTitle.Items.Add(titleItem);
            }

            ListItem baseItem = new ListItem("Please select title");
            DropDownListTitle.Items.Insert(0, baseItem);

            wrapper.Controls.Add(DropDownListTitle);

            Controls.Add(wrapper);
        }

        protected virtual void CreateFirstName()
        {
            Control wrapper = GetCssFriendlyControlWrapper();

            TextBoxFirstName = new TextBox();
            TextBoxFirstName.ID = this.ID + "_TextBoxFirstName";

            WatermarkFirstname = new AjaxControlToolkit.TextBoxWatermarkExtender();
            WatermarkFirstname.ID = this.ID + "_WatermarkFirstname";
            WatermarkFirstname.WatermarkText = "Firstname";
            WatermarkFirstname.TargetControlID = TextBoxFirstName.ID;

            wrapper.Controls.Add(TextBoxFirstName);
            wrapper.Controls.Add(WatermarkFirstname);

            Controls.Add(wrapper);
        }

        protected virtual void CreateLastName()
        {
            Control wrapper = GetCssFriendlyControlWrapper();

            TextBoxLastName = new TextBox();
            TextBoxLastName.ID = this.ID + "_TextBoxLastName";

            WatermarkLastName = new AjaxControlToolkit.TextBoxWatermarkExtender();
            WatermarkLastName.ID = this.ID + "_WatermarkLastName";
            WatermarkLastName.WatermarkText = "Lastname";
            WatermarkLastName.TargetControlID = TextBoxLastName.ID;

            wrapper.Controls.Add(TextBoxLastName);
            wrapper.Controls.Add(WatermarkLastName);

            Controls.Add(wrapper);
        }

        protected virtual void CreateDateOfBirth()
        {
            Control wrapper = GetCssFriendlyControlWrapper();

            TextBoxDob = new TextBox();
            TextBoxDob.ID = this.ID + "_TextBoxDob";

            WatermarkTextBoxDob = new AjaxControlToolkit.TextBoxWatermarkExtender();
            WatermarkTextBoxDob.ID = this.ID + "_WatermarkTextBoxDob";
            WatermarkTextBoxDob.WatermarkText = "Date of Birth (yyyy-mm-dd)";
            WatermarkTextBoxDob.TargetControlID = TextBoxDob.ID;

            CalendarDob = new AjaxControlToolkit.CalendarExtender();
            CalendarDob.ID = this.ID + "_CalendarDob.ID";
            CalendarDob.Format = "yyyy-MM-dd";
            CalendarDob.TargetControlID = TextBoxDob.ID;

            wrapper.Controls.Add(TextBoxDob);
            wrapper.Controls.Add(WatermarkTextBoxDob);
            wrapper.Controls.Add(CalendarDob);

            Controls.Add(wrapper);
        }

        protected virtual Control GetCssFriendlyControlWrapper()
        {
            return new HtmlGenericControl("div");
        }

        #endregion

Ok we are nearly ready to test this.  What we need to ensure next, is that we handle postbacks correctly, and we maintain state.  We are going to make use of the state object which we made above.  One alternative is to use a HashTable for example but I like to have a strongly typed version.

So final few things:

  • SaveControlState
  • LoadControlState
  • LoadPostData
  • RaisePostDataChangedEvent
    • Although I am not demoing this event in this post, this can be used for example in conjunction with custom EventArgs and maybe create a Changed Event, where subscribers can access your data when the subscribed event is fired

      protected override object SaveControlState()
        {
            //Create an instance of the state object and fill it with the 
            //contents of the properties in the controls
            PageInformationControlControlState state = new PageInformationControlControlState
            {
                DateOfBirth = this.DateOfBirth,
                Firstname = this.Firstname,
                Lastname = this.Lastname,
                Title = this.Title
            };
            return state;
        }

        protected override void LoadControlState(object savedState)
        {
            //If the saved state is null, just return
            if (savedState == null)
                return;

            //Cast the savedState as your state object
            PageInformationControlControlState state = (PageInformationControlControlState)savedState;

            //Repopulate your properties after postback
            Title = state.Title;
            Firstname = state.Firstname;
            Lastname = state.Lastname;
            DateOfBirth = state.DateOfBirth;
        }

        #region IPostBackDataHandler Members

        public bool LoadPostData(string postDataKey, System.Collections.Specialized.NameValueCollection postCollection)
        {
            //Make sure you controls have been created
            EnsureChildControls();
            //Fill the properties using the post data.
            Title = postCollection[DropDownListTitle.UniqueID];
            Firstname = postCollection[TextBoxFirstName.UniqueID];
            Lastname = postCollection[TextBoxLastName.UniqueID];
            DateTime outDateTime;
            if (DateTime.TryParse(postCollection[TextBoxDob.UniqueID], out outDateTime))
                DateOfBirth = outDateTime;

            return true;
        }

        public void RaisePostDataChangedEvent()
        {
            //throw an updated event
        }

        #endregion

OK so we are now ready to create a test, were by I will add this new control to the screen and also a button to raise a postback and a textarea which will display an aggregation of the data formatted in a tidy way.  On thing I have done at this point is add the reference to the control inside the web.config.  I have started off with an ASP.NET WebApplication, if you are using a normal ASP.NET Website and hence using the App_Code folder just omit the assembly attribute but makesure you give your control a namespace inside the App_Code folder and that it relates to what you are about to put into the web.config.  The following is inline with my program properties, and it is the first control reference:

		<pages>
			<controls>
				<add tagPrefix="eapps" namespace="WebApplication1.Controls" assembly="WebApplication1"/>
				<add tagPrefix="asp" namespace="System.Web.UI" assembly="System.Web.Extensions, Version=3.5.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35"/>
				<add tagPrefix="asp" namespace="System.Web.UI.WebControls" assembly="System.Web.Extensions, Version=3.5.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35"/>
			</controls>
		</pages>

I will now create the web display:

<%@ Page Language="C#" AutoEventWireup="true" CodeBehind="Default.aspx.cs" Inherits="WebApplication1._Default" %>

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head runat="server">
    <title></title>
</head>
<body>
    <form id="form1" runat="server">
    <asp:ScriptManager ID="ScriptManager1" runat="server">
    </asp:ScriptManager>
    <div>
        <eapps:PageInformationControl ID="information1" runat="server" />
    </div>
    <asp:Button ID="Button1" runat="server" Text="Test PostBack" 
        onclick="Button1_Click" /><br />
    <asp:TextBox ID="TextBoxTest" runat="server" TextMode="MultiLine" Rows="6" 
        Columns="10" Width="239px"></asp:TextBox>
    </form>
</body>
</html>

Which gives a nice desgin time layout.  I will make a post about DesignTimeDesigning which is a cool topic and leads you into Windows Forms if you want to go that far, you don't have to like, BUT, it shows you the power of integration that is at your finger tips and can lead to commercial control development and may be an income dependant on the popularity and effectiveness of your controls.  As you will see form the graphic below you need to add a Script Manager to your page prior to running the code otherwise it will tell you the same thing lol.

image

Next we will populate the TextBox you see above with the data from our control in a formatted fashion when the Test postback button is clicked.

using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.UI;
using System.Web.UI.WebControls;
using System.Text;

namespace WebApplication1
{
    public partial class _Default : System.Web.UI.Page
    {
        protected void Page_Load(object sender, EventArgs e)
        {

        }

        protected void Button1_Click(object sender, EventArgs e)
        {
            StringBuilder sb1 = new StringBuilder();

            sb1.AppendFormat("Title : {0}", information1.Title);
            sb1.AppendLine();
            sb1.AppendFormat("Firstname : {0}", information1.Lastname);
            sb1.AppendLine();
            sb1.AppendFormat("Lastname : {0}", information1.Firstname);
            sb1.AppendLine();
            //Notice the next part.  It is nice and strongly typed even though the
            //textBox is populated using clientside code.
            //I am formatting the date as I do not want the Time part
            sb1.AppendFormat("Date of Birth : {0}", information1.DateOfBirth.ToString("yyyy-MM-dd"));
            sb1.AppendLine();

            TextBoxTest.Text = sb1.ToString();

            sb1 = null;
        }
    }
}

All that is left is to run the code.

image

 image

Conclusion

Making controls this way, may seem long winded but at the end you will get a reusable, portable control.  You can extend it, you can improve it, you can change it etc...  My favourite part about it is the fact that you can access postdata from you control in a strongly typed fashion from the C# server side layer. 

Extensions I can think of straight away involves validation and also integrating the Ajax Control Toolkit Validator Callout.

You can download the files here.



C#
Saturday, January 17, 2009 12:14:44 PM (GMT Standard Time, UTC+00:00)  #    Disclaimer

I have just been playing around making a small networking application using Java when i came across a small and dead simple function which I thought, "hey that is useful," and "oh that would now fit .NET Extension Methods."  So straight away lol and got my console up and had a play, and i know it may seem a bit trivial, but it is just a bit tidier than other methods you could use.  In all I just like the simple function of the .... function.  Working in a case sensitive language, it seems quite relevant to differentiate.

Anyway, enough blabbering, the function is called equalsIgnoreCase(String inValue) and to use in C# simply create a string extension method like so, with an implementation following:

    public static class StringExtensions
    {
        public static bool EqualsIgnoreCase(this string value, string compare)
        {
            return (compare.ToLower() == value.ToLower());
        }
    }

            Console.WriteLine("QuIt".EqualsIgnoreCase("quit"));

The output is True obviously :-)

Cheers,

Andrew



C# | Java
Friday, January 16, 2009 5:46:47 PM (GMT Standard Time, UTC+00:00)  #    Disclaimer

UPDATE 2009-01-27:  Choosing a Service model over a domain model inside NetTiers for the Component Layer can also achieve this functionality, but is definitely good to know and great to work with ObjectDataSources.  Reduces the code required for a lot of tasks dramatically.

Of late I have been dabbling with CodeSmith and also the templates for NetTiers, also making my own templates which is fun, but does demand a lot of time to generate re-usable templates.  Well to me anyway.  Now I do like NetTiers, all apart from the Web Layer which are UI controls and also Data controls.  I enjoy making strong use of ObjectDataSources to highly reduce code and improve pages, and one of the things that struck me was, well where are the parameter-less constructors, which is what I need to use the object against an ObjecDataSource.

This actually is no big hurdle for a couple of reasons but mainly because NetTiers creates such a detailed Domain Model.  So what I need and also how to make light work of this using Code Smith again but with my own template.

I need 5 base methods which will encapsulate the basic CRUD operations oh and the object is RestaurantType, not an enum but a type, only because the client will want to add more down the line and I do not want to rebuild the assembly for such a trivial addition.

  1. IList<RestaurantType> GetRestaurantTypes(int index, int pageSize, string sort);
  2. int GetRestaurantTypesCount(int index, int pageSize, string sort);
    1. Although this count method accepts the same parameters, it does not use them, it is simply to comply with the rule that the ObjectDataSource's Select Count method must have the same method signature and the Select method itself.
  3. void AddRestaurantType(RestaurantType restaurantType)
  4. void UpdateRestaurantType(RestaurantType restaurantType)
  5. void DeleteRestaurantType(RestaurantType restaurantType)

Another nice tip here is to decorate your class and the methods with Data Attributes which identify the class and also the methods as suitable for binding against.  Only the first, third, fourth and fifth method need decorating as the count method is not applicable, so CRUD:

  1. Create : [DataObjectMethod(DataObjectMethodType.Insert)]
  2. Read : [DataObjectMethod(DataObjectMethodType.Select)]
  3. Update : [DataObjectMethod(DataObjectMethodType.Update)]
  4. Delete : [DataObjectMethod(DataObjectMethodType.Delete)]

Finally the class itself is also decorated with the following:

[DataObject]

So here is the code for the simple data object with which I can bind an ObjectDataSource to.

   [DataObject]
    public class CustomRestaurantTypeDataSource
    {
        public static TransactionManager CreateTransaction()
        {
            TransactionManager transactionManager = null;
            if (DataRepository.Provider.IsTransactionSupported)
            {
                transactionManager = DataRepository.Provider.CreateTransaction();
                transactionManager.BeginTransaction(System.Data.IsolationLevel.ReadUncommitted);
            }
            return transactionManager;
        }

        [DataObjectMethod(DataObjectMethodType.Select)]
        public IList<RestaurantType> GetRestaurantTypes(int index, int pageSize, string sort)
        {
            int count = -1;
            TList<RestaurantType> restaurantTypes = DataRepository.RestaurantTypeProvider.GetPaged(index / pageSize, pageSize, out count);
            return restaurantTypes.ToList();
        }

        public int GetRestaurantTypesCount(int index, int pageSize, string sort)
        {
            int count = -1;
            DataRepository.RestaurantTypeProvider.GetPaged(out count);
            return count;
        }

        [DataObjectMethod(DataObjectMethodType.Insert)]
        public void AddRestaurantType(RestaurantType restaurantType)
        {
            using (TransactionManager tm = CreateTransaction())
            {
                DataRepository.RestaurantTypeProvider.Insert(tm, restaurantType);
                tm.Commit();
            }
        }

        [DataObjectMethod(DataObjectMethodType.Update)]
        public void UpdateRestaurantType(RestaurantType restaurantType)
        {
            using (TransactionManager tm = CreateTransaction())
            {
                DataRepository.RestaurantTypeProvider.Update(tm, restaurantType);
                tm.Commit();
            }
        }

        [DataObjectMethod(DataObjectMethodType.Delete)]
        public void DeleteRestaurantType(RestaurantType restaurantType)
        {
            using (TransactionManager tm = CreateTransaction())
            {
                DataRepository.RestaurantTypeProvider.Delete(tm, restaurantType);
                tm.Commit();
            }
        }
    }

I have then used this on my ObjectDataSource like the following:

    <asp:ObjectDataSource ID="RestaurantTypeDataSource" runat="server" 
        DataObjectTypeName="TM.Entities.RestaurantType" 
        DeleteMethod="DeleteRestaurantType" EnablePaging="True" 
        MaximumRowsParameterName="pageSize" 
        OldValuesParameterFormatString="original_{0}" 
        SelectCountMethod="GetRestaurantTypesCount" SelectMethod="GetRestaurantTypes" 
        StartRowIndexParameterName="index" 
        TypeName="TM.WebSite.CodeFiles.CustomRestaurantTypeDataSource" 
        UpdateMethod="UpdateRestaurantType">
        <SelectParameters>
            <asp:Parameter DefaultValue="0" Name="index" Type="Int32" />
            <asp:Parameter DefaultValue="10" Name="pageSize" Type="Int32" />
            <asp:Parameter Name="sort" Type="String" />
        </SelectParameters>
    </asp:ObjectDataSource>

In one of my next posts I will show how to make a pager control.  I do like the ASP.NET Pager control but I really feel it lacks one thing, and that being a PageChangedEvent.  In the pager I will make, you will be able to set the TotalNumberOfPages and also subscribe to the PageChanged Event.  I feel this is quite useful and we could also write in code to handle any IPageableContainers brought in with the .NET 3.5 wave.

Cheers,


Andrew


Friday, January 16, 2009 8:26:44 AM (GMT Standard Time, UTC+00:00)  #    Disclaimer

If you have read my very first post on this new blog you will know that I am now running dasBlog, and publishing through Windows Live Writer.  It is such an effortless thing to do using such an powerful tool.  Well I have always seen for example on Scott Hanselman's site the nice decoration of script examples, and I really should have just asked I suppose, "Where did you get that plugin from lol."  Either way I think I found it, well if it is not the same it is still ok because this one I have found certainly does the trick.

For anyone else wanting to use it BTW, the project is on CodePlex at this URL :
http://www.codeplex.com/wlwSyntaxHighlighter

Since I am publishing some of my posts onto two blogs now, It is only functioning on my personal blog at http://www.andrewrea.co.uk, but I will be adding this to my asp.net blog as soon as I figure out how.  I am sure there is a way of including a JS File inside the template.  There will be I am sure.

The little bit of code below, "the test," is just a little analysis of a URI.  It is not long since I discovered that the URI actually yields a string array called segments which very kindly deals with splitting up the url for you, at least the part after the domain and host type thing anyway.  All the same tis handy.

		[STAThread]
        static void Main(string[] args)
        {
            StringBuilder sb1 = new StringBuilder();

            Uri u1 = new Uri("http://www.formula1.com/Folder1/Folder2/Folder3/default.aspx?SampleQueryString=12");

            foreach (PropertyInfo pi in typeof(Uri).GetProperties())
            {
                sb1.AppendLine(pi.Name + ":" + pi.GetValue(u1, null));
            }

            foreach (string s in u1.Segments)
            {
                sb1.AppendLine(String.Format("Segment : {0}", s));
            }

            Clipboard.SetDataObject(sb1.ToString(), true);

            Console.ReadLine();
        }

The output.

/*
AbsolutePath:/Folder1/Folder2/Folder3/default.aspx
AbsoluteUri:http://www.formula1.com/Folder1/Folder2/Folder3/default.aspx?SampleQueryString=12
Authority:www.formula1.com
Host:www.formula1.com
HostNameType:Dns
IsDefaultPort:True
IsFile:False
IsLoopback:False
IsUnc:False
LocalPath:/Folder1/Folder2/Folder3/default.aspx
PathAndQuery:/Folder1/Folder2/Folder3/default.aspx?SampleQueryString=12
Port:80
Query:?SampleQueryString=12
Fragment:
Scheme:http
OriginalString:http://www.formula1.com/Folder1/Folder2/Folder3/default.aspx?SampleQueryString=12
DnsSafeHost:www.formula1.com
IsAbsoluteUri:True
Segments:System.String[]
UserEscaped:False
UserInfo:
Segment : /
Segment : Folder1/
Segment : Folder2/
Segment : Folder3/
Segment : default.aspx
*/

Another thing which I have been using of late is Reflector too.  This allows me to see the actual .NET source code for all of the assemblies e.g. System.Web, amazingly handy tool this one and FREE.

http://www.red-gate.com/products/reflector/

Of late I have had to make various Web Controls and Composite Controls and I wanted to get a real feel for the base class for which I am inheriting from so I could really get the most out of it.  Anyway have a go and disassemble away.  One thing you may wonder is what happens when you do not wish your code to be susceptible to such a tool, well what you can do is follow the process of Obfuscation.

http://msdn.microsoft.com/en-gb/magazine/cc164058.aspx

Cheers,

Andrew


Wednesday, January 07, 2009 8:45:48 PM (GMT Standard Time, UTC+00:00)  #    Disclaimer
Jan
03
2009

Settling In

Welcome new blog, how are you.  I have downloaded dasBlog for my blog and currently setting up.  I like everything so far and the design looks really user friendly and also developer friendly I like to say.  The macros available to you and also the extensibility of allowing you to create yourown macro through the API is a really nice feature.   OK so things to do:

  1. Check everything is integrated from feed burner perspective
  2. Check out the macros on offer and customise the display

There are other things I need to do but at this moment I am testing out the Windows Livewriter integration with which I use to write my blog entries for this and also the one over at http://weblogs.asp.net/andrewrea

I have decided to have two as I am developing on a few platforms and languages and my blog over at asp.net is really for things revolving around ASP.NET and .NET in general.  I want to also Blog about JAVA, Action Script, Flex and definitely my learning of C++ in the dawn of C++08.  Anyway lots to do this year and not enough hours in the day.  Best get started!!

Image Test, this was our most recent holiday which was Canada and it is Lake Louise below.  I think dasBlog sends the image to the MetaWeblog API which is really fast:

Photo009

To keep inline with my chosen title for my personal blog, I am going to choose a set project and work through different avenues of its construction including database, distributed architecture, the web, desktop clients.

I have not thought of the domain name yet so like Microsoft does, and for good reason I suppose, I will forge a code name for this:

Project Name: Orion's Belt

Meaning behind the code name: I suppose I chose this name due to the fact that there are numerous stars on this constellation and my philosophical comparison in that the stars are the languages or platforms and the project as a whole is the constellation i.e. each are a part of the whole.

  • C#
    • A WCF base layer for a Regular Expression Create and Share Service.
  • Java
    • A Java Client to consume the WCF Service, interoperability.
  • ASP.NET
    • A Web site to consume the WCF Service and also a look a Performance Counters and how an ASP.NET Website can also make use of these.
  • C++
    • Boy this is the hard one.  I have wanted to learn C++ now for about a year, I see it as the biggest step in my Career, and I cannot wait to leverage its power.  Anyway this will be a Native C++ Client to consume the WCF Service and will use the MFC, interoperability.
  • Action Script
    • This will be an Adobe AIR client for the WCF Service, interoperability.
  • SQL Server 2008
    • The actual database which will act as the storage layer for the project.

Deep Breath, and .......go!

Cheers,


Andrew


Saturday, January 03, 2009 3:00:10 PM (GMT Standard Time, UTC+00:00)  #    Disclaimer