Tag Archives: C#

Binding A String to a Checkbox

In a recent project I was attempting to list data from a configuration settings database table. The values were boolean but stored as a ‘Y’ or a ‘N’ so that only one set of SQL’s was needed to be written, as the product supports both Oracle and SQL Server.

When I first put the GridView together, I was surprised to find that there was no Value property for the asp:checkbox nor could you bind any other column in a database but a ‘bit’ column to it.

The only solution I could come up with was to create a custom Checkbox and implement the feature. Below is the code for the custom Checkbox.

using System;
using System.ComponentModel;
using System.Web.UI;
using System.Web.UI.WebControls;
 
namespace ServerControls
{
    [Bindable(true)]
    [Category("Appearance")]
    [DefaultValue("")]
    [Localizable(true)]
    [ToolboxData("<{0}:CheckBoxValue runat=server></{0}:CheckBoxValue>")]
    public class CheckBoxValue : CheckBox
    {
        private string _value;
        private string _unCheckedValue;
        private string _checkedValue;
 
        public string Value
        {
            get { return _value; }
            set
            {
                _value = value;
                if (value != null && this.CheckedValue != null && this.UnCheckedValue != null)
                    base.Checked = value == this.CheckedValue;
            }
        }
 
        public string CheckedValue
        {
            get { return _checkedValue; }
            set { _checkedValue = value; }
        }
 
        public string UnCheckedValue
        {
            get { return _unCheckedValue; }
            set { _unCheckedValue = value; }
        }
 
        public override bool Checked
        {
            get { return base.Checked; }
            set
            {
                base.Checked = value;
                if (this.Value != null && this.CheckedValue != null && this.UnCheckedValue != null)
                    this.Value = value ? this.CheckedValue : this.UnCheckedValue;
            }
        }
 
        protected override void OnInit(EventArgs e)
        {
            Page.RegisterRequiresControlState(this);
            base.OnInit(e);
        }
 
        protected override object SaveControlState()
        {
            object[] state = new object[2];
            state[0] = base.SaveControlState();
            state[1] = this.Value;
            return state;
        }
 
        protected override void LoadControlState(object state)
        {
            object[] stateTmp = (object[])state;
            base.LoadControlState(stateTmp[0]);
            this.Value = (string)stateTmp[1];
        }
    }
}

The magic in the custom checkbox occurs in the Value property and the overridden Checked property.

When the value property is set, if it is the same as the ‘CheckedValue’ property then we set the base.Checked value to true else false. The same principles apply to the overridden Checked property. When the property is set we set the Value property to the ‘CheckedValue’ property if Checked equals true else we set it to the ‘UnCheckedValue’.

Once compiled we can then use this inside our GridView template and bind a varchar column from a database to it. Here is the syntax.


<
Custom:CheckBoxValue ID="cbv1" runat="server" CheckedValue="Y" UnCheckedValue="N" Value='<%# Bind("valueyn") %>' />

So when the GridView databinds and evaluates the ‘valueyn’ column; if the value is ‘Y’ then the checkbox will be checked and if the value is ‘N’ then the checkbox will be unchecked. Then if I choose to edit a line with the checkbox and change its value, the value stored in the database will match the value of the checkbox. eg. if the checkbox is checked, ‘Y’ will be entered into the database and if it is left unchecked then ‘N’ will be entered.

This seems to work extremely well for my project and suits my needs. It will even work if the ‘valueyn’ column is an Int, as long as you modify the ‘CheckedValue’ and ‘UnCheckedValue’ to something that can be implicitly converted to an Int.

Hope this helps. If you find any issues or have other ideas please don’t hesitate to leave a comment.

Importing Data Files with Linq

In my previous Linq post I discussed using Linq with Regular expressions and how much less code was needed. In this post we’ll again see how Linq can be used to speed up and simplify development.

There are many situations where you need to read data from a file into memory or a database. Lets consider this scenario.

We have a tab delimited data file that has been exported from some web or windows application etc. Below is the sample file.

carrots    4    0.64
beans      3    0.12
oranges    7    1.02
apples     5    0.87

This file includes three columns. Column 1is the name of the product. Column 2 is the quantity and Column 3 is the unit price. We would also like a total price column derived from column 2 being multiplied by column 3.

Our aim here is to load these into our application programmatically and then bind them to a gridview. Normally you would have to read the file in line by line then do a split on each line, enter each line into a prebuilt class or datatable then add a new column and multiply the quantity by the price to obtain the total. However by using a nice little extension helper method, all of this can be rolled into just a few lines of code.

public static IEnumerable<string> ReadLinesFromFile(string filename)
{
    using (StreamReader reader = new StreamReader(filename))
    {
        while (true)
        {
            string s = reader.ReadLine();
            if (s == null)
                break;
            yield return s;
        }
    }
}

Above is the extension method to convert lines of a file into a IEnumerable list of strings.

var products = from line in ReadLinesFromFile(@"c:\import.txt")
               let item = line.Split('\t')
               select new
               {
                   Product = item[0],
                   Quantity = Convert.ToInt32(item[1]),
                   Price = Convert.ToDecimal(item[2]),
                   Total = Convert.ToInt32(item[1]) * Convert.ToDecimal(item[2])
               };
GridView1.DataSource = products;
GridView1.DataBind();

What this gives us is a list of products, with each one having 4 properties associated with it. We can then bind this straight to a gridview by setting the datasource of the gridview to products and calling the DataBind() method. This will display a table with 4 columns with the headers Product, Quantity, Price and Total.

The Linq statement can then be modified in many ways to accommodate different file formats (eg. CSV or fixed width) with a few simple changes.

This is just another way Linq is making things easier!

Schotime

Select All (ctrl+A) For A Textbox

Have you ever tried to push ctrl+A on a multi-line or single line textbox in a Dot Net Windows Forms application to select all of the text? If you have you would know that it doesn’t work. That’s right, standard windows functionality doesn’t work for the TextBox control. So here’s how to fix it using a custom control.


namespace MyTextBoxDemo
{ public class MyTextBox : System.Windows.Forms.TextBox { protected override void OnKeyDown(System.Windows.Forms.KeyEventArgs e) { if (e.Control && (e.KeyCode == System.Windows.Forms.Keys.A)) { this.SelectAll(); e.SuppressKeyPress = true; e.Handled = true; } else base.OnKeyDown(e); } } }

Above you see the complete code. It is very simple and works by overriding the OnKeyDown event that the base TextBox class has. We check to see if the ctrl key is pressed in conjunction with the A key. If this is true we run the SelectAll() method which does all the work. Then we’re just left with suppressing the OnKeyPress event so we don’t get that annoying "beep!" and setting the handled function to true. If ctrl+A was not pressed then we proceed with the base OnKeyDown event, ensuring the MyTextBox control works exactly as the standard TextBox control does.

The MyTextBox control should be available to your project immediately after a build. It will also add the control to the toolbox automatically.

Hopefully this has added the standard functionality back into our dot net application and given you some hints on customising the TextBox control even further.

Schotime

Linq and Regular Expressions

With Linq now standard in .NET 3.5, there is no reason why we shouldn’t use it. After all its full of features that can be used by any object that inherits the type IEnumberable. With such power at our fingertips, sorting, filtering, manipulation etc. etc. are available to us with fewer lines of code than previous needed.

One powerful feature of programing is Regular Expressions. These provide a concise and flexible means for identifying text of interest, such as particular characters, words, or patterns of characters. So whilst going over some old code of mine to extract data from a remote website, I decided to give the Regular Expression part of my code a face lift with Linq.

The code below is the setup code just to give some background.

String StringToMatch = "<tr class=\"ar1\"><td>456642</td>"
        + "<td class=\"left\">John</td>"
        + "<td class=\"left\">Smith</td>"
        + "<td>j.smith@email.com</td></tr>"
        + "<tr class=\"ar1\"><td>456643</td>"
        + "<td class=\"left\">Edward</td>"
        + "<td class=\"left\">Norman</td>"
        + "<td>e.norman@email.com</td></tr>";

Regex r = new Regex("<tr class=\"(?:ar1|ar2)\"><td>([0-9]+)</td>"
        + "<td class=\"left\">(.*?)</td>"
        + "<td class=\"left\">(.*?)</td>"
        + "<td>(.*?)</td></tr>");

MatchCollection matches = r.Matches(StringToMatch);

The following code is the preLinq version of the code to process the Regular Expression.

List<Profile> Profiles = new List<Profile>();

if (matches.Count > 0)
{
    foreach (Match m in matches)
    {
        Profile p = new Profile();

        p.Id = m.Groups[1].Value;
        p.Firstname = m.Groups[2].Value;
        p.Lastname = m.Groups[3].Value;
        p.Email = m.Groups[4].Value;

        Profiles.Add(p);
    }
}

As you can see above, a strongly typed List of type Profile is created. Then we loop through each match, first creating a new instance of the Profile object. Filling the object up with the results from our Regular Expression and finally adding it to the list. Whilst this code is pretty straight forward, look how easily Linq handles this scenario.

if (matches.Count > 0)
{
     List<Profile> Profiles = (from Match m in matches
                              select new Profile
                              {
                                  Id = m.Groups[1].Value,
                                  Firstname = m.Groups[2].Value,
                                  Lastname = m.Groups[3].Value,
                                  Email = m.Groups[4].Value
                              }).ToList();
}

As you can see above, we have managed to reduced the amount of statements from around 8 to 1. So what this is doing in english is creating a strongly typed List of the type Profile and using Linq to fill it. It states that for ever Match m in the list matches, create a new object Profile and auto initialise the variables with the values contained in the match. Finally we convert the IEnumberable<Profile> result to a List<Profile> by using the method ToList().

How easy was that! Now say you wanted the list of Profile’s sorted by lastname. Well you would normally have to build the list as above and then call the Sort method using a defined Comparison object. This is where Linq becomes even more powerful. Simply by adding one line to the Linq statement above, the List generated will be sorted by lastname.

if (matches.Count > 0)
{
     List<Profile> Profiles = (from Match m in matches
                       --->   orderby m.Groups[3].Value
                              select new Profile
                              {
                                  Id = m.Groups[1].Value,
                                  Firstname = m.Groups[2].Value,
                                  Lastname = m.Groups[3].Value,
                                  Email = m.Groups[4].Value
                              }).ToList();
}

Also another point to add regarding the definition of class Profile. Back in .NET 2.0 days creating a class was pretty painful. A lot of repeated code just to get and object with some variables.

public class Profile
{
    private string _id;
    private string _firstname;
    private string _lastname;
    private string _email;

    public string Id
    {
        get { return _id; }
        set { _id = value; }
    }

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

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

    public string Email
    {
        get { return _email; }
        set { _email = value; }
    }
}

As you can see its way to long. Lets see how post .NET 2.0 does it.

public class Profile
{
    public string Id { get; set; }
    public string Firstname { get; set; }
    public string Lastname { get; set; }
    public string Email { get; set; }
}

Now thats what i’m talking about. Good work team. Thats how easy it should be to create a class!

Til’ Next Time, It’s Schotime Out!