Archives
-
VB.NET : where to from here?
Thanks to Tom for taking notes :)
-
Issues with a lambda expression
In javascript you can use a function to as an argument to the string.replace function when matching against a regex pattern - this is often referred to as a lambda expression. For example, in the following piece of code, the function is invoked for each match. The result is that the letters in the word "foo" are alerted in sequence:
-
Rss + Northwind disconnected = Developer Friendlies
I've noticed a couple of developer-friendlies floating around recently, namely:
-
Windows Authentication with Role based authorization
I've done a fair bit with ASP.NET security using the FormsAuthentication provider but not much at all with Windows authentication. I'm currently building an app. “out-of-hours” that needed to use integrated Windows authentication and also use Role based authorization based on the users Windows Group membership. Here is a little piece of code that I put together to hook the Windows groups into the roles of the IPrincipal in the application:
-
Loading Templates at runtime
I've just uploaded my latest article on ASPAlliance:
-
Begging is begg(in)ing.
To Dave...
-
Application.DoStuff
I nice little post by Eric Gunnerson that talked how to add an odd-shaped splash screen to an application. The most interesting thing that came out of this post for me was that he mentioned having to call Application.DoEvents to allow Windows to process the necessary messages to get the splash form to render properly. Being a web-guy Application.DoEvents is something that I've never really come to terms with. If you were to go under the hood of some of my winforms apps you would undoubtedly uncover a shot-gun approach to calling this method - i.e.: sprayed at random.
-
Javascript Links
Today Marcie enquired about favourite javascript links, here's my list:
-
Regex Reminders [1] - Replacement Operations
A common application for regular expressions is to find and replace strings within a body of text. These operations range from something as simple as finding some text and removing it to locating and re-writing Hmtl tags. Let's take a quick look at the signatures of the .NET Regular Expression Replace overloads.
-
Regex Reminders #0 - Commenting Regular Expressions
Free spacing and comment mode
.NET Regular Expressions allow you to embed comments and whitespace within pattern strings making them clearer to
read (because of the whitespace), and easier to maintain (due to the modularity). To use this feature you must turn on the RegexOptions.IgnorePatternWhitespace flag. This can be achieved
either by using the RegexOptions enumerated datatype or, via the (?x) mode modifier. Therefore the following
two examples are functionally identical: Regex re = new Regex( @" # This pattern matches Foo (?i) # turn on insensitivity # The Foo bit \b(Foo)\b " , RegexOptions.IgnorePatternWhitespace ) ; Regex re = new Regex( @"(?x) # This pattern matches Foo (?i) # turn on insensitivity # The Foo bit \b(Foo)\b " ) ; Using IgnorePatternWhitespace option, comments can be embedded in one of two ways. Firstly, a raw '#'
character can be used to mark the beginning of a comment and the comment runs up to the first NEWLINE
(\n) character that is encountered. This can be easily achieved in C# with verbatim strings @"..."
or in VB by appending newline characters within the string using Chr(10), vbCrLf or Environment.NewLine.
Comments can also be declared using the (?#...) syntax. The following 3 snippets demonstrate examples of each of these methods... C# Verbatim Strings. using System; using System.Collections; using System.Text.RegularExpressions ; namespace Regex Snippets.Tests { public class CommentedCSharp { public static void Main() { Regex re = new Regex( @" # This pattern matches Foo (?i) # turn on insensitivity # The Foo bit \b(Foo)\b " , RegexOptions.IgnorePatternWhitespace ) ; for ( Match m = re.Match( "foo bar Foo" ) ; m.Success ; m = m.NextMatch() ) Console.WriteLine( m.Value + Environment.NewLine ) ; Console.ReadLine(); } } } VB.NET using (?#...) syntax. Option Strict On Imports System.Text.RegularExpressions Namespace Regex Snippets.Tests Module CommentedVBOne Public Sub Main() ' Demonstrates a VB Whitespace pattern using the '" (?#...) " & _ ' syntax Dim re As New Regex( _ " (?# This pattern matches Foo ) " & _ " (?i) (?# turn on insensitivity ) " & _ " (?# The Foo bit ) " & _ " \b(Foo)\b " _ , RegexOptions.IgnorePatternWhitespace) Dim m As Match = re.Match("foo bar foo") Dim s As String = "" While m.Success s &= (m.Value & Environment.NewLine) m = m.NextMatch() End While MessageBox.Show(s) End Sub End Module End Namespace VB.NET using appended newlines. Option Strict On Imports System.Text.RegularExpressions Namespace Regex Snippets.Tests Module CommentedVBTwo Public Sub Main() ' Demonstrates a VB Whitespace pattern using the '" (?#...) " & _ ' syntax Dim re As New Regex( _ " # This pattern matches Foo " & vbCrLf & _ " (?i) # turn on insensitivity " & vbCrLf & _ " # The Foo bit " & vbCrLf & _ " \b(Foo)\b " _ , RegexOptions.IgnorePatternWhitespace) Dim m As Match = re.Match("foo bar foo") Dim s As String = "" While m.Success s &= (m.Value & Environment.NewLine) m = m.NextMatch() End While MessageBox.Show(s) End Sub End Module End Namespace -
Regex Reminders - A brief explanation
Over the next couple weeks I'm going to post a series of regular expression examinations; each one will be a code intensive focus on a certain operations such as "Replace" or "Working with Matches and Groups". The goal of the Regex Reminders is to end up with a lot of code for working with regex's that people can just use to "grab and go". The series will also spend time looking at common regex techniques such as alternation and grouping techniques.
-
Timing javascript
A little snippet that demonstrates how I perform speed tests against js code:
-
Redefining Boundaries - \b and \B
\b and \B are useful metacharacters; they provide a simple syntax to easily find items that exist around word boundaries (or, in the case of \B, non-word boundaries). For example, to find the word "per" you can wrap the actual text inside \b's to ensure that the phrase is not inadvertantly matched when found inside of "person" or "Supercalif", i.e.:
-
The amazing Javascript
... never ceases to amaze me!
-
Timer demo online
Just posted a working demo of the Timer control:
-
Timer source code available
As per my previous post, the source for MarkItUp.WebControls.Timer is now available:
-
MarkItUp.WebControls.Timer
I've finally finished my first server control that is targetted as a public release. The control is a Timer control that generates optional client-side events and performs a server postback after a specified duration.
-
RegexLib.com RSS feeds
As mentioned by Roy I've altered the main RegexLib.com Rss feed so that the feed title displays more useful information. I've also created a new feed to display the most recent comments that have been entered by users against patterns.
-
IFormatProvider whackiness
While visiting the Holy Place today I stopped in to visit some random links in the .NET Framework section (as you do). One of my mouse-clicks happened to land on the section which talks about FormatProvider's and illustrated the results that various format strings have on the output of ToString. Here's a demo that I think is particularly cool:
-
\G - match at the end of the previous match.
Over the next few days I'd like to spend a bit of time looking at using \G in the .NET "flavour" of regular expressions. I'd love to hear from anyone that has *had* to use \G in a real-world application (.NET only).
-
DaysOfTheWeek regex
Michael Ash has done some neat work on the DaysOfTheWeek regex:
-
A better design time experience
I'm sure that Andy Smith has probably trademarked the term "A better design time experience" but, anyways here goes...
-
KPI ServerControl Source
Option Strict On Imports System Imports System.ComponentModel Imports System.Configuration Imports System.Data Imports System.Drawing Imports System.Web.UI Imports System.Web.UI.WebControls '********************************************************************* ' ' KPIs Class ' ' WebControl that displays a listing of KPIs for a given Category/Month. ' '********************************************************************* < _ Description("WebControl that displays a listing of KPIs for a given Category/Month."), _ DefaultProperty("DataSource"), _ Designer(GetType(KPIsDesigner)), _ ToolboxData("<{0}:KPIs runat=server></{0}:KPIs>") _ > _ Public Class KPIs Inherits Web.UI.WebControls.Table Implements INamingContainer Private mstrCategoryName As String = String.Empty Private mstrNavigateUrl As String = String.Empty Private mstrBaseImagePath As String = String.Empty Private mdtmSelectedMonth As DateTime = DateTime.MinValue Private mDatasource As DataTable '********************************************************************* ' ' BaseImagePath Property ' ' The directory to look in to find the images. ' '********************************************************************* < _ Browsable(True), _ Description("The directory to look in to find the images."), _ Category("Data") _ > _ Public Property BaseImagePath() As String Get Return Me.mstrBaseImagePath End Get Set(ByVal Value As String) Me.mstrBaseImagePath = Value End Set End Property '********************************************************************* ' ' CategoryName Property ' ' The CategoryName to filterBy. ' '********************************************************************* < _ Browsable(True), _ Description("The name of the current category being displayed."), _ Category("Data") _ > _ Public Property CategoryName() As String Get Return Me.mstrCategoryName End Get Set(ByVal Value As String) Me.mstrCategoryName = Value End Set End Property < _ Browsable(True), _ Description("The foreground color for alternating items in the table."), _ Category("Appearance") _ > _ Public Property AlternatingForeColor() As Color Get If ViewState("AlternatingForeColor") Is Nothing Then Return Me.ForeColor Else Return CType(ViewState("AlternatingForeColor"), Color) End If End Get Set(ByVal Value As Color) ViewState("AlternatingForeColor") = Value End Set End Property < _ Browsable(True), _ Description("The background color for alternating items in the table."), _ Category("Appearance") _ > _ Public Property AlternatingBackColor() As Color Get If ViewState("AlternatingBackColor") Is Nothing Then Return Me.ForeColor Else Return CType(ViewState("AlternatingBackColor"), Color) End If End Get Set(ByVal Value As Color) ViewState("AlternatingBackColor") = Value End Set End Property < _ Browsable(True), _ Description("The DataTable to use as a datasource."), _ Category("Data") _ > _ Public Property DataSource() As DataTable Get Return Me.mDatasource End Get Set(ByVal Value As DataTable) Me.mDatasource = Value End Set End Property '********************************************************************* ' ' NavigateUrl Property ' ' The Url to navigate to to display the details for a given KPI ' '********************************************************************* < _ Browsable(True), _ Description("The Url to navigate to to display the details for a given KPI. Uses a {0} placeholder to insert the Id of the KPI."), _ Category("Data") _ > _ Public Property NavigateUrl() As String Get Return Me.mstrNavigateUrl End Get Set(ByVal Value As String) Me.mstrNavigateUrl = Value End Set End Property '********************************************************************* ' ' Controls Property ' ' Make sure that when you access a child control, the ' CreateChildControls method has been called. ' '********************************************************************* Public Overrides ReadOnly Property Controls() As ControlCollection Get EnsureChildControls() Return MyBase.Controls End Get End Property '********************************************************************* ' ' SelectedMonth Property ' ' The SelectedMonth to filterBy. ' '********************************************************************* < _ Browsable(True), _ Description("The resultset is filtered by the Month of the DateTime that is passed in."), _ Category("Data") _ > _ Public Property SelectedMonth() As DateTime Get Return Me.mdtmSelectedMonth End Get Set(ByVal Value As DateTime) Me.mdtmSelectedMonth = Value End Set End Property Protected Overrides Sub CreateChildControls() Controls.Clear() If mDatasource Is Nothing Then mDatasource = GetData() End If If Not mDatasource Is Nothing Then Me.Rows.Add(BuildHeaderRow()) For Each row As DataRow In mDatasource.Rows Dim KPIId As Integer = Convert.ToInt32(row.Item("kpiId")) Dim KPIDescription As String = row.Item("kpiDescription").ToString Dim mtdRaw As Double = Convert.ToDouble(row.Item("mtdRawValue")) Dim ytdRaw As Double = Convert.ToDouble(row.Item("ytdRawValue")) Dim mtdDisplay As Integer = Convert.ToInt32(row.Item("mtdDisplayFlag")) Dim ytdDisplay As Integer = Convert.ToInt32(row.Item("ytdDisplayFlag")) Dim alternating As Boolean = (Me.Rows.Count Mod 2 = 0) Me.Rows.Add(BuildRow(KPIId, KPIDescription, mtdRaw, ytdRaw, mtdDisplay, ytdDisplay, alternating)) Next End If End Sub '********************************************************************* ' ' Render Method ' '********************************************************************* Protected Overrides Sub Render(ByVal tw As HtmlTextWriter) MyBase.Render(tw) End Sub ' Render Private Function BuildRow(ByVal kpiId As Integer, ByVal kpiDescription As String, ByVal mtdRaw As Double, _ ByVal ytdRaw As Double, ByVal mtdDisplay As Integer, ByVal ytdDisplay As Integer, ByVal isAlternatingItem As Boolean) As TableRow Dim cell As TableCell Dim row As New TableRow If isAlternatingItem Then row.ForeColor = Me.AlternatingForeColor row.BackColor = Me.AlternatingBackColor End If Dim link As New HyperLink link.Text = kpiDescription If Not Me.mstrNavigateUrl Is String.Empty Then link.NavigateUrl = String.Format(Me.NavigateUrl, kpiId) End If cell = New TableCell cell.Controls.Add(link) row.Cells.Add(cell) cell = New TableCell cell.Controls.Add(GetImage(mtdDisplay, mtdRaw, "MTD")) row.Cells.Add(cell) cell = New TableCell cell.Controls.Add(GetImage(ytdDisplay, ytdRaw, "YTD")) row.Cells.Add(cell) Return row End Function Private Function BuildHeaderRow() As TableRow Dim cell As TableCell Dim row As New TableRow cell = New TableHeaderCell cell.Text = " " row.Cells.Add(cell) cell = New TableHeaderCell cell.Text = "MTD" row.Cells.Add(cell) cell = New TableHeaderCell cell.Text = "YTD" row.Cells.Add(cell) Return row End Function Private Function GetData() As DataTable Return Nothing End Function '********************************************************************* ' ' GetImage Method ' ' Returns the appropriate image for a particular rating. ' '********************************************************************* Friend Function GetImage(ByVal ratingNumber As Integer, ByVal rawVal As Double, ByVal desc As String) As Web.UI.WebControls.Image Dim img As New Web.UI.WebControls.Image If Me.mstrBaseImagePath <> String.Empty Then If ratingNumber = 1 Then img.ImageUrl = Page.ResolveUrl(String.Format("{0}/Green.gif", Me.mstrBaseImagePath)) ElseIf ratingNumber = 2 Then img.ImageUrl = Page.ResolveUrl(String.Format("{0}/Yellow.gif", Me.mstrBaseImagePath)) ElseIf ratingNumber = 3 Then img.ImageUrl = Page.ResolveUrl(String.Format("{0}/Red.gif", Me.mstrBaseImagePath)) Else img.ImageUrl = Page.ResolveUrl(String.Format("{0}/Spacer.gif", Me.mstrBaseImagePath)) End If End If img.AlternateText = String.Format("{1} : {0}", rawVal, desc) Return img End Function 'GetImage End Class
-
using C# and unlocking some secrets
Recently, I've made a decision that all of the code that I write "out of hours" (which is most of the code that I write these days) will be written in C#; and what I'm finding is that switching languages is a very tricky affair. There's so many little pieces of the language that you have to get used to. Take the using statement - as opposed to the using directive - for example. At first sight it seems interesting, according to the docco. it allows me to use an IDisposable type and the call to dispose will get handled under the covers; GREAT! Or is it? First of all, methinks that, by the very nature of IDisposable, anything that implemented that interface would be worth putting in a try{}catch{} because you are relying on an "external" resource being available! So it appears that a statement such as:
-
Conditional matching
Today, while proving what a prat I am, I added some conditional testing to a pattern which I had written. Conditional matching allows you to perform a test based on if...then[...else] logic. The syntax is (?if then | else ) - with the 'else' part being optional.
-
Oft used code: reading from files and urls
Here's some code that I use very regularly to read from files or urls, especially when writing test code that has to read in large chunks of text:
-
Good VBScript reference
I never really did much VB6 programming - built a couple of insignificant apps but that was about it - and today a friend asked me to package some VBScript routines into an ActiveX Library project. It all went pretty well except for the fact that I couldn't work out which .dll to reference to get the VBScript ESCAPE and UNESCAPE functions in my VB6 code. While looking around Msdn for version numbers etc. I came across this neat little VBScript reference:
-
Using backreferences in a Match
You can reference backreferences within a regular expression to keep the length and complexity of patterns to a minimum. Backreferences can be referenced with the \1..\N or \k'name' notation. To highlight where this is useful consider a simple-minded pattern for matching Dates. Dates can (potentially) be delimited by either a space, a dot, a hyphen or a slash - that is, any of the following might be allowed:
-
Find words NOT IN text
I'm currently writing a series of articles (that will hopefully get published {grin}) titled "Regex Reminders" that will provide dozens of code snippets that demonstrate how to perform common - and some not-so-common - operations using regex.
-
Date Regex - [ Note To Self ]
While scouring through the pile of comments that have been left on RegexLib.com I noticed a pattern which purports to validate Dates in dmy format. I couldn't help but notice that all of the comments which have been left have been highly favourable of this expression.