Friday 28 November 2008

How to display HTML code in your Blogger Post

Convert the code to display in a blog post using this tool:

http://www.accessify.com/tools-and-wizards/developer-tools/quick-escape/default.php

Sorting and Paging a GridView with Custom DataSource in ASP.Net

So it's pretty simple to use a GridView in ASP.Net you can bind it to all sorts of data, but what I like doing is binding it to collections of my own custom objects. But this causes issues, because then you can't use all the nice in built paging and sorting without extra cosing. If you use the GridView wizard are hook it up to a SQLdatasource directly or a data set then all the paging and sorting is handled for you. But what if like me you want to use your own custome objects.

Well there is a way, it does require a little extras coding but it's nothing too complicated. Firstly lets look at the code to set up a standard GridView:

Client Side Code:



<asp:gridview id="GridView1" runat="server" autogeneratecolumns="False" onrowdatabound="GridView1_RowDataBound" onselectedindexchanging="GridView1_SelectedIndexChanging">

<columns>

<asp:boundfield datafield="ProjectID" headertext="ProjectID"/>

<asp:boundfield datafield="ProjectName" headertext="ProjectName"/>

<asp:boundfield datafield="Sector" headertext="Sector"/>

<asp:boundfield datafield="ProjectStatus" headertext="Project Status"/>

</columns>

</asp:gridview>


Server Side Code:


IList<project> projectList = Project.GetAllProjects();
GridView1. DataSource = projectList;
GridView1.DataBind();

Project Class:

public class Project
{

public Project()
{
}

public int ProjectID { get;set;}

public string ProjectName {get;set;}

public string Sector {get;set;}

public string ProjectStatus {get;set;}

static public Project GetAllProjects()
}





So this will display my list of custom objects in a simple GridView but I can't do paging or sorting, bummer. So what do we have to change to get it to work?

Well first on the ASP.Net page we add an ObjectDataSource control and point that to our datasource. This will help make our custome data collection more compatible with the GridView. We can then point out GridView at this ObjectDataSource.

We can then set paging on the GridView and Sorting. But for the sorting to work we still need some extra code. We need to make our custom data class comparable. So in the GetAllProjects method we add a parameter that will handle the sortExpression, we add this into the code of our GridView as well.

Then we add a switch statement in here to handle this sort expression. This requires us also to create a comparer class, we will call it ProjectComparer and in there we place code to handle the comparisons for each project value.


Client Side Code:

<asp:ObjectDataSource ID="dsProjects" runat="server" DataObjectTypeName="Business.DomainLogic.Project" TypeName="Business.DomainLogic.Project" SelectMethod="GetAllProjects" SortParameterName="sortExpression"></asp:ObjectDataSource>

<asp:GridView ID="GridView1" runat="server" AutoGenerateColumns="False"
OnRowDataBound="GridView1_RowDataBound" DataSourceID="dsProjects"
AllowPaging="True" PageSize="8" AllowSorting="True"
OnSelectedIndexChanging="GridView1_SelectedIndexChanging"
OnPageIndexChanging="GridView1_PageIndexChanging">
<Columns>
<asp:BoundField DataField="ProjectID" HeaderText="ProjectID" />
<asp:BoundField DataField="ProjectName" HeaderText="ProjectName" SortExpression="ProjectName" />
<asp:BoundField DataField="Sector" HeaderText="Sector" SortExpression="Sector" />
<asp:BoundField DataField="ProjectStatus" HeaderText="Project Status" SortExpression="ProjectStatus" />
</Columns>
</asp:GridView>


Server Side Code:


protected void GridView1_PageIndexChanging(object sender, GridViewPageEventArgs e)
{
GridView1.PageIndex = e.NewPageIndex;
GridView1.DataBind();
}

Project Class:

public List<project> GetAllProjects(string sortExpression)
{
List<project> projects = new List<project>();

switch (sortExpression)
{
case "ProjectName":
case "ProjectName ASC":
projects.Sort(ProjectComparer.CompareByName);
break;

case "ProjectName DESC":
projects.Sort(ProjectComparer.CompareByNameDesc);
break;

case "Sector":
case "Sector ASC":
projects.Sort(ProjectComparer.CompareBySector);
break;

case "Sector DESC":
projects.Sort(ProjectComparer.CompareBySectorDesc);
break;

case "ProjectStatus":
case "ProjectStatus ASC":
projects.Sort(ProjectComparer.CompareByProjectStatus);
break;

case "ProjectStatus DESC":
projects.Sort(ProjectComparer.CompareByProjectStatusDesc);
break;
}
}

ProjectComparer Class:

public class ProjectComparer
{
//COMPARE BY NAME

private static IComparer<project> _compareByName = new _sortName(false);
public static IComparer<project> CompareByName { get { return _compareByName; } }

private static IComparer<project> _compareByNameDesc = new _sortName(true);
public static IComparer<project> CompareByNameDesc { get { return _compareByNameDesc; } }

private class _sortName : IComparer<project>
{
bool _reverse;
public _sortName(bool reverse)
{
this._reverse = reverse;
}

public int Compare(Project x, Project y)
{
if (_reverse) return y.ProjectName.CompareTo(x.ProjectName);
else return x.ProjectName.CompareTo(y.ProjectName);
}
}


//COMPARE BY SECTOR

private static IComparer<project> _compareBySector = new _sortSector(false);
public static IComparer<project> CompareBySector { get { return _compareBySector; } }

private static IComparer<project> _compareBySectorDesc = new _sortSector(true);
public static IComparer<project> CompareBySectorDesc { get { return _compareBySectorDesc; } }

private class _sortSector : IComparer<project>
{
bool _reverse;
public _sortSector(bool reverse)
{
this._reverse = reverse;
}

public int Compare(Project x, Project y)
{
if (_reverse) return y.Sector.CompareTo(x.Sector);
else return x.Sector.CompareTo(y.Sector);
}
}


//COMPARE BY Project Status

private static IComparer<project> _compareByProjectStatus = new _sortProjectStatus(false);
public static IComparer<project> CompareByProjectStatus { get { return _compareByProjectStatus; } }

private static IComparer<project> _compareByProjectStatusDesc = new _sortProjectStatus(true);
public static IComparer<project> CompareByProjectStatusDesc { get { return _compareByProjectStatusDesc; } }

private class _sortProjectStatus : IComparer<project>
{
bool _reverse;
public _sortProjectStatus(bool reverse)
{
this._reverse = reverse;
}

public int Compare(Project x, Project y)
{
if (_reverse) return y.ProjectStatus.CompareTo(x.ProjectStatus);
else return x.ProjectStatus.CompareTo(y.ProjectStatus);
}
}

}




And that will give you paging and sorting on your GridView bound to a collection of custom objects. If i have missed any thing or it doesn't make any sense, plese just drop me a comment.

Tuesday 11 November 2008

SQL Server Collation

This error sucks the first time you see it because you may have no idea what it means:

Cannot resolve the collation conflict between "SQL_Latin1_General_CP1_CI_AS" and "Latin1_General_CI_AS" in the equal to operation


Well you can do a search to find the solution but basically if your doing a join between two tables from two seperate databases then this might happen. One has the wrong collation. You can Check like this:


use DB1
print 'My database [' + db_name() + '] collation is: ' + cast( DATABASEPROPERTYEX ( db_name(), N'Collation' ) as varchar(128) )

use DB2
print 'My database [' + db_name() + '] collation is: ' + cast( DATABASEPROPERTYEX ( db_name(), N'Collation' ) as varchar(128) )


If they are different then on your join just add this to the end of the code to convert the collation.

JOIN
Table T ON T.ID = P.ID COLLATE Latin1_General_CI_AS

Thursday 15 May 2008

Programmatically Creating GridView with Template Columns ASP.Net C#.Net

So making a grid view is easy, the designer in Visual Studio is really easy to use to set up columns and bind to a data source. However that's only useful if you know what columns you want and if you know exactly where and when you want to display this data.

What if some of these details are built up dynamically through code while your site is running. I had a situation where I wanted to build up multiple grid views pro grammatically as a result of a user interaction, and I didn't just want normal columns of text data, my grid view required template columns. So how do you create grid view template columns through your server side code?


// C#.Net code to Create Grid View //
GridView newGrid = new GridView();

TemplateField template = new TemplateField();
template.ItemTemplate = new GridViewTemplate(ListItemType.Item, columnName);

newGrid.Columns.Add(template);

newGrid.DataSource = 'Your Data Source Object';
newGrid.DataBind();


The above code will create a Grid View control, this can already exist on your page if you want or as I have done you can create it in code. It maybe best to call this code from the Page_Load method, but you can experiment with that.

Then we will create a Template column and add it to the Grid View, you can create as many of these as you require columns. The code will then bind a Data Source to your Grid View, how the values of that Data Source are displayed is handled in the code below.


Below is the Class code for a GridViewTemplate.



public class GridViewTemplate : System.Web.UI.Page, ITemplate
{
ListItemType _templateType;
string _columnName;


public GridViewTemplate(ListItemType type, string columnName)
{
_templateType = type;
_groupName = columnName;
}


public void InstantiateIn(System.Web.UI.Control container)
{

switch (_templateType)
{

case ListItemType.Header:

break;

case ListItemType.Item:

Literal lc = new Literal();

lc.DataBinding += new EventHandler(this.lc_DataBinding);

container.Controls.Add(lc);

break;

case ListItemType.EditItem:

break;

case ListItemType.Footer:

break;

}
}


private void lc_DataBinding(Object sender, EventArgs e)
{

Literal lc = (Literal)sender;

GridViewRow row = (GridViewRow)lc.NamingContainer;

string propertyValue =
DataBinder.Eval(row.DataItem, "PropertyName").ToString();

lc.Text = propertyValue;

}
}




The GridViewTemplate will set up the basics of your template column. You can set the Header, Item, Footer etc.. and add controls to them just as you could add controls through the designer.

You can then set up Data Binding to these controls, in the Data Binding method you will then pass in the name of the property from your Data Source you want to display the value for in that control, eg. "PropertyName".

Hope this is a useful basic reference for this, hopefully from this you can easily figure out even more complex things you can do with the Grid View.

Wednesday 30 April 2008

A nice ticking clock for your asp.net webpage

I looked around for ages to get a ticking clock on my webpage and couldn't find one that would work in both IE and Firefox. Lots of javascripts sites and lots of not great scripts for a ticking clock.

However I found this site and implemented this solution really quickly and easily.

Dynamic Drive Ticking Clock

Great, have fun.

IE6, CSS Debugging Issues

Since today was spent debugging a css issue in IE6 I would like to post some solutions and development tools that are useful for this sort of thing.

Firstly the main issue that I seems to have was that images inside a table cell left a white space gap of about 3 pixels between bottom of the image and the bottom of the table cell.

The problem was that the vertical-align of the image in IE6 was defaulting to baseline, which apparently means its aligned vertically to the baseline of the text, meaning 3 pixel gap is left to accomodate the trailing tails og letters such as lower case g and y.

To fix this you must vertical-align the image using vertical-align: bottom;

While trying to debug this issue I found two very useful tools. In Firefox you can download the addon, FireBug, that will let you debug a webpage. There are also tools identical to this for IE6 and IE7 which are more handy because in my experience its IE that has more trouble rendering a web page correctly.

IE Developer ToolBar

IE DebugBar

Monday 3 March 2008

using .Net ToString() to format currency values

A nice little bit of code to help display decimal values as currency and using the ever so helpful ToString() method. All you do is add in some format info as show below to tell it to format the string as a currency.


decimal myMoney = 142.00;
string formattedString = myMoney.ToString("c0");


It will use the CurrentInfo property of System.Globalization.NumberFormatInfo the localization information to work out what currency to use. So for me the formatted string would be £142. The zero in the format string sets the number of decimal places to use.

To convert this value back to a decimal you can use this code below.


decimal myMoney = Decimal.Parse(formattedString , NumberStyles.Currency);


Just to be safe wrap this in a try catch block to catch System.FormatException errors which means that someone entered a value using the wrong currency type. SO if the CurrentInfo says the local currency should be US dollars $142 and someone uses pounds £142 instead it will complain.

Right cool, think that's just about that.

MPH.

Friday 29 February 2008

GridView Select Rows Code 2.0

Simple link to a good post about how to make a Grid View row selectable without having a button at the end of each row, you can just click on the row to fire the onSelectedIndexChanging Event.

http://www.geekzilla.co.uk/

Linked Post written by : Paul Marshall

Here is a minor imporvement I made to the code written by Paul Marshall that just makes it easier to control the styling applied onMouseOver of the grid. I used it to change it so the whol row is highlighted rather than just underlining the text.

In GridView_RowDataBound I changed this bit of code to reference the my css file.

e.Row.Attributes["onmouseover"] ="this.style.cursor='hand';this.className='gridRollOver';";
e.Row.Attributes["onmouseout"] = "this.className='';";



A Belated Welcome to My New Blog

I created this new blog the other day when I realised I was starting to add lots of boring geeky programming stuff to my personal blog. The main problem with that is that my Wordpress blog isn't very customizable, the code quotes are crap and for some reason at the moment the edit tools are a bit broken.

So I decided to create a new blog just for all the boring coding tips and helpful hints I want to write about, mostly just as a place for me to collate stuff so I don't have to remember it in my head.

I was going to try a few different blog sites but Blogger appears to be really good and I quite like how customizable it is with so many templates and being able to edit the HTML directly for the template and CSS is much nicer than Wordpress so I'm just going to use this.

A link to my regular blog is in the side bar so I will still keep that going to write blog posts about general more interesting stuff than computer programming and save this bog just for the boring stuff.

MPH.

Wednesday 27 February 2008

Find Good Free Blog Templates

I just created this blog today and have been playing around with the formatting of it. I want to get a clear, easy to read and well organized template. Below is a link to the best template site you will find with hundreds of Free Templates for many different blogs.

http://www.eblogtemplates.com/

Also some nice CSS code to add a shaded boxes around areas for code or quotes:


blockquote
{
margin:.75em 0;
border:1px solid #596;
border-width:1px 1px;
padding:5px 15px;
display: block;
background-color: #dedede;
}

code
{
font-family: Courier;
margin:.75em 0;
border:1px solid #596;
border-width:1px 1px;
padding:5px 15px;
display: block;
background-color: #dedede;
white-space: pre;
}

SharePoint stsadm.exe and Powershell

Trying to run the SharePoint tool stsadm.exe in PowerSehll I get the following error:

The term 'stsadm.exe' is not recognized as a cmdlet, function, operable program, or script file


To get stsadm.exe to work in PowerShell you have to edit the 'profile.ps1' file.
Look in C:\WINDOWS\system32\windowspowershell\v1.0\ and if it doesn't exist just create a new file and add the following code:

Set-Alias -Name stsadm -Value $env:CommonProgramFiles”\Microsoft Shared\Web Server Extensions\12\BIN\STSADM.EXE”

Now you can use stsadm in Powershell without it buggering up.