Thursday, May 28, 2009

TomTom sucks for customisation.

I recently emailed TomTom technical support stating that I was a software developer (and TomTom owner) interested in writing software for the TomTom device. I wanted to know where to get the SDK that they did have available up to about 1 year ago but now seems to have disappeared. This was their response:

Dear Mr Clark,

Thank you for your query. Your incident reference number is 090526-001861.

Unfortunately the Software Development Kit is no longer available from TomTom.

Please note that we are unable to offer any technical support for 3rd party add ons or software tools used in conjunction with your TomTom device.

Best Regards,

David A

TomTom Customer Support

Damn that sucks. What is with companies that want to keep you locked down to the software they make on a device that you own. They don’t even sell the navcore, they make nothing from it – they sell the hardware and the maps! It should only increase the value of the device and maps if there is more software available, and the cost to them of releasing their SDK would be minimal. Pretty short sighted if you ask me.

There are lots of little software projects that are now dead in the water due to the lack of an SDK for the latest version.

Tuesday, May 26, 2009

How to make images look disabled (greyed out) when the Button or MenuItem they are within is disabled in WPF

By default in WPF image controls that are within disabled menus and buttons will not be greyed out. One common way to achieve a standard look is to apply a style to the image that will cause it to be partially transparent when its parent is disabled. You create a style with TargetType of Image that is a Setter for the Opacity property with a Style.Trigger bound to the IsEnabled property of the image's parent (via RelativeSource). (Code later...) I made two triggers initially, as some of my Images are in Buttons and some are in MenuItems.

Just looking at my output window, I noticed a whole bunch of errors when the UI was coming up, some like this:

System.Windows.Data Error: 4 : Cannot find source for binding with reference 
'RelativeSource FindAncestor, AncestorType='System.Windows.Controls.MenuItem', 
AncestorLevel='1''. BindingExpression:Path=IsEnabled; DataItem=null; target 
element is 'Image' (Name=''); target property is 'NoTarget' (type 'Object')

And others like this:

System.Windows.Data Error: 4 : Cannot find source for binding with reference 
'RelativeSource FindAncestor, AncestorType='System.Windows.Controls.Button', 
AncestorLevel='1''. BindingExpression:Path=IsEnabled; DataItem=null; target 
element is 'Image' (Name=''); target property is 'NoTarget' (type 'Object') 

Thinking about it for a second, you can see that both of the style triggers will get applied to each image. For each image one will work and one will fail - there can only be one type for the parent element, Button or MenuItem not both. It is a silent failure so could just be lived with but I wanted to fix it.

First I was trying to find a way to choose which trigger to apply depending on the type of the parent*. I know you could remove the TargetType from the style and apply it as a named style to each element, but that just becomes a mess. The whole idea of this solution is to make at as simple to use as possible - basically just letting it modify the behaviour of all images. The real solution of course is to realise that the IsEnabled property is not a member of Button nor MenuItem directly, but it is on the UIElement class.

The fix then is to have only one Style.Trigger with the AncestorType of UIElement:

<Style TargetType="{x:Type Image}">
    <Style.Triggers>
        <DataTrigger Binding="{Binding RelativeSource={RelativeSource AncestorType={x:Type UIElement}, AncestorLevel=1}, Path=IsEnabled}" Value="False">
            <Setter Property="Opacity" Value="0.3"></Setter>
        </DataTrigger>
    </Style.Triggers>
</Style> 

* I would still like to know how to do this, but that will have to wait until another time when I really do need to do it. No time!

Programmatically changing TreeViewItem IsSelected fails to set IsFocused

I was having an odd problem with the IsSelected property of TreeViewItems. After adding an item and setting its IsSelected property, the originally selected item is no longer selectable.

I am using the Model-View-ViewModel pattern and a HierarchicalDataTemplate to bind a TreeView. The ItemsSource is an ObservableCollection. I noticed that when I added a new item to the collection (making it IsExpanded and IsSelected) it was added fine and was selected, but the parent item was no longer selectable. Any other item in the TreeView was selectable, and if you select one then the parent was again selectable, but right after the Add on the collection it was broken.

Seems to be a known problem: the IsFocused property is not updated when you change IsSelected via code. I am a little surprised that it is also not kept up to date when you set it via a binding… but I guess in the end binding is just code that you didn’t have to write yourself. Hopefully someone, somewhere will decide that this is indeed a bug so I can remove the event handler that I have put in place as a workaround*

Sample reproduction code:

<Window x:Class="WpfApplication1.Window1"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    xmlns:local="clr-namespace:WpfApplication1;assembly="
    Title="Window1" Height="300" Width="300">
    <Window.CommandBindings>
        <CommandBinding Command="{x:Static local:Window1.AddChildItem}" 
                            CanExecute="AddChildItem_CanExecute"
                            Executed="AddChildItem_Executed" />
    </Window.CommandBindings>
    <Window.Resources>
        <HierarchicalDataTemplate DataType="{x:Type local:Item}"
                                  ItemsSource="{Binding Children}">
            <TextBlock>
                <TextBlock Text="Name -> " />
                <TextBlock Text="{Binding ItemName}" />
                <TextBox></TextBox>
            </TextBlock>
        </HierarchicalDataTemplate>
        <Style TargetType="{x:Type TreeViewItem}">
            <!-- property bindings -->
            <Setter Property="IsExpanded" Value="{Binding IsExpanded, Mode=TwoWay}" />
            <Setter Property="IsSelected" Value="{Binding IsSelected, Mode=TwoWay}" />
            <!-- Workaround: Keep the IsFocused property up to date when the IsSelected property changes -->
            <EventSetter Event="Selected" Handler="TreeViewItem_Selected" />
        </Style>
    </Window.Resources>
    <DockPanel LastChildFill="True">
        <ToolBarTray DockPanel.Dock="Top" Height="21">
            <ToolBar>
                <Button Command="{x:Static local:Window1.AddChildItem}">
                    <TextBlock Text="Add" />
                </Button>
            </ToolBar>
        </ToolBarTray>
        <TreeView Name="tv1" ItemsSource="{Binding Items}">
        </TreeView>
    </DockPanel>
</Window>

using System.Collections.ObjectModel;
using System.ComponentModel;
using System.Windows;
using System.Windows.Input;
using System.Windows.Controls;
 
namespace WpfApplication1 {
    public partial class Window1 : Window {
        private ObservableCollection<Item> _items = new ObservableCollection<Item>();
        public ObservableCollection<Item> Items {
            get { return _items; }
        }
 
        public static readonly RoutedCommand AddChildItem = new RoutedCommand("AddChildItem", typeof(Window1));
 
        public Window1() {
            InitializeComponent();
 
            _items.Add(new Item { ItemName = "One" });
            _items.Add(new Item { ItemName = "Two" });
            _items.Add(new Item { ItemName = "Three" });
 
            this.DataContext = this;
        }
 
        private void AddChildItem_CanExecute(object sender, CanExecuteRoutedEventArgs e) {
            if(tv1 != null && tv1.SelectedItem != null) {
                e.CanExecute = true;
            }
        }
 
        private void AddChildItem_Executed(object sender, ExecutedRoutedEventArgs e) {
            if(tv1.SelectedItem != null) {
                (tv1.SelectedItem as Item).AddChildItem();
            }
        }
 
        // Without this event handler you will see the problem
        private void TreeViewItem_Selected(object sender, RoutedEventArgs e){
            TreeViewItem tvi = e.OriginalSource as TreeViewItem;
            if(tvi != null && !tvi.IsFocused) {
                tvi.Focus();
            }
        }
    }
 
    public class Item : INotifyPropertyChanged {
        private string _itemName = "New Item";
        public string ItemName {
            get { return _itemName; }
            set { _itemName = value; }
        }
        private ObservableCollection<Item> _children = new ObservableCollection<Item>();
        public ObservableCollection<Item> Children {
            get { return _children; }
        }
        private Item _parent = null;
        public Item Parent {
            get { return _parent; }
        }
 
        public Item() : this(null) { }
        public Item(Item parent) {
            _parent = parent;
        }
 
        public void AddChildItem() {
            Item i = new Item(this);
            _children.Add(i);
            i.IsSelected = true;
        }
 
        private bool _isSelected;
        public bool IsSelected {
            get { return _isSelected; }
            set {
                if(_isSelected != value) {
                    _isSelected = value;
                    OnPropertyChanged("IsSelected");
                }
            }
        }
 
        private bool _isExpanded = true;
        public bool IsExpanded {
            get { return _isExpanded; }
            set {
                if(_isExpanded != value) {
                    _isExpanded = value;
                    if(_isExpanded && _parent != null) {
                        _parent.IsExpanded = true;
                    }
                    OnPropertyChanged("IsExpanded");
                }
            }
        }
 
        #region INotifyPropertyChanged Members
 
        public event PropertyChangedEventHandler PropertyChanged;
 
        #endregion
 
        protected virtual void OnPropertyChanged(string propertyName) {
            if(this.PropertyChanged != null) {
                this.PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
            }
        }
    }
}

Just Comment out the call to Focus to see the problem.

Of note also is the fact that you must set IsSelected after the new item is inserted into the visual tree. For me that meant a small refactor (seen in the example in AddChildItem) to create the item, add it to the collection then set its IsSelected property rather than creating it with IsSelected already set to true. Otherwise it seems that the call to Focus fails.


* I.e. my code was all nice and separated, I was not handling any TreeView or TreeViewItem events, it was all done with smoke and mirrors** in a layer between the UI and the BO

** Data binding

Thursday, April 09, 2009

Tweet Delete?

Ack! all of my twitterings since over a month ago have disappeared!

I feel lost! They were only silly irrelevant mutterings for the most part, but they were my silly irrelevant mutterings and I trusted you to store them!

I have logged a ticket with twitter, hopefully they will return from the void…

Wednesday, April 08, 2009

Page.IsAsync broken on ASP.Net MVC

I was just trying to add a condition to my validation code so it would not run when the page was asynchronously posted (my controls were getting highlighted as an error before the user has even had the chance to enter any values because of some ajax that was updating another area of the page), but I found that the Page.IsAsync member is always false.

I managed to find another member that you can access via the ScriptManager:

ScriptManager.GetCurrent(Page).IsInAsyncPostBack

Which seems to work.

Wednesday, March 18, 2009

TextChanged event of TextBox not raised by the Internet Explorer AutoComplete feature

As noted in this msdn article, The TextChanged event of a TextBox control may not fire if the AutoComplete feature is enabled in Internet Explorer. And it appears to be “by design” – I hate that.

Fortunately, it is pretty easy to add some JavaScript to make the ‘right thing’ happen.

All you need to do is raise the onchange event at the appropriate time. For me that is when the TextBox loses focus. As I am doing this from code behind (as usual) I am registering a client script, then when I add the TextBox I set its onblur attribute accordingly:

Page.ClientScript.RegisterClientScriptBlock(typeof(FormPage), "RaiseOnChange", "function RaiseOnChange(ctrl){ctrl.fireEvent('onchange');}", true);
tb.Attributes[HtmlAttributes.OnBlur] = string.Format("RaiseOnChange({0})", tb.UniqueID);

The server side TextChanged event only gets raised if the TextBox.Value has really changed. I needed to do this because I am using the TextChanged event of some TextBox controls to trigger an asyncpostback to update an UpdatePanel. The code that sets the content of the UpdatePanel is in the server side TextChanged handler.

Friday, March 13, 2009

Quoted strings

I posted something about this once before, but having just given myself a headache trying to fix something similar once again I feel like writing some more.

Using the quote delimiter character inside of a quoted string at always a minor problem. There are two ways you can fix it – you can escape the quote using whatever method is valid at the time* or you can change the type of quote delimiter, i.e. you can switch from " to ' or vice-versa. There is a deeper problem though that is only really seen when you are not just embedding a delimiter in a string, but (as seems to be often the case with web development) when you are passing such a string to someone or something else. Say for example you are writing ASP.Net code behind to output a __doPostback where one of the arguments is a string with an embedded delimiter. The string in .Net code will be delimited (say with ") then the argument to __doPostback will also be delimited (say with ') but then the data in that string might contain ' (e.g. O'Neil) which will have to be escaped.

My exact situation this time was slightly more complicated still – I have three levels of indirection! I am in c# code behind, setting the .Text property on a Telerik DataGridItem to be an html anchor tag which will do a postback. So the .Net string is delimited (with " naturally), the onclick of the a tag is delimited (with " also by convention, so escaped for .Net as \"), the argument to the __doPostback function is delimited (with ' because there is no way of escaping nested " characters for html) and finally the data in that argument might have ' characters so it needs to be escaped (by \')! And certain parts need to be UrlEncoded also, but before you put in the \' escaping or else you will UrlEncode the \ character. *Hum*

item[colName].Text = string.Format("<a href=\"#\" onclick=\"__doPostBack('', '{1}{0}{2}')\">{3}</a>", QueryString.PostBackArgSep, postbackType, item[colName].Text.Replace("'", "\\'"), item[colName].Text);

* Mmm, yes. Whatever method is valid at the time. This is not always straight forward with some situations calling for \ to give \' or \", some for a doubling up of the offending character giving '' or "", or even for escaping to be impossible in the current context, leaving you with only the ability to switch delimiters. This last problem with why I try to stick with " as the delimiter most of the time and escaping where required rather than the simpler change to ' so as to save the other character for situations where it is the only method (e.g. html). I think that it is probably possible to get yourself into a situation where there is no possible way to pass the string ‘down the line’ as it were without breaking something. If that happens either you need to encode and decode the whole string somewhere, or admit that you are doing something the hard way and find the right way to do it… I almost think that is what is going on here with my current problem – I think it could be solved by keeping the information that I am passing through to __doPostback somewhere else and just passing a key to it to the code I am calling, but I don’t have the time to do that right now, and this form will be soon superseded by an ASP.Net MVC version.

Wednesday, March 04, 2009

Virtual Root (~) gives 404 error

We had a server reboot after a power failure yesterday, and this morning an ASP.NET application that has been working for months started giving this error:

Server Error in '/' Application.

The resource cannot be found.

Description: HTTP 404. The resource you are looking for (or one of its dependencies) could have been removed, had its name changed, or is temporarily unavailable.  Please review the following URL and make sure that it is spelled correctly.

Requested URL: /~/direct.aspx


Version Information: Microsoft .NET Framework Version:2.0.50727.3082; ASP.NET Version:2.0.50727.3082

Seems to me that it is not translating the ~ into the Application Root path, but I am at a loss as to why. I have posted a question about the ~ virtual root giving a 404 on the ASP.NET newsgroup, but as is often the case with these WTF kind of posts I am not really expecting a response…

It was easily ‘fixed’ by just making the form action use the absolute path to the aspx file, but I want to know why it is broken.

Tuesday, March 03, 2009

Telerik RadUploadProgressHandler and ASP.NET MVC

Just ran into a small problem with the Telerik radUpload control and ASP.NET MVC.

The upload progress needs to have a httpHandler and httpModule configured in Web.config for it to work correctly – I think it is that which handles the GUID that it tacks onto the end of the url to maintain state (among other things). The path is normally Telerik.RadUploadProgressHandler.ashx but with MVC this will be routed to a controller and the handler will not be found.

I have added an exclusion to my Global.asax.cs file and it seems to work.

routes.IgnoreRoute("Telerik.RadUploadProgressHandler.ashx/{*pathInfo}");

Remains to be seen if this is the right way to do it or if there is anything else wrong, but for now I am just trying to get two existing web applications merged together as one MVC application. A lot of the stuff that those apps are doing is not “correct” from a MVC point of view, but this is version 0.9 :)


[Edit] Meh. Don’t need to do that. There are instructions on the Telerik site for how to configure the httpHandler for RadUpload under ASP.NET MVC

Shake to do something

What? That has to be the most stupid interface trick that I have ever heard of. Why the hell would I want to shake my iPhone to delete the current entry or shake it to start the recording? Jeebus. Perhaps if it was really sensitive and the shaking was totally in context with what you are using the device for, but shake to delete a database entry? That is just a stupid gimmick!

Monday, March 02, 2009

More iPhone icons

I am not quite happy with the template that I made for these icons… The corners are not quite right. But at least the first page of my applications all are about the same brightness now, and they all have the same border look. One for Twittelator* and one for gNotes:

Twittelator gNotes

Next!


* The channels of the png are in the wrong order, or a different order, or something on the iPhone so you have to use fixpng or something to fix it before you can open it for editing… but that seems to modify the colours (fair enough I guess, you are changing the channels…). I thought it was just a straight negative, but I don’t think it is. Rather than fiddling too much though, I quite like the colour of the Twittelator one as it is – better than the aqua and purple one that is the default anyway.

iPhone themes…

Wow, there are a bunch of themes out there for WinterBoard etc.

I am using iGlassSol which is very nice, but there are a couple of things I didn’t like. The clock could have a better time on it, and there was no icon for WideEmail. So I made some:

Clock WideEmail

The other thing that I made was a new dock with 5 icons on it… but it seems like there is a way to make it generate the glassy looking dock on the fly… but I can’t find it, only forum posts talking about it. Anyway, the dock (with WideEmail as the extra icon):

SBDockBG

Fun.

Tuesday, February 24, 2009

Call a method on an object only when that object is not null

I have often wanted an operator or something that will do something like run a method on an object if that object is not null (returning a default value if it is null). An example:

string s = SomeClass.SomeMember.ToString(); 

maybe for output or something. Now this works just fine, unless SomeMember happens to be null, when this code will throw an exception. So the code has to become:

string s = SomeClass.SomeMember != null ? SomeClass.SomeMember.ToString() : ""; 

or something like that. Upon finding the ?? ‘null coalescing operator’ I thought that would do the trick, but that will only munge the ToString (say) return value to "" if it was null, not let you call members on a null reference. You could do something with a chain of ?? operators, but that looks nasty and if anything in the chain is actually a method call rather than a property access then it may be called multiple times…

I think that I have come up with something neat and simple that works.

public static TResult Try<T, TResult>(this T left, Func<T, TResult> func) { 
    return Try(left, func, default(TResult)); 
} 
 
public static TResult Try<T, TResult>(this T left, Func<T, TResult> func, TResult defaultValue) { 
    if(left != null) { 
        return func(left); 
    } else { 
        return defaultValue; 
    } 
} 

Which can be used like this:

string s = SomeClass.SomeMember.Try(m => m.ToString(), ""); 

I named it Try in reference to functions such as TryParse. Perhaps not the best choice of name, but I am pretty phenomenally bad a choosing names for things… If you use it on a null reference you will get back the default value you specify or if you don't specify one you get the default value of type of the lambda expression. This second case (not specifying the default explicitly) is more useful when the type is not nullable... It is useful for calling functions on members of a class that might be null. More than that of course though, as that is a lambda (well actually a Func<T, TResult> Generic Delegate which is most easily populated with a lambda) you can pretty much do whatever you like in there.

Now I understand that this is not for everybody and that it is not going to work in all situations. Sometimes a null return value will not always have the same meaning as the default value for that type, but if you keep this in mind to does clean up a lot of code.

Another example to illustrate:

public class DataObject { 
    public List<string> Strings; 
} 
 
DataObject myDataObject = new DataObject(); 
// int stringCount = myDataObject.Strings.Count; // *boom!*
int stringCount = myDataObject.Strings.Try(l => l.Count); 

So this does not give you all of the same information that you get from receiving the null value, but it makes some common stuff painless, like telling the user how many strings there are. I find myself hiding the null value a lot of the time anyway, converting it to "" or 0 or whatever, so there you go.

Real world ‘improvement’. This:

object obj = ExecuteScript(script);
if(obj != null) {
    return obj.ToString();
} else {
    return "";
}
Becomes this:
return ExecuteScript(script).Try(o => o.ToString(), "");

Incidentally, I really love how well the type inference works now. There is no need to specify the types when calling the function - like myDataObject.Strings.Try<string, int>(l => l.Count) - and the return type gets updated when you add or change the return type of the lambda expression. Very neat.

A little love for Windows Live Writer

Problem solved.

There was some odd “bug fixing” stuff in the blogger theme.

.post-body p {
  line-height: 1.4em;
  /* Fix bug in IE5/Win with italics in posts */
  margin: 0;
  height: 1%;
  overflow: visible;
}

This was confusing WLW a bit obviously. I just removed this (sorry no more support for IE5 *pfft*) and all is well. the problem that I thought I was going to have with the empty p tags between each paragraph that I was getting but do not get when WLW is working properly is a non problem. The actually empty tags: <p></p> are not rendered at all, only the tags that WLW was inserting: <p>&#160;</p> with that non breaking space in there were causing the blank paragraph to be given some space – and these are not generated when your CSS is okay.

So everything work as far as I can see. Looks like a real WYSIWYG editor now. I can click anywhere, I can insert lists, I can probably stop checking the mark-up like a freak…

Thanks Joe Cheng! You rock.

Sunday, February 22, 2009

Bad Xml – to accept or to reject, that is the question.

Was just reading this post which touches on accepting invalid Xml communications. And I agree.

I think it boils down to “make sure you produce good XML, but accept anything with the proviso that there may be odd behaviour if the format is not correct”. Library wise though, permissive reading is fine, but if your library produces bad XML you deserve to be stamped out. I have to say that the Microsoft Xml stuff is really pretty good. They are an option 1 library though, so don’t expect to be able to read in any old just, but they will not produce invalid Xml*.

This is the route that I have gone with all of the stuff that I have been doing lately. It is a little more complicated than that though because the data structure that I am using is created from the DTD** so I need to not only accept invalid XML but convert it into valid XML to store it.


* This is something that I have had to explain a few times… Sometimes is is difficult, sometimes people understand. Mostly I don’t bother complaining too much about receiving nasty Xml, but forcing myself to produce bad Xml because someone’s hand coded parser reacts badly to something valid in my valid Xml (namespace definition).

** Funny story. It’s their DTD, but they can’t manage to produce Xml that validates against it, and they expect values for certain elements that are not valid under it (value="" when value is an NMTOKEN). Chuckle…

WLW tag problems

After looking at this post from someone with formatting problems in WLW, I have switched WLW into editing without the template. Looks nasty, but the mark-up is nice.

Only problem is that now it does not put a blank p tag in between each paragraph. So I would go and change the template to add some margin to the end of a paragraph to get my spacing back but then that is going to stuff up all of the old posts! Ugh. I do not want to go back and edit them all again! I already did that once…

It would be nice if I could modify the tag that WLW puts in for a paragraph to include a class attribute – that way I could modify the template so it only affected these new posts… Actually, that is something that is a bit of a problem with Blogger in general – changes take effect on all old posts. E.g. if you change the time zone. Not much you can do about that though really.

Just store it for me

This is an interesting article: untitled document syndrome

In the past I was firmly in the “no, I really do want to specify where you are putting my file” camp, but increasingly I prefer to succumb to human nature and let someone else do it for me.

I still like to be able to configure the root of the storage. For example to put it into my svn working copy so I have a backup and can get at it from other machines. But once that is done, and as long as I can actually find the files somewhere should I want to, I do quite like the way iTunes (for example) just takes what you put into iTunes and stores it for you.

It would be nice if more applications did this. It might be nice if this was some king of system service that an application could use. I think a lot of my applications could benefit from this – it is certainly true that for most business users the location (or the very existence) of the actual file is of little importance, as long as they can find the work and get it back and use it. You only have to look at some people’s machines and the places they manage to get files saved to realise that most people either don’t know or don’t care that there is even a choice to make about the directory they save a file in.

Saturday, February 21, 2009

Login or Register

When you have a site that uses user accounts, say for returning customers, I really hate the common theme of having a login fields area and a register fields area.

Mainly because I can’t always remember if I am registered or not. Why not make the forms do double duty as login and registration forms? You put in your email address* and what you think is your password and hit the button. If that user exists and the password is correct, let me in. If that user exists and the password is not correct, bounce me with a message. If that user does not exist, go on to a registration page and get the rest of my details**, and keep the hash of my password so you only have to confirm it not get me to type it twice again.

Streamlined. The only thing that I can see that is wrong with this idea is that it does give away some information, namely the form tells you that a certain email address is registered on that site. However the existing registration form does that anyway so…


* I am pretty much a believer in the email address as username idea. There is never going to be a problem with your desired username being take already, and people who complain that they have too many email addresses or they change them often or whatever… pfft.

** Or better yet – don’t ask me for any more information, just to confirm the password. Oh, and make sure I can continue on with what I was doing.

Google JavaScript error AGAIN

What the hell Google? A JScript error again? Last week it was AdSense, this week it is in the Followers gadget.

I just happened to look at my blog before thinking about posting something and up pops a JScript error and then a blank blog page. Nice. Upon debugging I see the error is in this line:
google.friendconnect.container.renderUrlCanvasGadget({'id': 'gadget-canvas'})

Which look like it might be the Followers gadget. I disable it and no more error. So not too hard to get by, but what the hell is with all these scripting errors?

I think there might be some kind of problem with the QA and deployment strategy over at the big g…


[Edit] I went and put the gadget right back again, and the error does not reoccur… I can’t see that line of code anywhere at all, so I don’t know if that was not the problem or if it was fixed quickly or if adding and removing it updated the code or what… Gotta go.

Friday, February 20, 2009

Unfun things

Programmers tend to loathe writing documentation. I always have great documentation in mind while I am developing a nice solution to a problem, but it rarely gets realised. Usually the bare minimum gets done – sometimes less than that.

Another thing that is probably number two on the list of most not fun to do is error handling and logging.

I have just spent a little time cleaning up the error handling in the couple of applications that I am writing right now.

There are various components, running across various platforms – Windows and Web clients, .NET Remoting servers, Windows services, Web services, ASP.NET web sites (that are actually generated from specifications in xml files that are in turn created by a tool – one of the windows client applications). Anyway, the whole thing is getting a little too complex to hold in your head at once, and before it gets too complicated I wanted to put in a common logging component. I have wanted to do it for a while – get away from each component knowing how to ends an email or write the windows log. Now it is mostly done.

I guess the whole point of this ramble was just to say that I got myself to do something pretty unpleasant – fix up exception handling chains, move chunks of code around while deciding which of 3 similar implementations are correct, fix up dll referencing issues, test error conditions – by giving myself something a little but fun to do – write a nice class using generics to build and hold an error message (so a message can be build up as different components have more or less important problems), grow the re-usable library that I have and actually re-use it.

Wednesday, February 18, 2009

Adding text to a WLW post without screwing up the mark-up!

Finally! I have discovered a way to add text at the end or middle of a post without causing horrible nesting problems with the <p> tags.

If you just go clicking at the end of an existing paragraph, or even on it, or even clicking in a space that looks blank, it is pretty easy to end up with this kind of mess:

<p>
  <p>para1</p>
 
  <p>para2</p></p>

But now I have managed to work out how to avoid it! As an example, to add a paragraph to the end of a post:

  • Hover over the invisible box that represents the blank <p></p> that WLW sticks after each paragraph with text in it. You are looking for the North South East West arrow cursor.

  • Click to select it. You need to end up with the eight little squares in the corners and on the edges showing that the whole element is selected, not the insertion point indicating that it is trying to add text inside the element.

  • Now press the right arrow key. You should end up with the insertion point below the element you clicked on. Now you can type and the text will go into the paragraph element and pressing enter at the end will close the current paragraph, insert a blank one and start a new one. Remember also that you do need to press enter at the end of the paragraph, even the last one, to get the tag to close properly.

To insert a paragraph between two existing ones, you want to do the same thing with the invisible blank paragraph element between two with text in. When you press the right arrow it will look like you are in the next paragraph with text, but you aren’t. Once you get to the end of your paragraph and hit enter all will be well again.

I feel like I am 90% of the way to being able to use WLW without switching to the source pane all the time – which is how you bloody well should be able to use it. It is just a bit unfortunate that I have to do it by being careful where I click and type and so on.

Gmail 2.0 and scrolling in IE7

Gmail’s new version 2 interface might be a slight improvement visually, but it sure does not like Internet Explorer 7 very much.

If you use the scrollbar at all the cpu usage for iexplore.exe gets pegged to 100% for a couple of seconds. I have not looked into what it is actually doing yet – not interested enough perhaps. If you switch back to the old interface (there is a link up on the top right of the page) the problem goes away. The only hassle is that this setting is not saved, the next time you log in you are back to the regular interface.

Curiously if you scroll with the keyboard it works fine. Scrolling with the scroll wheel or the edge of the touchpad hangs it up too. Seems to be in the handling of the onScroll (or whatever) event.


[Edit] It seems to be a problem with FlashGet. Disabling the FlashGet GetFlash Class makes the problem go away. Interestingly enough FlashGet still seems to work just fine…

Remote debugging

Yesterday I had quite a bit of fun trying to get remote debugging of a web application working.

I did solve this problem a little (very short) while ago… but I forgot what I had done.

So after executing a couple (quite a few) iterations of a Modify, Compile, Deploy, TryToDebug, Uninstall loop I know what you have to do to get it working. At least if you are using a deployment project to put the files up on the server.

You have to add the debug output from any project that you want to debug into to the deployment project*.

You must make sure that those debug outputs are in the right directory in the File System configuration pane so that the TargetName will have the files going into the correct directory on the server**.

Then you can install and debug. The setup of the remote debugger is a bit complex too. Basically the way I got it to work was by adding my own domain user (I log into my machine by logging into the domain) to the Administrators group on the server, and then logged in (via mstsc /console) to the server as myself (so that user could reconnect back to my machine). Bingo.


* You can’t just copy them up to the server it seems. I don’t know what the difference is, but it just does not manage to find them. I have even tried loading the symbols from the modules window directly – if complains that the symbols are not for the same version of the dll. I have not seen what happens if you are not actually deploying with an msi – there could be trouble. It is just one of those cases where there is some mechanism there that is storing some information somewhere and when it works everything is rosy, but when it does not work it can be fairly opaque. I guess that is what comes from not technically knowing what you are doing, but we can’t all be experts on the internal workings of everything – there is just not time, and when most of the time it just automagically works there is not much point either.

** The target name for the debug output of some project types (e.g. ASP.Net Web Application) will be bin/AssemblyName.pdb so the output needs to be placed in the Web Application Folder (where they seem to go by default), whereas other types (e.g. Class Library) will just be AssemblyName.pdb so their output needs to be put into the bin folder – they won’t be there by default, they will be one level up in the Web Application Folder. If you do not get this right the debug symbols will fail to load. You can look at information about what is being loaded from where in the Modules window found in Debug > Windows > Modules when you are in debug mode.

Tuesday, February 17, 2009

Lotsa windows

I just had a weird occurrence… I was in gmail, clicked to archive a message, and it started to open a bunch of new windows with one certain address:
http://mail.google.com/mail/#..&remote_iframe_0@2&1&0&%7B%22s%22%3A%22resize_iframe%22%2C%22f%22%3A%22remote_iframe_0%22%2C%22c%22%3A0%2C%22a%22%3A%5B199%5D%2C%22t%22%3A%22r0rtgf-lsmnyy%22%7D

It got to about 20 or so before I managed to kill it with taskman.

Monday, February 16, 2009

Security.dll

I was getting a funky error when trying to call one of my WCF web service’s methods:

Unable to find an entry point named 'FreeCredentialsHandle' in DLL 'security.Dll'.

Fortunately my brain is working this morning and I remembered the last time I saw this kind of odd error. Looking in the bin directory of the web site, sure enough I see a dll called security.dll. Ruhroh… IIS kindly loads up any dlls that you ask it to, then when it tries to access the Microsoft Security.dll it seems to find your dll and routes calls into it. These entry points (normally) don’t exist hence the error.

The moral of the story is: Do not call your dll security.dll*.

I just went through the whole project and made sure that the outputs were called something useful like Company.Project.Thing.dll. You do need to restart the web server too so it will reload the (correct) Security.dll.


* Other bad names are probably things like System.dll, mscorlib.dll etc. A much better idea is to create a proper namespace for your code and make the assembly name something like the namespace – or even the whole namespace, why not? Knock yourself out.

Sunday, February 15, 2009

Reuse types in a Web Service

For some time I have trying, with no success, to get the Reuse types in referenced assemblies option to work after adding a web service reference to a project.

Finally I have found the answer: That option is not available for so called ‘legacy’ ASP.NET web services, only for WCF web services. So I just re-created my web service as a WCF service. My web service is a pretty simple one providing access to a .NET Remoting server hosted in a windows service. As such the code is pretty simple, and it was a matter of less than an hour to get it all going.

Just one small gotcha that I guess should be pretty obvious. The assembly with the types that you want to re-use must already be referenced in the project that you are adding the service reference to. I.e. it does not go and look for them. I don’t suppose it would have any way of doing that.

The only modification that I had to do was to the web service. It seems to work. I am a little surprised that I did not have to add the DataContractAttribute to the classes to use them… They are already marked Serializable and the members are XmlElements… perhaps that is why it works. I have not really tested it yet, just compiled the service and the client. I am thinking now that perhaps the data is not being passed at all. Will see tomorrow – when I am supposed to be working (rather than now, the weekend).


[Edit] I does work just fine. I wonder then what is the difference between using DataContract and just making them Serializable. I also wonder what is the benefit of using the ClientFactory rather than just using the Client object directly.


[Edit] There are, it seems, times when you do need to add the DataContractAttribute to your data classes. I just found that one class that I was using as a parameter caused an exception upon serialization:

There was an error while trying to serialize parameter http://tempuri.org/:Commands. The InnerException message was 'Type 'BSPG.Prism.Script.Table' with data contract name 'Table:http://schemas.datacontract.org/2004/07/BSPG.Prism.Script' is not expected. Add any types not known statically to the list of known types - for example, by using the KnownTypeAttribute attribute or by adding them to the list of known types passed to DataContractSerializer.'.  Please see InnerException for more details.

This class contains members whose type is also not a standard class. The class that was working only had members of standard types. Fortunately, it seems to work if you just decorate the top level class with the DataContractAttribute – no need to go and change each other class in there (this would have been quite a pain for me, as they are all generated classes). That said, it might turn out that it only works because after the first level they are all standard types… That is not necessarily true for all possible data though – this is a class hierarchy created by XSDObjectGen from a quite deeply nested DOM… We will see.

Saturday, February 14, 2009

Batteries

The battery meter on my laptop is playing up.

It seems to think the battery is always at 100%. The hours remaining displayed changed, and seems to be about correct, but the percentage is always at 100%. I am guessing that that is why it keeps shutting off with no warning. Hrm.

I had other stuff to post, but I am at 100% (18 minutes) so I butter go plug in.

Wednesday, February 11, 2009

Merging Help files

This may take several minutes...

Boy you are not kidding… Why does this always take so long? And why can’t you do it in the background? I don’t need the help right now, but I would like to do something else with my machine.

Changing the console font

You can add new fonts to the list available in the cmd.exe preferences screen.

First you want to find a good mono-spaced font like Consolas and install it.

Then you need to add a new String Value to the registry under HKLM\Software\Microsoft\WindowsNT\CurrentVersion\Console\TrueTypeFont called 00* with a value of the exact font name (eg Consolas)

Something needs to happen before the font can be used, I am not sure what, but a reboot achieves it (logoff does not), so a reboot is next.

Finally, you can pop open a command prompt and change the preferences to use the new font. You might need to do this a couple of times if you use different ways of getting up a command prompt: the run command, the shortcut in accessories, or a shell extension - because of the way the system applies the preferences according to window title and not the actual executable.


* the default TrueType font is specified by 0, so the next needs to be 00, if you want to add another you can add 000 etc.

AdSense JScript error

I don’t know wether it is just IE7 or what but I do seem to be getting a lot of JScript runtime errors on lots of different sites… I have opened a few in the debugger and found them to be, for the most part strangely, coming from within jQuery…

Now the AdSense stuff on this blog has started to have an error:

The bit where it barfs is:

<script>tick('1ad')</script>

with:

Object expected

so meh, not finding the tick function. I have not changed anything, but I am beginning to wonder if it is not something that I have done to this machine. Perhaps I am just paranoid, but I do seem pretty capable of some kind of voodoo against windows installations…


[Edit] S’not just me - there are some posts on the AdSense Help forum (which has a JScript error, haha) about this already (Recent Javascript Errors in Ads, Javascript errors, JavaScript error <script>tick('1ad')</script>) but no response from Google so far...


[Edit] Silently fixed by Google. I did not keep a copy of the offending source file from this morning, but looking at the same file generated just now, they seem to have totally removed the call to tick. That function by the way ends up injected into your main page and seems to be for storing timestamps for certain actions like the first load, the first time the page is scrolled, the load time of each ad etc.) Poor form really… perhaps an explanation will surface soon.

Tuesday, February 10, 2009

Multiple selection

I was watching someone the other day trying to select a number of different files from a directory to copy somewhere else. She had about four goes at it, control clicking on each file she wanted, skipping over the ones she didn’t, then accidentally clicking without holding control somewhere and undoing all of her selections, before she gave up and copied them one at a time.

Just now I was trying to move some gmail ‘suggested contacts’ to ‘my contacts’. I had never used that interface before, but I don’t like it. You select each contact by checking its checkbox, but for some odd reason they have made clicking on the name of the contact select the checkbox also – and unfortunately deselect all of the other ones! The nice thing, usually, about a list of checkboxes is that they avoid the accidental de-selection that is so easy with the control click way of doing things…

This all has just reminded me that it would be nice to have an explorer extension that made selecting multiple files more forgiving. Maybe by altering the selected state in a more robust way. You could do undo and redo of selection, you could do add to and subtract from selection, you could keep selections or save and re-load them… you could make it usable. As it is, it is just about inevitable that someone not hugely skilled with the mouse will loose all of their selections if they are trying to select a non-trivial number of files together.

SQLServer 2005

Having failed to install SQLServer 2008 – don’t ask, I grabbed the 2005 dvd and ‘installed’ it… But the server setup could not find any of the client msi files. I looked at the directory structure on the disk and where they used to have Server and Client directories, there are now Server and Tools. I am not sure if that is the problem but I went into the Tools directory and ran the setup there. It got some way through its install, but still could not find the msi for the native client, and the ‘workstation, books online and development tools’ installer would not run. So I went spelunking in the \Tools\Setup directory and ran a few msi files by hand and now it seems to be happy.

Yay, I have my SQL Server Management Studio!

The msi installers that actually managed to do something were: \Tools\Setup\sqlncli.msi and \Tools\Setup\SqlRun_Tools.msi though there may be other stuff missing… we will see.

TortoiseSVN right drag

I did not know this: http://tortoisesvn.net/most-forgotten-feature

SVN global ignore pattern

I have just been fiddling with my global ignore pattern so I thought I would post it here (more for my future self than anything else). This modification was triggered by my having fun trying to use the same repo from two different machines where the directory structure is not identical, so the *.suo files and *.user files can cause problems. I also noticed that there were a few other odd files in the repo that I don’t really want.

[Bb]in [Oo]bj Debug Release *.suo *.user _UpgradeReport_Files UpgradeLog.XML RECYCLER Thumbs.db Desktop.ini

So a little explanation:

  • [Bb]in [Oo]bj – directories containing build files generated by studio, seems like older versions of studio create the files in all lowercase where 2008 has an initial cap and as SVN is case sensitive you unfortunately need to deal with both
  • Debug Release – directories created when building a deployment project
  • *.suo *.user – user project setting and general studio user settings files
  • _UpgradeReport_Files_ – directory containing log files and stuff created when you migrate a project from an older version of studio
  • UpgradeLog.XML – the main project migration report file
  • RECYCLER – not sure if this is still needed, but I was finding this directory sometimes gets created, I guess it is for storing deleted files… was just searching for it in the repo local copy but could not find it, oh well
  • Thumbs.db Desktop.ini – files created when you do certain things in explorer, like look at a directory of images in thumbnail view

Monday, February 09, 2009

Office Live

I have a new install of Microsoft Office Word 2007 with the Office Live plug-in installed. The Office live splash screen comes up and I was having trouble configuring it – it could not seem to deal with my Live account that had a Gmail address… anyway, that is sorted now (though all my cookies are gone in the process), but the splash screen still comes up each time. I thought it was because the sign-in process was failing, but I am all set up now and it is still showing up every time I open word.

Fortunately I have found the solution on TechNet: Get Started with Office Live.

The workaround is to create a registry key called OfficeLive under the key HKEY_CURRENT_USER\Software\Microsoft.

Group policy

I hate that the group policies specified for our domain accounts have the Internet Explorer home page locked down, and the web proxy enabled. Those settings though are just registry entries, and as there is no inherent security on registry editing, you can just go back in and edit them after login.

After some time interval though I have noticed that there must be a gpupdate or something that resets the keys to the values defined by the policy. I just wrote a quick VBScript to ensure that my preferred settings are made after login.

Set shell = WScript.CreateObject("WScript.Shell")
 
shell.RegWrite "HKCU\Software\Microsoft\Internet Explorer\Main\Start Page", "http://www.google.com.au", "REG_SZ"
shell.RegWrite "HKCU\Software\Microsoft\Internet Explorer\Main\Default_Page_URL", "http://www.google.com.au", "REG_SZ"
shell.RegWrite "HKCU\Software\Microsoft\Internet Explorer\Main\Search Bar", "http://www.google.com.au", "REG_SZ"
shell.RegWrite "HKCU\Software\Microsoft\Windows\CurrentVersion\Internet Settings\ProxyEnable", 0, "REG_DWORD"

Most of the time when I pop open IE it is to go to Google. Plus the group policy had some stupid HP news site specified, and several times over the last week their first displayed news story was some model in a state of partial undress – difficult it is when the company policy enforces a breach of company policy…

Sunday, February 08, 2009

WLW Plug-in

I just finished working on a Windows Live Writer plug-in to allow insertion of snippets. You can define templates for snippets that you can then insert into the current document from the Insert list. The snippets can be anything basically, but I will be using it to insert HTML snippets of the right format to make error message blocks, command line blocks, basically all of the little bits of mark-up that I want to re-use all of the time.

To create a new template you access the options dialog via Tools > Options > Plug-ins where you select the Snippet plug-in and click Options.

You can insert the currently selected text or the clipboard contents into the template by specifying #content# or #clipboard# somewhere in the template. You can also take the content or the clipboard if the content is blank with #contentorclipboard# or the reverse with #clipboardorcontent#.

There is no documentation (other than the info here), no installer (you just need to copy the dll file to C:\Program Files\Windows Live\Writer\Plugins), and not too many features. So hopefully not too many bugs. There are a few things that I would like to work on: A context menu to select the #content# things; Pretty up the interface a bit; Add a different mode that can ask for user input to fill in the template; An installer.

I created a Google Code project for this one too, it is wlwsnippetplugin. I think that I have put the source up properly in the SVN repository… Regardless, the source is zipped there too, as is the SnippetPlugin.dll file that you can just grab and copy to the right directory.

Enjoy!

Mark-up cleanup

I have just spent some hours going through all of my old posts and editing them in WLW to get all the mark-up nice and neat and how Blogger and WLW likes it.

I have put everything in p tags, removed all of the display oriented tags (fonts, inline classes), and fixed up the code and error message and command text blocks that I had. I think I fixed most of the quote marks and apostrophes too - mainly because WLW does it automatically and they do look pretty neat.

I guess that is all a bit anal, but I do feel clean now.

Friday, February 06, 2009

Erm… ForEach

Why did I not see this before? I was pretty sure that I looked for a ForEach function before I went off looking for Map etc… but bugger me if there isn’t an extension method on IEnumerable(Of T) that does just exactly what I want.

It’s even called ForEach!

List<thing> myList = new List<thing>();
myList.ForEach(item => item.DoSomething());

[Edit] Okay, I feel a little better now… I know why I didn’t see it before - ForEach is defined on List(Of T) and not, unfortunately, on IEnumerable(Of T) which is where I was looking for it. Perhaps next week in a spare moment I might get to try my hand at writing it.

Select method problems…

An issue that I have run into using Select as Map HOF.

The Select function is only evaluated when the returned Enumerable(Of T) is evaluated. That means that the code that I posted (which I did not test until now…) does not really do anything. I guess that means that the foreach method is probably the way to go for calling a function for each item in a list.

Thinking about this, and re-reading some information about the Map function, I come to the realisation that it is perhaps my understanding of what Map is supposed to do that is incorrect. It does say that map is for transforming the items. Perhaps what I want is another, slightly different HOF that is for operating on a list of items, i.e. calling a function for each of them, rather than for building a second list. Oh I don’t know, I will keep looking.

Windows Live Writer first paragraph problem

I was having trouble with WLW messing up the mark-up for the first paragraph when I start a new blog entry.

Once I had typed the first paragraph then pressed enter, rather than starting a new paragraph tag after the first, it inserted a new one in the first one before the text. After that the paragraphs come up in pretty much the right order, but the nesting is all wrong and not at all what you would want.

Here is an example of the mess that it manages:

<p>
  <p>Second paragraph.</p>
 
  <p></p>
Third paragraph.
 
  <p>First paragraph.</p></p>

What you want really is this:

<p>First paragraph.</p>
 
<p></p>
 
<p>Second paragraph.</p>
 
<p></p>
 
<p>Third paragraph.</p>

I have finally worked out what was causing this. It was the fact that I was clicking in the edit area before typing! So if you edit the title, you need to NOT click in the post body area, you can just hit Enter after you are done with the title and it seems to work.

Unfortunately, clicking will have bad effects on the mark-up whenever you do it in a blank area… You need to be clicking in an existing paragraph or else it seems to get a bit stuffed up. I am still trying to work out exactly which action causes which problems and hot to possibly avoid them. One is to paste in the html for a paragraph with some text in it rather than clicking at the end of a post to add a new paragraph. This is a beta product though so I guess one is meant to deal with quirkiness.

Another related note: you really have to hit Enter at the end of a paragraph, even the last one. If you don’t you can end up with:

<p>Paragraph 1.</p>
 
<p></p>
Paragraph 2.
 

I like WLW. I am sure there is not much more to go before it is kind to your mark-up. The sad thing is that this kind of stuff is probably not that important to a lot of people.

Thursday, February 05, 2009

foreach to LINQ to HOF progression

Three stages of a real world example.

protected virtual string ReplaceFunctions(string messageTemplate) {
    string messageBody = messageTemplate;
    Regex ex = new Regex(@"\$(?<name>[^\$]+)\$");
    MatchCollection functions = ex.Matches(messageTemplate);
 
    foreach(Match function in functions) {
        if(function.Groups["name"].Success) {
            messageBody = messageBody.Replace(string.Format("${0}$", function.Groups["name"].Value), "");
        }
    }
    return messageBody;
}

protected virtual string ReplaceFunctions(string messageTemplate) {
    string messageBody = messageTemplate;
    Regex ex = new Regex(@"\$(?<name>[^\$]+)\$");
    MatchCollection functions = ex.Matches(messageTemplate);
 
    foreach(var function in (from Match f in functions where f.Groups["name"].Success select f)) {
        messageBody = messageBody.Replace(string.Format("${0}$", function.Groups["name"].Value), "");
    }
 
    return messageBody;
}

protected virtual string ReplaceFunctions(string messageTemplate) {
    string messageBody = messageTemplate;
    Regex ex = new Regex(@"\$(?<name>[^\$]+)\$");
    MatchCollection functions = ex.Matches(messageTemplate);
 
    functions.OfType<Match>().Where(function => function.Groups["name"].Success).Select(function => messageBody.Replace(string.Format("${0}$", function.Groups["name"].Value), ""));
    
    return messageBody;
}

C# Map HOF goodness

The Map higher order function is provided in C# as the Select extension method.

So to cover the last step that I was going on about this morning, i.e. to transform this:

foreach(var field in (from field in TheForm.Fields where field.Disabled select field)) {
    field.DoSomething();
}

We can use method syntax (fluent) rather than query syntax to give the one liner:

TheForm.Fields.Where(field => field.Disabled).Select(field => field.DoSomething());

Neato!

Incidentally though, this seems to only work when DoSomething returns a non void. For example, if you try to compile:

TheForm.Fields.Where(field => field.Disabled).Select(field => Console.WriteLine(field.Name));

You will get an error:

The type arguments for method 'System.Linq.Enumerable.Select<TSource,TResult>(System.Collections.Generic.IEnumerable<TSource>, System.Func<TSource,TResult>)' cannot be inferred from the usage. Try specifying the type arguments explicitly.

This is pretty easy to fix though by changing the expression lambda to a statement lambda:

TheForm.Fields.Where(field => field.Disabled).Select(field => { Console.WriteLine(field.Name); return true; });

Windows Live Writer and Blogger formatting

I think I have it worked out.

There is a Blogger setting that stuffs up edits done with Live Writer. Settings > Formatting > Convert line breaks needs to be set to No. Then you don’t seem to get the double line spacing.

The trick with WLW seems to be to let it put in paragraph tags and to never ever edit the post in blogger. Or at least to never switch between the blogger html editor and the compose editor – that really screws things up.

In the end, WLW is still in beta so there are issues. Undo does not do what I would expect. You can’t just type away and press enter to get a new paragraph… Seems like for the first paragraph you have to hit enter then the down arrow otherwise the insertion point is above the first paragraph container. Odd.

I will just resign myself to being careful with the editor, then being prepared to fix the mark-up by hand.

The CodeSnippet pug-in works best if you do not embed the styles but copy them to your template to be re-used. That is how I wanted to do it anyway. Here is a little code snippet:

// Check for required fields
foreach(var f in from f in TheForm.Fields
                 where f.RequiredForEmail
                 select f) {
    prop = requestType.GetProperty(f.Name);
    if(prop == null || prop.GetValue(data, null).IsBlank()) {
        Ok = false;
        break;
    }
}

Query pattern problem

I have been getting this error with some LINQ expressions:

Could not find an implementation of the query pattern for source type 'System.Text.RegularExpressions.MatchCollection'. 'Where' not found. Consider explicitly specifying the type of the range variable 'v'

You get this error because MatchCollection implements only IEnumerable and not IEnumerable(Of T) All you need to do is change:

from v in ex.Matches(template)

to:

from Match v in ex.Matches(template)

I.e. do what it says and specify the type of the range variable.

CodeSnippet plug-in

Dammit. Those code snippets look so nice in Live Writer… grr. They get all sorts of horrible linebreaks and the formatting does not work at all. Work dammit!

Explorer:

Live Writer:

Grumble.

LINQ expression syntax

I have been recently starting to use LINQ expression syntax a little more. One refactoring that I have been doing is changing things like:

foreach(SomeItem item in items) {
    if(item.SomeProperty == someValue) {
        item.DoSomething();
    }
}

into the slightly nicer:

foreach(var item in (from i in items
                     where i.SomeProperty == someValue
                     select i)) {
    item.DoSomething();
}

… My only hesitation is the nastiness of the syntax (if you try to get it inline with no extra variable definitions – yes I know the extra parentheses are not required, but I find var item in from i in items to be very unreadable, plus I am often adding method syntax to these things at a later stage)… Some syntactic sugar might be nice to get:

foreach(var item from items                                      
                 where item.SomeProperty == someValue                 
                 select item) {
    item.DoSomething();
}

There is probably also a higher order function way to do this for simple cases of just calling one function on each match, but most of the time the code is not as simple as a single method call. Ideally I would love to do something like:

(from i in items where i.SomeProperty == someValue select i).Map(DoSomething);

P.S. Do not like the new Windows Live Writer editor. I just want an editor that makes it easy to create nice neat mark-up! Why is it so difficult to NOT put in paragraphs and other containers that I don’t need? And why can’t I see them in edit mode? And why do I drop out of the edit container and then have the backspace key delete the whole container?

Friday, January 30, 2009

WindowsUpdate

Installing Studio and stuff on my new desktop (laptop is almost officially dead) I was having a problem with Microsoft Update...

The website has encountered a problem and cannot display the page you are trying to view. The options provided below might help you solve the problem.

The error code is 0x8007000B. Looking in the WindowsUpdate.log shows:

WARNING: DownloadFileInternal failed for http://download.windowsupdate.com/v8/windowsupdate/b/selfupdate/WSUS3/x86/Other/wsus3setup.cab: error 0x8007000b

So I tried to download that file in ie and get:

Access to http://download.windowsupdate.com/v8/windowsupdate/b/selfupdate/WSUS3/x86/Other/wsus3setup.cab has been blocked by WebMarshal

Ah ha!

(P.S. I don't remember the blogger editor being this bad... the format of this post is terrible right now.)

[Edit] Formatting maybe fixed...

Thursday, January 29, 2009

Lambda expressions

I just used a lambda expression for the first time. They are neat!

Friday, January 02, 2009

Gunner gunner

I was going to write about some things that I am going to do this year... but I think that kind of thing might be part of the problem... Gonna neva duzzit. So I'm not gonna right nuffink.

I will say though that I have changed something. As in already, it is done. Not going to be done, not only started, but done. I changed the template. They all pretty much suck though so I am going to... no wait. Scratch that. Let's leave it at they suck.

I realise that I have now screwed up the code snippet thingy but too bad. I just wanted a change. What do I need to look for in a template?

  • Quote callouts must look nice
  • Code samples
  • Picture and Video posts must look nice
  • Simple, block oriented
  • Should use my own images not generic ones