Monday, 30 August 2010

Rounded Corners

I was asked to put some content inside a box shaped element which had rounded corners. Not square corners, it had to have rounded corners.

Unfortunately, since HTML is so 'boxy' this behaviour does not come naturally. It's not just a setting on your table or div element, and there's no particularly easy way to achieve this effect.

Until CSS3 and its border-radius property comes into play in all of the next generation browsers, creating a screen element with rounded corners needs to be done another way. More info on border-radius and browser support is available on CSS3.info.

I found that the effect can be achieved using images and divs. There's a nice article on the Webcredible site which gives you a step by step tutorial on exactly how to do it.

N.B: Being honest, you can actually use browser specific properties such as '-moz-border-radius' to display rounded corners, but I couldn't find the equivalent for IE which is no good since a large chunk of users will be using IE.

Monday, 23 August 2010

ASP.NET Error: "The DataSource does not support sorting"

In one of our projects we had a GridView which was by default bound to an ObjectDataSource to allow us to Sort/Page and to apply custom filtering. But we also needed to be able to search the data which the GridView is bound to, which we achieved in code and then databound the GridView to the resulting DataTable.

Here's a code snippet:

Before


grdvSummaryGrid.DataSourceID = String.Empty

Dim _clientBLL As New ClientBLL()
grdvSummaryGrid.DataSource = _clientBLL .Search(e.SearchText)
grdvSummaryGrid.DataBind()

Using this code, a problem arose where if you sorted the GridView and then carried out a search, an error resulted when the code attempted to DataBind it to the resulting table:

"System.NotSupportedException: The data source does not support sorting"

I tried a few things and considered creating an ObjectDataSource in code with the search results and then binding the GridView to that, but the answer turned out to be simple.

Before setting the DataSourceID of the GridView to an empty string to allow you to set its DataSource to the resulting DataTable (you can't set both properties), you clear the sort expression.

Like this:

After (Notice the new first line)

grdvSummaryGrid.Sort("", SortDirection.Ascending)
grdvSummaryGrid.DataSourceID = String.Empty

Dim _clientBLL As New ClientBLL()
grdvSummaryGrid.DataSource = _clientBLL .Search(e.SearchText)
grdvSummaryGrid.DataBind()

That did the job. Lots of people seem to have had this problem too, so hopefully this answer will be useful.

Saturday, 21 August 2010

ASP.NET: Sorting a DataTable

I was pulling out a DataTable from my database and applying some sorting to it in the Stored Procedure, which of course worked as expected.

But I needed the user to be able to pull a row out from a GridView, edit its fields and then reinsert it to the GridView, all the time preserving the sort order.

As usual, I went round the houses looking at all the usual crappy solutions that others who also forget to read the documentation come up with, until I found a simple solution that worked for me:


dataTable.DefaultView.Sort = "date_of_birth asc"

Simples!

Here's the MSDN documentation.

Wednesday, 18 August 2010

CSS: RadioButtonList Layout

For the most part, I love web development, but there are some things that I absolutely detest about it.

For example, something that should be straightforward such as getting horizontal radio buttons to appear in a neat and tidy way can be tough. Obviously your radiobutton labels will have different values and will therefore cause the list to have different widths - this can be messy if you have a few rows of radiobuttons.

In addition, the radiobutton label will by default wrap down to underneath the radiobutton itself which is hideous. That needs to be fixed.

You could try laying the controls out with a table or a series of fixed size divs, but you shouldn't need to. And using tables could be nasty.

CSS to the rescue! Create a class to use for your RadioButton controls and assign it.


.radioButtons {
border:none;
border-collapse:separate ;
}
.radioButtons input {
float:left;
}
.radioButtons label {
margin-left: 25px;
display: block;
}
.radioButtons td{
min-width:175px;
}

Then just lay out your control like this (an ASP RadioButtonList control is used here but you could use HTML literals too I guess):


<asp:RadioButtonList ID="rblYesNoMaybe" runat="server" RepeatDirection="Horizontal"
CssClass="radioButtons" >
<asp:ListItem>Yes</asp:ListItem>
<asp:ListItem>No</asp:ListItem>
<asp:ListItem>Maybe</asp:ListItem>
</asp:RadioButtonList>

Using this, you should find that your RadioButtons look better and that your label text doesn't wrap underneath the radiobutton input. You'll probably need to set the min-width property of the td to an arbitrary value to suit your page or site.

Saturday, 26 June 2010

ASP.NET: Inserting NULL Values Into SQL Server Database

I literally almost destroyed a laptop today when trying to get around the fact that empty dates in my application were being stored in SQL Server as the completely useless '1900-01-01 00:00:00.000'.

Note that SQL Server is not the issue here, it WILL insert a NULL value if it's told to. If you're seeing this 1900 date then it's coming from your application.

I'm using an XSD within my Visual Studio project, and therefore it auto-generates methods for each of the methods I define on my TableAdapters. I needed to get null dates into these methods and then into the database without the application passing the 1900 date to SQL Server.

I tried loads of different methods of checking the values, by trying to pass Nothing, SqlDateTime.Null or System.DBNull.Value where the date was empty, but to no avail, I either got cast errors or the database did the insert but continued to think we were at the dawn of the 20th century.

Finally, I figured it out, and really there are two ways of achieving this. One is to use a Typed DataSet, which allows you to use the autogenerated 'SetMyColumnNameNull()' method.

But I'm not using a typed DataSet for my database insert methods, rather I call the stored procedure methods in my BLL and pass in the values rather than a row object.

So anyway, the answer was this:

When passing your date to your method which calls your stored procedure, pass your dates as strings. Then in your code you can check them like this:



(System.ComponentModel.DataObjectMethodType.Insert, True)> _
Public Function InsertOrder(ByVal date_in_question as String)

Dim dateInQuestion As Global.System.Nullable(Of Date)

' Bust any empty dates
If date_in_question <> "" Then
dateInQuestion = CDate(date_in_question)
End If

' Do the Insert
Dim orderId As Integer = Adapter.db_Insert_Update_Order(dateInQuestion)

Return orderId

Now when the date is passed to the stored procedure's method, if no date is set then an empty date is passed and the database inserts a NULL value.

You might want a more robust way of parsing your dates etc etc, but this worked for me.

Hope I've provided enough detail.

Monday, 21 June 2010

ASP.NET FileUpload Control Inside an UpdatePanel

I put a FileUpload control inside an UpdatePanel and ran into some problems, as many others did.

Since the UpdatePanel does not do a full postback by nature (and therefore only partially refreshes the screen), the FileUpload control does not work straight away.

To get it to work you need to add a PostBackTrigger which points at your Upload button. Here's a Microsoft example on that very topic.

Using a PostBackTrigger will cause a full postback to fire when a file is uploaded and will cause your control to work... in most cases.

However I found an odd issue where the file upload did not work the first time (the FileUpload control's HasFile property was always False) but it would upload successfully the second time.

I had to root around in a few places and eventually found the answer on StackOverflow's forums.

Turns out the answer is to define this in your Page_Load event:


Protected Sub Page_Load(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.Load

Page.Form.Enctype = "multipart/form-data"

End Sub

After I added this, the FileUpload control started to work every time.

Monday, 14 June 2010

Syntax Highlighter Success

Finally, I managed to get SyntaxHighlighter working.

I had tried a few things previously, but it seems that some of the tutorials I had seen were based on older versions. The joy arrived when I found this post.

Now I can post code snippets in a way which is actually readable!


SELECT
COUNT(dbid) as TotalConnections
FROM
sys.sysprocesses
WHERE
dbid > 0

Hurrah!

I'm still using Stanley Shilov's utility to escape my HTML so that I can post using these simple tags:


<pre class="brush: html">
</pre>

SQL Server 2005: Determining the Total Number of Open/Active Connections

Sometimes applications can become unresponsive or generate SQL Server timeout exceptions (System.Data.SQLClient.SQLException: Timeout Expired) and sometimes you just need to find out how much traffic is hitting your database.

You can find out a few things by using these commands:

Total Number of Connections by Database


SELECT
DB_NAME(dbid) as DBName,
COUNT(dbid) as NumberOfConnections,
loginame as LoginName
FROM
sys.sysprocesses
WHERE
dbid > 0
GROUP BY
dbid, loginame

Total Connections

SELECT
COUNT(dbid) as TotalConnections
FROM
sys.sysprocesses
WHERE
dbid > 0

Detailed description of all running processes

sp_who2 'Active'

NB: You probably need to be logged in with SA privileges to run these commands.

Wednesday, 9 June 2010

ASP.NET: ListView Control and Nested ListViews

I have grown to love (in a purely sensible way) the ASP.NET ListView control. It's very flexible and gives you a lot of control over how you display your data on your site.

I needed to display on a summary screen not only the orders belonging to a specific customer, but the products belonging to each order. So I built a ListView to display the orders, then nested another ListView inside it which displays the products belonging to that order.

After some rooting around on the net, I found this excellent tutorial for nesting ListViews that I'll definitely be revisiting in future.

Monday, 7 June 2010

ASP.NET: Select DISTINCT from DataTable

I needed to filter a GridView using a bunch of DropDownLists which were placed in its header. As you filter the GridView, the drop down lists had to update according to the filtered data in the GridView (i.e. they should not display filter options for data that's not visible in the table).

In order for this to work, I had to get a distinct list of values for each column with which to populate the drop down lists. This required getting a distinct list of values from a DataTable, and this behaviour does not come naturally to a DataTable since it's a representation of a SQL Database table rather than an actual database table which you can run SQL against.

I found a nice tutorial on this, which I'm linking to here for future reference, in both VB.NET and C#.NET versions.

I had to pass the DataSource my GridView was pointing at into a method which bound the DropDownLists using the function demonstrated in Microsoft's tutorials above.

Implemented, hooked into my GridView and Bob's My Uncle.

Very nice!