Thursday, October 15, 2009

Reading data from a closed Stream

Problem:
Sometimes you need to read data from a Stream, either to save it or to process it in other layers, but you really don't want to open or pass along the Stream for too long.

Solution:
At first glance, the GetBuffer() method of the Stream object would seem ideal, since it copies the text to a byte array, allowing you to close the underlying stream without any issues.

However, GetBuffer has some definite issues, the biggest one being that he will pad the resulting byte array with "\0" (nulls), depending on how big the data in your stream is. Which can lead to all kinds of nasty side-effects (in particular when working with XML data).

Never fear, in comes the rescuer, in this case the ToArray() method of the Stream object. This basically does everything GetBuffer does, minus the padding. And likewise, you can simply dispose of the Stream and do whatever you need to do with the data.

How to retrieve an old version of your project in Sourcesafe

Open Command Prompt

Set Sourcesafe Directory

C:\Program Files\Microsoft Visual Studio\VSS\win32>set SSDIR=<unc path to your sourcesafe root>

Execute GET command

ss get $/ -R -Vd5/6/2009;5:16a -I-N -W -GLD:\temp\<your project name>-GTM –GWR

- Project: $/Projects/<your project>: naam van het project die je wilt hebben
- -Vd5/6/2009;5:16a: tijdstip van de bestanden die je wilt terugkrijgen (DD/MM/YYYY formaat, dus 5 juni in dit geval)
- -GLD:\temp\<your project>: lokale folder waar de files in moeten terechtkomen

Friday, October 09, 2009

Quick Linq tip

When you crete a construction such as

if (list.Count > 0)
{
// do stuff
}


its actually much more efficient to use LINQ as such:

if (list.Any())
{
// do stuff
}


Advantage: ANY will stop after the first hit, while COUNT will traverse the entire enumerator. This can be significant for larger lists.

Validation for ComponentArt datepicker

External DatePicker Controls can be useful, and the ComponentArt sure is, except for the annoying lack of client-side validation. Nevertheless, its not too hard to integrate your own javascript and validate your date entries.

This sample uses Prototype, but you can simply replace the '$' by 'document.getElementById' and you should be okay.

(This also assumes you have encapsulated your date picker in a user control)


1.Add a (hidden) div element to your user control


<div style="display:none" id="validationdiv<%=ClientID%>">
<asp:TextBox ID="ValidationTextBox" runat="server" EnableViewState="false"></asp:TextBox>
</div>


2. Add a RequiredFieldValidator, pointing to our hidden TextBox

<asp:RequiredFieldValidator Enabled="false" ID="dateValidator" ControlToValidate="ValidationTextBox" runat="server" ErrorMessage="***" Display="None"></asp:RequiredFieldValidator>

3.Expand your javascript handlers, to change your textbox values when the Calendar/Picker values change.

function MarkAsValidationOk<%=ClientID%>()
{
$('<%=ValidationTextBox.ClientID%>').value = true;
}

function MarkAsValidationNOk<%=ClientID%>()
{
$('<%=ValidationTextBox.ClientID%>').value = “”;
}


function Picker1_onSelectionChanged(sender, eventArgs)
{
sender.AssociatedCalendar.setSelectedDate(sender.getSelectedDate());
MarkAsValidationOk<%=ClientID%>()}

function Calendar_OnSelectionChanged(calendar)
{
calendar.AssociatedPicker.SetSelectedDate(calendar.GetSelectedDate());
MarkAsValidationOk<%=ClientID%>()}

function ClearCalendar<%= Calendar1.ClientObjectId %>()
{
<%= Calendar1.ClientObjectId %>.ClearSelectedDate();
<%= Picker1.ClientObjectId %>.ClearSelectedDate();
MarkAsValidationNOk<%=ClientID%>()
}


4. Add some configuration settings to your user control Codebehind.

public bool EnableValidation { set { dateValidator.Enabled = value; } }
public string ValidationErrorMessage { set { dateValidator.ErrorMessage = value; } }
public string ValidationGroup { set { dateValidator.ValidationGroup = value; } }


5. Expand your 'setdate' server-side functionality to flag validation as ok.

public void SetDate(DateTime date)
{
Calendar1.SelectedDate = date;
Picker1.SelectedDate = date;
timeSelectorControl.DefaultHour = date.Hour;
timeSelectorControl.DefaultMinute = date.Minute;

Page.ClientScript.RegisterStartupScript(GetType(), "datejs" + ClientID, "MarkAsValidationOk" + ClientID + "();", true);
}


6. All done, now you can simply enable validation by setting some properties in the page that uses your control:

<uc1:CalendarPicker ID="birthdayPicker" EnableValidation="true" ValidationGroup="EmployeeValidationGroup" ValidationErrorMessage="BirthDate_Required" runat="server" ShowTimePart="false" />

Selecting all checkboxes with Prootype

For creating a "Select All Checkboxes" link in javascript:

function CheckAll()
{
var allCheckboxes = $$('input[type=checkbox]');
allCheckboxes.each(function(e) { e.click(); });
}


Don't use e.checked = true, because it doesn't trigger the Grid_Item_CheckChanged events of the ComponentArt grid.