Tuesday, 22 December 2009

Changing the last item in a repeater

You can't change the last item of a repeater in its itemDataBound event, as there is no way of knowing you are on the last item. The concept you need to follow is that you poke it later on during the preRender event of either the repeater or the page.

I needed to do this, but I had an extra complication - I was working with a nested repeater in a page that had a master page. The fact that this was a child page made finding my control a bit of a pain using Page preRender, so I thought it would be sensible to use the preRender event of the parent repeater. To my surprise while debugging I discovered that my parent repeater's preRender event was firing before the child or nested repeaters had even started binding. Weird.

So, in the end, I used the child repeater's preRender event. In this I look for the parent repeater, and loop through its repeater items looking for my nested repeater (which I'm about to render). Then I find my control and make the change I want.

Simples!

protected void ChildRepeater_PreRender(object sender, System.EventArgs e)
{

   Repeater ParentRepeaterRpt = (Repeater)ContainerofParent.FindControl("ParentRepeater");

    foreach (RepeaterItem item in ParentRepeaterRpt.Items)
    {
        Repeater ChildRepeaterRpt = (Repeater)item.FindControl("ChildRepeater");
        if (ChildRepeaterRpt.Items.Count > 0)
        {
            RepeaterItem rptItem = ChildRepeaterRpt.Items[ChildRepeaterRpt.Items.Count - 1];

            Literal MyLit = (Literal)rptItem.FindControl("MyLitName");
            MyLit.Text = "whatever";
        }
    }



}

Thursday, 17 December 2009

Directory.Move...but no Directory.Copy?

If you want to move a directory and its contents in .Net then you can use this:
Directory.Move(sourceDir,destDir)
For some reason unbeknownst to me, there is no Directory.Copy. So, instead of re-inventing the wheel I googled for some code that's already written. I found this, and it seems to work a treat. It was posted by a chap called Mike on the vbCity forums, so all gratitude should go to him:

' Usage:
    ' Copy Recursive with Overwrite if exists.
    ' RecursiveDirectoryCopy("C:\Data", "D:\Data", True, True)
    ' Copy Recursive without Overwriting.
    ' RecursiveDirectoryCopy("C:\Data", "D:\Data", True, False)
    ' Copy this directory Only. Overwrite if exists.
    ' RecursiveDirectoryCopy("C:\Data", "D:\Data", False, True)
    ' Copy this directory only without overwriting.
    ' RecursiveDirectoryCopy("C:\Data", "D:\Data", False, False)

    ' Recursively copy all files and subdirectories from the specified source to the specified 
    ' destination.
    Private Sub RecursiveDirectoryCopy(ByVal sourceDir As String, ByVal destDir As String, ByVal fRecursive As Boolean, ByVal overWrite As Boolean)
        Dim sDir As String
        Dim dDirInfo As IO.DirectoryInfo
        Dim sDirInfo As IO.DirectoryInfo
        Dim sFile As String
        Dim sFileInfo As IO.FileInfo
        Dim dFileInfo As IO.FileInfo
        ' Add trailing separators to the supplied paths if they don't exist.
        If Not sourceDir.EndsWith(System.IO.Path.DirectorySeparatorChar.ToString()) Then
            sourceDir &= System.IO.Path.DirectorySeparatorChar
        End If
        If Not destDir.EndsWith(System.IO.Path.DirectorySeparatorChar.ToString()) Then
            destDir &= System.IO.Path.DirectorySeparatorChar
        End If
        'If destination directory does not exist, create it.
        dDirInfo = New System.IO.DirectoryInfo(destDir)
        If dDirInfo.Exists = False Then dDirInfo.Create()
        dDirInfo = Nothing
        ' Recursive switch to continue drilling down into directory structure.
        If fRecursive Then
            ' Get a list of directories from the current parent.
            For Each sDir In System.IO.Directory.GetDirectories(sourceDir)
                sDirInfo = New System.IO.DirectoryInfo(sDir)
                dDirInfo = New System.IO.DirectoryInfo(destDir & sDirInfo.Name)
                ' Create the directory if it does not exist.
                If dDirInfo.Exists = False Then dDirInfo.Create()
                ' Since we are in recursive mode, copy the children also
                RecursiveDirectoryCopy(sDirInfo.FullName, dDirInfo.FullName, fRecursive, overWrite)
                sDirInfo = Nothing
                dDirInfo = Nothing
            Next
        End If
        ' Get the files from the current parent.
        For Each sFile In System.IO.Directory.GetFiles(sourceDir)
            sFileInfo = New System.IO.FileInfo(sFile)
            dFileInfo = New System.IO.FileInfo(Replace(sFile, sourceDir, destDir))
            'If File does not exist. Copy.
            If dFileInfo.Exists = False Then
                sFileInfo.CopyTo(dFileInfo.FullName, overWrite)
            Else
                'If file exists and is the same length (size). Skip.
                'If file exists and is of different Length (size) and overwrite = True. Copy
                If sFileInfo.Length <> dFileInfo.Length AndAlso overWrite Then
                    sFileInfo.CopyTo(dFileInfo.FullName, overWrite)
                    'If file exists and is of different Length (size) and overwrite = False. Skip
                ElseIf sFileInfo.Length <> dFileInfo.Length AndAlso Not overWrite Then
                    'Debug.WriteLine(sFileInfo.FullName & " Not copied.")
                End If
            End If
            sFileInfo = Nothing
            dFileInfo = Nothing
        Next
    End Sub

Wednesday, 16 December 2009

Check if a record exists in a stored procedure

I have users assigning selected items from a list to a group that they have created. I don't want to bother the user with detailed information about whether any particular item they selected was already in the group, I just want to add it if it's not there, and do nothing if it's there already.

The neatest way to do this was to drop the logic into the stored procedure like below. The 'IF NOT EXISTS' condition means I can insert only when there is no record matching the SELECT query.

IF NOT EXISTS(SELECT * from [table] where something = @mySomething)
 
BEGIN
 
/**** do insert ****/
   
END

GO

Wednesday, 9 December 2009

Validating input for an email address

Use this pretty, simple, and pretty simple regular expression validator:
<asp:RegularExpressionValidator ID="valEmailAddress" ControlToValidate="EmailTextBox" ValidationExpression=".*@.*\..*" ErrorMessage="Email address is invalid" EnableClientScript="true" runat="server" ValidationGroup="Insert">*</asp:RegularExpressionValidator>

Or, if you want to do it in code rather than use a control, try this:

public static bool isEmail(string inputEmail)
{
    if( inputEmail == null || inputEmail.Length == 0 )
    {
        throw new ArgumentNullException( "inputEmail" );
    }

    const string expression = @"^([a-zA-Z0-9_\-\.]+)@((\[[0-9]{1,3}" +
                              @"\.[0-9]{1,3}\.[0-9]{1,3}\.)|(([a-zA-Z0-9\-]+\" +
                              @".)+))([a-zA-Z]{2,4}|[0-9]{1,3})(\]?)$";

    Regex regex = new Regex(expression);
    return regex.IsMatch(inputEmail);
}