Sunday, 15 February 2009

Off Topic: Vista on Mac

I’ve been quite busy the last week, since I’ve changed employment. I now work with a small consulting firm where I might get the opportunity  to develop my own ideas in the future.

With this new employment I’ve got an IPhone and new new computer, which I decided to be a MacBook! People who knows me are wondering if I lost my mind, because I’ve always ranted about Mac. Well, I have not loosed  my mind, of course I’ve installed Windows on the computer. Now I have a dual-boot computer so that I can develop IPhone apps, and maybe an IPhone app for Invitational Tour!

I installed Windows Vista 64bit so that I can use all the 4GB of memory installed in the MacBook. It all worked fine at first, but my computer started to freeze more often than I have the patience for. And with freeze I mean a total freeze, no messages or log items, the only way around it is to do a hard reset of the computer. (Hold down the power button for a couple of seconds.)

I have experienced this with my desktop PC a few times, but not so many times that it really bugged me. But with the MacBook it wouldn't last more than 30 minutes before it froze. I started to suspect that something was wrong with the hardware, but then I noticed that the computer froze when I browsed the Internet. So I googled for this problem on my other PC, and it turns out that there are a lot of people having this problem. After I read a lot of blog posts and forum posts, I did not get a hands on solution to the problem, some stated that there was a problem with the video drivers, some had problems with the touch pad and some had other driver problems. A few mentioned the wireless network driver. So after a couple of hours searching for a solution, I got tired of browsing the internet and disabled the wireless network connection and hooked a cable between my router and the computer. That seemed to help, my MacBook has not frozen for in the last 24 hours!

This works fine while I’m at my home office, I dread for the moment when I have to be mobile with my computer, but that is a problem to be solved then.

Labels: , ,

kick it on DotNetKicks.com

Saturday, 24 January 2009

How to center a listview column in Grid mode

This one I’ve really struggled with. I have a lot of listviews in the application, and basically I love listviews in WPF, but as I wrote earlier, the downside of having total control is that you must control everything…

I have some columns that I wanted to be centred. Actually, this is not very easy. I’ve used Goggle a bit, but mostly I’ve read the MSDN documentation and now after three hours of testing I’ve come up with a solution. I’m not really satisfied yet, but it will work for now.

First I thought that there would be some sort of HorizontalContentAlignment property I could set. But there isn’t any there for columns. So I started to style the column in the listview that I want to centre like this.

<Style x:Key="OnlineHeaderStyle" 
               TargetType="{x:Type GridViewColumnHeader}" 
               BasedOn="{StaticResource 
TournamentColumnHeaderStyle}"
> <Setter Property="HorizontalContentAlignment" Value="Center"/> </Style> <DataTemplate x:Key="OnlineCell"> <DockPanel> <TextBlock Foreground="DarkBlue" HorizontalAlignment="Center" TextAlignment="Center"> <TextBlock.Text> <Binding Path="Publish" Converter="{StaticResource
converterBooleanTextConverter}"
/> </TextBlock.Text> </TextBlock> </DockPanel> </DataTemplate>

This should do it I assumed, but it wasn’t enough. I also had to set a style for the ListView.ItemContainerStyle, like this:

<ListView Name="lv_Tournaments" 
   View="{StaticResource GridViewTournament}">
   <ListView.ItemContainerStyle>
     <Style TargetType="ListViewItem">
      <Setter Property="HorizontalContentAlignment" 
Value="Stretch" /> </Style> </ListView.ItemContainerStyle> </ListView>

This has to be done because the Dockpanel, or all containers for a column cell has some sort of auto size, so if the cell is 100px wide, but the text of that cell if only 20px wide, the text container will be only 20px, and the textontainer is some how aligned to the left, and even tough the content is centred, it appears as left aligned, but with the HorizontalContentAlignment of the ItemcontainerStyle set to stretch the textcontainer will have a width of 100px, and the text will appear as centred. As i wrote in the beginning, I’m not total happy with this solution, but it is good enough for now. I can get it better, and will write about it then, and I also think that Microsoft has some things to develop regarding the Listview.

Labels: ,

kick it on DotNetKicks.com

Returning an empty list and Null Continued

Ok, you live and learn. In my earlier post I wrote that I wanted to return null Lists when getting tournaments for an owner.
For example, the functions List<Tournament> GetTournamentsByOwner(Guid ownerGuid) should return NULL if no tournaments where found for that owner in the database. This is wrong, in this case.
First of all, I'm doing this project as a hobby project, and one of the reasons for doing this project is to challenge standard ways of doing things, and instead start with a new, and empty, mind set of how things should be done. I stand corrected, but I still think that in many cases it depends. It is not a given rule all the time. Obviously I have some learning to do about how, and when, I write about stuff in this blog, but I was also wrong about some things. After I read the comments, and answered to them, I continued to discuss this issue with a former colleague of mine.  And I also thought about this when I was out on the pub and have a few beers with my girlfriend and our friends.

So my conclusion is this, regarding the former post, and how I will handle it as standard way in the application, but there will be exceptions to that! When I discuss with my former colleague we usually don't settle with arguments as "it is the standard". We want to change the standard. I don't make any stakes that I change the standards, but I want to remind my self while doing this project why a standard is a standard, and how and if it can be evolved. When a function that returns a List<T>, like List<Tournament> GetTournamentsByOwner(Guid ownerGuid) and that functions doesn't have any items, it will return an empty List, not NULL! In this case I was wrong.
When a function returns an entity, like Tournament GetTournamentByGuid(Guid tournamentGuid) and that entity is not found, it will return NULL. My conclusion was that a function that returns a list, is a search function in a way. GetTournamentsBy.. actually searches for a set of tournaments, and if no tournaments are found, a search results is returned, with  zero elements. So you might see it like that function returns a search result, not a list of tournaments.

But if I call the function GetTournamentByGuid(Guid tournamentGuid) , I expect a specific tournament, and if this tournament does not exists, NULL will be returned. Some people would argue that I should return a Tournament object with empty values, but I think that is a bad idea. Because I would rather check for NULL than check for the state of the object if it is a real entity or a "placeholder". So in that perspective I rather "break" the standard of never returning NULL.

Labels: ,

kick it on DotNetKicks.com

Friday, 23 January 2009

Returning an empty list or null?

In my data access classes, which is using Linq2Sql I have functions like GetAllTournamentsByGuid().
A Tournament is a set of competitions in golf, see www.invitationaltour.com if you want to know what this project is all about.

Well, at first I wrote the test for this function, from a TDD perspective, like this;

The test is pretty straight forward, it saves two tournaments to the database with a specific owner, created earlier, then it calls the data layer and tries to get these two tournaments from the database.

[Test]
 
public void CanGetAllTournamentsByOwner()
{
  //Save two tournaments to db
  User owner = tournament.Owner;
  dataManager.SaveTournament(tournament);
  dataManager.SaveTournament(tournament2);
  
  //The actual test
  System.Collections.Generic.List<Tournament> tournaments = 
   dataManager.GetTournamentsByOwnerGuid(owner.Guid);
 
  Assert.That(tournaments.Count,Is.EqualTo(2));
  
  //Clean up is performed in the teardown routine
}

This test works well and passes when run, but what if there are no tournaments in the database, what if I want to get tournaments for a owner that does not have any tournaments? Should the function return an empty List<Tournament> or null? Or should the function return a Boolean value telling the caller if the call to the database was successful and the returning List as an output parameter or as a ref List?

I have struggled with this question for a long time during the development of various systems, and I have two ground rules, which are them self fights with each other.

1) Never throw exceptions if not needed.
Exceptions are resource intensive, compare to regular code. If you know that something can go wrong you should be able to create code that prevents that error, with validation etc. I’ve started to reconsider this rule. If the system I’m building is not that performance intensive. But I still apply this rule through out my systems.

2) Don’t return null.
Actually, I’ve adopted this rule while reading the book Clean Code by Robert C. Martin (Uncle Bob) where he writes that functions should never return NULL. Well, I’m starting to disagree.
The book states very clearly that the book is not the law, it is a book about clean code and suggestions, and there is nothing wrong with making other rules than stated in the book, so this is not a flame about the book, I love that book!

I’m rambling again….. Back to the problem

What if the function doesn’t return any tournaments? Should i return an empty List<Tournament> with a count of 0? I think I’ve decided that the return value should be NULL. The main reason for that is if this function is called via a service, a NULL value is less to serialize than an empty List of Tournaments.

What if an exception occurs? Well, I will re throw it in the function, but wrap the exception in an own exception class, which is better for serializing. This will make up the signature for the core function of gettournaments. It will be the callers responsibility to handle any exceptions.

What about returning a Boolean value indicating if the operation was successful. No problem! If I need a function that never throws an exception back to the caller I will create a wrapper function, but I will only make that function if I need it. One of the pillars in agile development is not to code functions until you need it, and it is also the third rule of TDD; only create code to pass the unit test. It also apply to the rule, from Clean Code, that a function should be responsible for one, and only one, thing!

So, to summarize:

- The functions that get entities from the repository will return null if no result aren’t found.

- The functions that get entities will throw exception if any thing goes wrong, it is the callers responsibility to handle exceptions.

- If a function is needed that doesn’t throw any exceptions, instead it should return a Boolean telling if the operation succeeded a wrapper will be created around the core getter function with an out parameter for the entity or the list of entities.

Labels: , , ,

kick it on DotNetKicks.com

Sunday, 11 January 2009

Unable to build in VS2008

I’m sitting and trying to resolve an error in my application. It is the handling of images from the database, to the WPF gui. I have written a post about this in Swedish which I will translate when I have resolved the problem I have now. But this post is not about that, this post is about the annoying  build error
Unable to copy file "obj\Debug\exe-file" to "bin\Debug\exe-file.exe". The process cannot access the file 'bin\Debug\exe-file.exe' because it is being used by another process.

I’ve tried several ways to get around this, but it seems to be very hard, especially when GDI+ is involved. But one thing I’ve found that helps is to first kill the process vshost.exe for the current project. (It will be directly restarted), then I choose Clean Solution under the Build menu in VS2008, then I can build the solution again. I think the trick lies in killing the vshost.exe process.

Labels: , ,

kick it on DotNetKicks.com

Saturday, 10 January 2009

Disable a toolbar button image in WPF

When I worked with winforms, it was very easy to disable a toolbar button image, just set Enabled=False and your were done. With WPF on the other hand, it is a little bit more complicated.

I love WPF! You can do everything you couldn’t to in winforms. You have total control. But the downside of having total control is that you must control everything. :-)

So, to disable a toolbar button with an image, which I do via application commands, use this following trigger.

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

And in the toolbar apply the style.

<Button 
 Name="btPlayersDelete" 
Command="commands:UserCommands.DeleteUsers" 
ToolTip="Delete players">
 
    <Image 
             Style="{StaticResource toolbarImageStyle}" 
             Name="imgPlayersDelete" 
Source="Images/Toolbar/delete.png"/> </Button>

Labels: ,

kick it on DotNetKicks.com

Friday, 9 January 2009

Localization in Asp.Net

Since I changed to English for this blog I realised that I had to change the language of the single webpage of www.invitationaltour.com.

So I took the chance of developing a “proof-of-concept” for localization, which actually was harder than I thought when you are using master pages in asp.net. Before I started I was sure it was only a matter of setting the currentuiculture of the current thread, since the page class has a property named Culture which can be set to change the culture for a page, but it was more to it than that. I did a simplified version of localization, and in the future I will make a more appropriate solution and will write a post about that solution. For now I just wanted to localize a single page, which are nested in a master page. The correct language should be determined by the browsers language settings. So, here it is.
First, I use the Localization control. You can use a literal control, they are exact the same, but the localisation control allows you to edit the text in design mode.

<h1>
    <asp:Localize 
    ID="Header1" 
    meta:resourceKey="Header1" 
    runat="server" 
    Text="Välkommen!"/>
</h1>

Välkommen is Swedish for Welcome, and Swedish is the default language for the site. This is the first word on the page at www.invitationaltour.com

Next I created a folder under my solution and named it App_LocalResources. Resource files under App_LocalResources are page specific, and resources in the folder App_GlobalResources  are application specific, and should be the place to store words that are used through out the application.

Next, I added a resource file to the App_LocalResources and named the file to Default.aspx.resx. Double click on that file and an editor i shown where you can add and edit localised words. This file has no culture info in it, so the words in this file will be the default language for the page.

Add a new item by typing Header1.Text in the name column, and the value for the text in the Value column. As you can see in my asp.net code, I’ve named both the ID and the meta:resourceKey to “Header1”. This is the way I want to do it, to keep the ID and resourceKey the same, but it’s up to you. The important thing is that the value for Name in the resource file corresponds to the value of meta:resourceKey. In the resource file you also typed .Text after Header1. This is the way to tell Asp.Net which property that should display the text. You can do it the same for buttons or other controls in the same way.

After you’re down, save the file. Now we will create a second language. Create a copy of the newly created resource file in the same directory, and rename it to Default.Aspx.en.resx. This is now the resource file for the English language. Double click the file to open it in the editor and change “Välkommen” to “Welcome”. Save the file.

Now, to let asp.net automatically  determine the language of the calling browser, add the following to your web.config file.

<system.web>
    <globalization culture="auto"  uiCulture="auto"/>

This will tell the asp.net runtime to set the culture for you, and if no resource file is found for the current culture, it will fallback to the words in the file Default.aspx.resx, which is Swedish. So If someone from France browses to this page, they will see the page in Swedish.
Normally, a French person wont understand Swedish, so I decided to add two language buttons in the upper right corner, one for Swedish and one for English. Now, it was here I thought it was just a matter of setting the currentUICulture on the current thread, but it’s more complicated than that. In the click event for each button, I have the following code in the master page.

protected void imgBtSwedish_Click(
object sender, ImageClickEventArgs e)
        {
            this.Response.Redirect("Default.aspx?lang=se");
        }

        protected void imgBtEnglish_Click(
object sender, ImageClickEventArgs e)
        {
            this.Response.Redirect("Default.aspx?lang=en");
        }

The above code actually just redirect the user the default page, with a query string specifying the chosen language.

I know that this is not the correct way of doing this, but it is good enough for just one page. When the web page gets more pages, this will not do it, then I will use the Profile class to set the languages, but more on this in a future post.

This is all the code that are needed in the master page, but in the default.aspx we have to put some code also, to actually set the language.

protected override void InitializeCulture()
{
            if (this.Request["lang"] != null)
            {
                //Swedish is the fallback language
                CultureInfo newCultureInfo = 
new CultureInfo("sv-SE"); switch (this.Request["lang"].ToLower()) { case "en": { newCultureInfo =
new CultureInfo("en-GB"); break; } } Thread.CurrentThread.CurrentCulture =
newCultureInfo; Thread.CurrentThread.CurrentUICulture =
newCultureInfo; } else base.InitializeCulture(); }

The above code overrides the InitializeCulture and checks if there are any language specified, and if so, sets is. Remember to call base.InitializeCulture() if you don't set the language your self, and NOT to call base.InitializeCulture if you do. The base class doesn’t do nothing extra than setting the culture as in this code.

There is much more to Localization than I have written about here, this post jus describes a very simple way to localize a single page with in a master page, in my case enough to display a localized “under construction” page. In the future I will user the Profile class and store language settings for a user in a database. The resource files are XML files, I am also on the search for some great editors. Because the way it is now in Visual Studio, the workflow does not encourage agile development, since I don’t want to open each resource file one at a time, remember the meta:ResourceKey and type the localized word. I want an editor where I can edit all languages at the same time! For now I make all in the default language, and the make copies of the resource file and edit them in the XML-editor, since the built in editor does not handle line breaks very well. To make copies of the resource files works well if you develop on page from top to bottom, and get done with it, but I don’t want to work that way.

Labels: , , ,

kick it on DotNetKicks.com