Saturday, August 22, 2009

WPF auto fading error message

Here is a small control template to display an error message. The message will fade away after a couple of seconds. You set the message like this:-

Label1.Content = DateTime.Now.ToString();


Here is the xaml:-



<Window x:Class="TRM_Uploader.Window2"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Title="Window2" Height="300" Width="300">
<Window.Resources>
<ControlTemplate x:Key="MyErrorMessage"
TargetType="{x:Type Label}">
<StackPanel Orientation="Horizontal"
Name="ErrorMessage">
<Border CornerRadius="4"
BorderThickness="0"
Background="Red"
VerticalAlignment="Center"
Margin="4,0"
BorderBrush="Transparent">
<Label Foreground="White"
VerticalAlignment="Center"
Padding="4,2"
FontWeight="Bold"
Name="Part1"
Visibility="Visible">Error</Label>
</Border>
<!-- This TextBlock accepts the content from the parent 'label'. It is not actually displayed, just used to bind data-->
<TextBlock Name="Part3"
Text="{TemplateBinding Content}"
Visibility="Collapsed"></TextBlock>
<!-- This TextBlock binds to the one above and triggers an animation when it gets updated. -->
<!-- Its required because TemplateBinding does not allow NotifyOnTargetUpdate -->
<TextBlock Margin="2"
Name="Part2"
Foreground="Red"
Padding="3"
Text="{Binding ElementName=Part3, Path=Text,NotifyOnTargetUpdated=True}"
VerticalAlignment="Center"></TextBlock>
</StackPanel>
<ControlTemplate.Triggers>
<!-- When Text property of Part2 is blank hide entire control-->
<Trigger SourceName="Part3"
Property="Text"
Value="">
<Setter TargetName="ErrorMessage"
Property="Visibility"
Value="Hidden"></Setter>
</Trigger>
<!-- This trigger is called when Part2 updates which in turn is updated by Part3's databind.
It uses animation to make the label fade away after a few seconds. -->
<EventTrigger SourceName="Part2"
RoutedEvent="Binding.TargetUpdated">
<BeginStoryboard>
<Storyboard TargetName="ErrorMessage">
<DoubleAnimation Storyboard.TargetProperty="Opacity"
Duration="0:0:0"
To="1.0" />
<DoubleAnimation Storyboard.TargetProperty="Opacity"
Duration="0:0:2"
From="1.0"
To="0.0"
BeginTime="0:0:1" />
</Storyboard>
</BeginStoryboard>
</EventTrigger>
</ControlTemplate.Triggers>
</ControlTemplate>
</Window.Resources>
<StackPanel Orientation="Vertical">
<Label Template="{StaticResource MyErrorMessage}"
Name="Label1"></Label>
<Button Click="button1_Click">click to test</Button>
</StackPanel>
</Window>




And the c#



 



public partial class Window2 : Window
{
public Window2 ()
{
InitializeComponent();
}

private void button1_Click (object sender, RoutedEventArgs e)
{
Label1.Content = DateTime.Now.ToString();
}
}

Thursday, August 20, 2009

How to make a bootable USB memory stick in Windows 7

I spent ages on this last night without any success, tonight it took me about 60 seconds. Here is the trick.

First you need to download Windows Enabler from http://www.angelfire.com/falcon/speedload/Enabler.htm. This allows any disabled controls to be re-enabled. Install the program and click on its system tray icon to enable it. The Icon should show ‘on’ to show it’s working :

With Windows Enabler running you can go into Windows Explorer and format your memory stick (obviously this will erase everything on the stick). Normally the “create an MS-DOS startup disk” is disabled for everything except floppy disks but with Windows Enabler running you can click the disabled checkbox to use the option with any drive.

I think the file system needs to be set to “FAT”. Once formatted your stick will be a bootable MS-DOS 4.9.3000 boot disk. Easy!

IE image visibility bug

I found two very strange bugs in IE 8 yesterday (probably in other IE versions as well). I have an image and some text in a SPAN that is made visible with some JavaScript. Here is the HTML :

<img id="ctl00_ContentPlaceHolder1_Image3" src="Graphics/waiting.gif" align="middle" style="border-width:0px;visibility:hidden" />

<span id="ctl00_ContentPlaceHolder1_Label4" style="visibility:hidden">Please wait. Adding results to database.</span>

The Javascript attempts to change the visibility like this :

ctl00_ContentPlaceHolder1_Label4.style.visibility='visible';

ctl00_ContentPlaceHolder1_Image3.style.visibility='visible';

for SPAN tags this works. for IMG tags it has absolutely no effect!

The solution is a horrible hack :-

<script type="text/javascript">

function UploadComplete()

{

ctl00_ContentPlaceHolder1_Label4.style.visibility='visible';

document.all.ctl00_ContentPlaceHolder1_Image3.style.display='none';

document.all.ctl00_ContentPlaceHolder1_Image3.style.display='block';

document.all.ctl00_ContentPlaceHolder1_Image3.style.visibility='visible';

document.all.ctl00_ContentPlaceHolder1_Image3.src='waiting.gif';

window.setTimeout(TurnAnimatedGifBackOn, 500);

}

function TurnAnimatedGifBackOn ()

{

var tmp = document.all.ctl00_ContentPlaceHolder1_Image3;

if(typeof (tmp) == 'object')

{

tmp.style.visibility = 'visible'; tmp.src='waiting.gif';

}

}

</script>

To fix the problem the IMG tag has to have it’s display property toggled from ‘none’ and back to ‘block’.

The second bug is that animated gifs stop animating when a page post back occurs. To fix this problem I’ve used a timer to alter the image 500ms after the page post back. To get the animation working the src tag must be reloaded with the image url.

Other browsers do not seem to have this problem.

Enable Hardware Virtualization on Sony VGN-AR71ZU

It is really annoying to discover that Sony disable hardware virtualization and do not provide a bios setting to allow it to be re-enabled. This prevents you from being able to use Windows Virtual PC/MP Mode in Windows 7. I finally managed to hack the bios and now have full hardware virtualization!

Hacking the bios is actually trivial provided you know the right register to change. Chris Hay has a blog post which describes the change for a VGN-AR71ZU (bios = Phoenix R2090J8). (http://silverlightuk.blogspot.com/2009/04/enabling-hardware-virtualization-on.html)

The trouble I had was creating a bootable USB memory stick. I spent hours messing around last night with absolutely no success. In the end I gave up on the USB stick and found an old USB floppy drive. I downloaded the ms-dos 6.22 disk images from MSDN and made myself a set of three setup disks. I then booted off the floppy, exited ms-dos setup with F3 and ran SYMCMOS as described in Chris’s blog post. The process was not helped by the fact that the USB floppy would not work on Vista or Windows 7 so I had to create the ms-dos setup disks on an old XP machine.

Wednesday, July 01, 2009

Firefox 3.5 causes WiFi problems

I have a Intel 4965AGN WiFi card running Windows 7 RC. Yesterday Firefox 3.5 was installed. I think the new location services (which uses WiFi to work out your location) is causing the Windows 7 WiFi to stop working. uninstalled Firefox and WiFi started working again.

Friday, June 19, 2009

FTP.exe on Windows 7

I have a scheduled batch file that sends some files to an FTP server. This stopped working when I upgraded to Windows 7 a few weeks ago. I finally tracked down the problem to the new improved firewall in Windows 7. If you want to use FTP you must edit the Inbound Rule for "File Transfer Program" Private profile and change the TCP action from blocked to allow.

Thursday, May 14, 2009

Tweeting real time energy usage

I finally joined Twitter and promptly wrote a cool windows service that tweets the cost of electricity used in our buildings every half hour. See http://twitter.com/alquistarj Could this be the most boring tweet of all time?

Andrew

Tuesday, December 02, 2008

CRM 4.0 Get accountid from Customer Name (account name)

I could not find a c# web services example of how to get the accountid from an account given the name of the customer. Here is some c# code that can easily be adapted to search for other entities. In this example CrmService is my connection to the web service.

Use it like this :-

string accountid = GetAccountId("My Company Name");




private string GetAccountID (string customername)
{
string ret = "";

// Query condition
ConditionExpression condition = new ConditionExpression();
condition.AttributeName = "name";
condition.Operator = ConditionOperator.Equal;
condition.Values = new object[1];
condition.Values[0] = customername;

// FilterExpression
FilterExpression filterPrincipal = new FilterExpression();
filterPrincipal.FilterOperator = LogicalOperator.And;
filterPrincipal.Conditions = new ConditionExpression[] { condition };

// Columns to return
ColumnSet columns = new ColumnSet();
columns.Attributes = new string[] { "accountid" };

// Query Contact
QueryExpression Query = new QueryExpression();
Query.EntityName = EntityName.account.ToString();
Query.ColumnSet = columns;
Query.Criteria = filterPrincipal;

// Get entities
BusinessEntityCollection entities = (BusinessEntityCollection) CrmService.RetrieveMultiple (Query);
foreach (BusinessEntity entity in entities.BusinessEntities)
{
account Account = entity as account;
return Account.accountid.Value.ToString();
}
return "";
}

Thursday, September 11, 2008

Virtual PC 2007 Version numbers

Virtual PC 2007 = Version 6.0.156.0
Virtual PC 2007 SP1 = Version 6.0.192.0

SQL 2008 Error 5120

Today I was trying to attach some databases to SQL 2008 on a Vista machine but kept getting Error 5120. To avoid this problem you must start SQL Server Management Studio in Administrator mode. (right click the link, select Properties, click Advanced and enable "run as Administrator").

SMTP server in Windows Server 2008

This took me a while to find today. If you install the SMTP server in Windows 2008 the management tool is in Internet Information Services (IIS) 6.0 Manager rather then in the new IIS7 tool.

Tuesday, September 02, 2008

PopupControlExtender bug with buttons

There seems to be a bug in the Ajax Control Toolkit that generates a Javascript error when you click on a button inside a PopupControlExtender panel. I replaced the Button with a LinkButton and managed to get things working.

Sunday, August 31, 2008

IIS7 folder rights when uploading files

IIS7 seems to create a new Application Pool for each web site. The app pool uses the "NetworkService" identity by default (right click on the application pool and select Advanced Settings to see the details). You therefore need to allow "Network Service" (Note space) to have write permission to any folders where you want to save uploaded files into when using Anonymous or Forms authentication.

IIS7 Membership provider

I've just installed Windows 2008 on one of my main web servers. I have an ASP.NET web site that uses the SQL Membership provider.

Originally I had this in my web.config file :-

< defaultprovider="MyMembershipProvider">
<>
< name="MyMembershipProvider" connectionstringname="MyMembershipConnectionString" type="System.Web.Security.SqlMembershipProvider" applicationname="MyAppName" enablepasswordretrieval="false" enablepasswordreset="true" requiresquestionandanswer="true" requiresuniqueemail="true" passwordformat="Hashed">
< /add >
< /providers >
< /membership >

But I discovered that this works as a membership provider but does not allow IIS Manager to display the users when the .NET Users button is clicked. If you replace the type attribute above with :-

type="System.Web.Security.SqlMembershipProvider,System.Web,Version=2.0.0.0,Culture=neutral,PublicKeyToken=b03f5f7f11d50a3a"

it works.

Wednesday, August 27, 2008

iPhone 3G - Useless

Today I took a trip by train from Cambridge to London with my new iPhone 3G. What a waste of time the iPhone is. The main problem seems to be getting any sort of reliable connectivity. The phone is constantly switching from GPRS to Edge to 3G to WiFi and each time it does this it seems to freeze for a few seconds. If this is twice as fast as the old iPhone I'm glad I never had one. It makes working with a 56K modem seem like fun. I suppose I was playing with the phone for an hour on the train but by 11:53 am the phone was flat! I'd only managed a couple of hours - Totally useless!!! I'm almost tempted to send it straight back. I can understand connectivity on the train being a problem but it's no better in central London. I'll wait and see if V2.1 is any better.

It's also really annoying that the mail application cannot be rotated and where is the copy & paste functionality? I understand copy & paste is a security issue but surely it’s an essential feature.

Overall : not at all impressed.

Wednesday, July 09, 2008

Good quote...

If you are willing to satisfy people with good enough, you can make just about everybody happy. If you delight people and create change that lasts, you're going to offend those that hate change in all its forms. Your choice.

Thursday, June 12, 2008

Adding OpenID to an existing ASP.NET application

[Updated 22:00 12 June 2008] To include improvements suggested by Andrew Arnott.

In this post I'll describe the steps I took to add OpenID support to an existing ASP.NET app that used forms authentication. The application originally used the users email address as their username. The OpenID login process therefore needs to provide an email address to avoid having to rewrite loads of code. Not all OpenID providers allow email addresses to be sent so new users might have to partially re-register the first time they use their OpenID.

  1. Downloaded the latest DotNetOpenID zip file from http://dotnetopenid.googlecode.com/files/
  2. Unziped the package
  3. Copied and renamed login.aspx and login.cs from \Samples\RelyingPartyPortal to my project's root folder, renaming them loginOpenID.aspx and loginOpenID.cs. Changed codebehind attribute in loginOpenID.aspx from CodeBehind="login.aspx.cs" to CodeBehind="loginOpenID.aspx.cs". I then added a link named "Login with OpenID" on my original login.aspx page pointing to the new loginOpenID.aspx page. I then changed some of the properties on the OpenIdLogin control as I wanted to ask the OpenID provider to supply the users FullName and Email address. Unfortunately some providers (eg Yahoo.com) do not allow the FullName & Email info to be sent so we'll have to deal with this in code later.

    <RP:OpenIdLogin ID="OpenIdLogin1"
    runat="server"
    RequestFullName="Require"
    RequestEmail="Require"
    RememberMeVisible="True"
    PolicyUrl="~/PrivacyPolicy.aspx"
    TabIndex="1"
    OnLoggedIn="OpenIdLogin1_LoggedIn"    
    OnCanceled="OpenIdLogin1_Canceled"
    OnFailed="OpenIdLogin1_Failed"
    OnSetupRequired="OpenIdLogin1_SetupRequired" RememberMe="True"
    />

  4. Copied \Samples\RelyingPartyPortal\Code\state.cs to my project's App_Code folder
  5. Copied \Samples\RelyingPartyPortal\xrds.aspx to my project's root folder. Modified this file to point to my new loginOpenID.aspx page changing

    <URI><%=new Uri(Request.Url, Response.ApplyAppPathModifier("~/login.aspx"))%></URI>

    to

    <URI><%=new Uri(Request.Url, Response.ApplyAppPathModifier("~/loginopenid.aspx"))%></URI>

  6. Copied \Samples\RelyingPartyPortal\privacypolicy.aspx to my project's root folder.
  7. I added the following to default.aspx (the default document for this domain).
    <%@ Register Assembly="DotNetOpenId" Namespace="DotNetOpenId" TagPrefix="openid" %>
    <openid:XrdsPublisher runat="server" XrdsUrl="~/xrds.aspx" />
    This was required to get myopenid.com accounts to work.
  8. Added a reference to the DotNetOpenID.dll from the \Samples\RelyingPartyPortal\bin folder
  9. I then added code to OpenIdLogin1_LoggedIn in loginOpenID.cs to ensure we have the user's real email address. If for whatever reason we cannot get their email address redirect them to the partially populated registration page.


     

    protected void OpenIdLogin1_LoggedIn (object sender, OpenIdEventArgs e)

        {

        State.ProfileFields = e.ProfileFields;

        

        //    Setup linq connection to SQL database                        

        DataClassesDataContext db = new DataClassesDataContext(ConfigurationManager.ConnectionStrings["DB_RW"].ConnectionString);

        People people = null;


     

        //    See if user has logged on using OpenID before                

        try

            {

            people = (from c in db.Peoples

                     where c.OpenID == e.ClaimedIdentifier.ToString()

                     select c).Single();

            }

        catch

            {

            }


     

        if (people == null)

            {

            //    This is the first time this OpenID identity has been used    

            if (e.ProfileFields.Email == null)

                {

                //    Force user to register as their OpenID provider did not send their email

                //    address (eg Yahoo.com) and this app needs their real email address.        

                e.Cancel = true;

                Response.Redirect("RegisterNewAccount.aspx?mode=OpenID_NoEmailSupplied");

                return;

                }

            else

                {

                //    See if user has created an account already                

                try

                    {

                    people = (from c in db.Peoples

                             where c.Email == e.ProfileFields.Email

                             select c).Single();

                    }

                catch

                    {

                    //    email address does not exist in our user table redirect user    

                    //    to registration page.                                            

                    e.Cancel = true;

                    Response.Redirect("RegisterNewAccount.aspx?mode=OpenID_UnknownEmail");

                    return;

                    }

                }

            }


     

        if (people.Status.StartsWith("Reject T&C"))

            {

            e.Cancel = true;

            loginFailedLabel.Text = "Your account has been suspended because you have rejected our T&C's.";

            loginFailedLabel.Visible = true;

            return;

            }


     

        if (people.Status != "Verified")

            {

            e.Cancel = true;

            loginFailedLabel.Text = "Your account has not been verified yet. Check your email for further instructions.";

            loginFailedLabel.Visible = true;

            return;

            }


     


     

        //    Remember OpenID identity for next time            

    people.OpenID = e.ClaimedIdentifier.ToString();
    people.LoginCount = (people.LoginCount ?? 0) + 1;

        db.SubmitChanges();


     

        //    I set some other Session variables here

    Session["UserEmail"] = people.Email;


     

    //    The openID code will now redirect to the requesting page    

    //    and set context.user.identity.name to the OpenID identity    

    //    eg http://andrew.jones.myopemid.com                            

    }

  10. The RegisterNewAccount.aspx pre-populates as much information as it can. Any additional user information sent by the OpenID provider is available in State.ProfileFields.

Thursday, June 05, 2008

DataGridViewRow SelectedRows selection order

When you use SelectedRows to get the selected rows from a DataGridView the order of items is dependent on the order they were selected. If you start at the top and select down the item list will be reversed. Selecting from the bottom row up is OK. Selecting random rows with CTRL pressed will leave the most recent item at the start of the list. The list therefore needs to be sorted based on the DataGridViewRow.Index property.

Here is a function to sort the list




// Create a generics list to hold selected rows so it can be sorted later
List<DataGridViewRow> SelectedRows = new List<DataGridViewRow>();


foreach (DataGridViewRow dgvr in yourDataGridViewControl.SelectedRows)
SelectedRows.Add(dgvr);

// Sort list based on DataGridViewRow.Index
SelectedRows.Sort (DataGridViewRowIndexCompare);




private static int DataGridViewRowIndexCompare (DataGridViewRow x, DataGridViewRow y)
{
if (x == null)
{
if (y == null)
{
// If x is null and y is null, they're
// equal.
return 0;
}
else
{
// If x is null and y is not null, y
// is greater.
return -1;
}
}
else
{
// If x is not null...
//
if (y == null)
// ...and y is null, x is greater.
{
return 1;
}
else
{
// ...and y is not null, compare the
// lengths of the two strings.
//
int retval = x.Index.CompareTo (y.Index);

if (retval != 0)
{
// If the strings are not of equal length,
// the longer string is greater.
//
return retval;
}
else
{
// If the strings are of equal length,
// sort them with ordinary string comparison.
//
return x.Index.CompareTo(y.Index);
}
}
}
}

Monday, June 02, 2008

TCP/IP Fundamentals

Microsoft have released a very useful (free) PDF book describing in details TCP/IP.

Download

Friday, May 09, 2008

LinkedIn BICSI RCDD group

I've just created a BICSI RCDD group on LinkedIn. If you are a BICSI RCDD click on the link below to join :-

http://www.linkedin.com/e/gis/101866/2861405DDA38