Posted by: Terry Nederveld | August 12, 2011

S.O.L.I.D. by Terry

One question that was asked of me each time I interviewed the last time I switch careers was: “What is S.O.L.I.D.?” Each posting in this series will highlight one area of the S.O.L.I.D. principles. If you are here reading my blog because you are a friend or family member that is not a software developer you probably have not heard the acronym before. S.O.L.I.D. is a set of principles that are used to create great object-orientated software applications. For a detailed definition you can find one at the following link: http://tinyurl.com/3xxzlff

  1. S – Single Responsibility Principle
  2. O – Open/Closed Principle
  3. L – Liskov Substitution Principle
  4. I – Interface Segregation Principle
  5. D – Dependency Inversion Principle

This series may not come in order since I don’t end up blogging that much. But I will eventually finish the series, I promise! Each time I post an entry to this series I will update the list above with links to that principle’s article.

Happy Coding!

Advertisements
Posted by: Terry Nederveld | July 29, 2011

MvcContrib DataList fix

While working with the MvcContrib DataList the other day I noticed a problem. Here is how I found the issue. I had a collection that contained 3 items and everything was hunky-dory. I had my view setup with the following code for the DataList.


@Html.DataList( Model.GroupBy( g => g.CategoryTitle ) ).NumberOfColumns( 3 ).CellTemplate( x =>
{ Write( new MvcHtmlString( "<ul class="links"><p>" + x.Key + "</p>" + x.Each( @<li><a href="@(item.Item.LinkResourceType.ToLower().Equals( "report" ) ? Url.Action( "Viewer", new { Id = item.Item.LinkId } ) : item.Item.LinkUrl)" @(item.Item.OpenInNewWindow ? "target="_blank"" : "")>@Html.Raw( item.Item.LinkContent )</a></li> ) + "</ul>" ) ); } ).CellAttributes( valign => "top", width => "33%" )

Here are a few finer details about of the code above.

  1. The DataList control uses the table Html element to lay its self out.
  2. It is set to 3 columns.
  3. Since the repeat direction is not set, it will use vertical repeating (the default).
  4. Since we don’t want the default table alignment of middle, each cell in the table will have the “valign=”top” width=”33%”” attributes appended to each <td>.
  5. .Each() is a HelperResult extension. It was detailed by Phil Haack on his blog at http://haacked.com/archive/2011/04/14/a-better-razor-foreach-loop.aspx

Life was good and my items were showing up fine and dandy, until I added a fourth item to my collection. And I received:

Index was out of range. Must be non-negative and less than the size of the collection.

I added another item and the message went away. Then it came back again this time it was when I added the seventh item and again on the tenth item. I was seeing a pattern, so forked the CodePlex project and attempted to clone the repository locally in order to fix the issue. Turns out I could load the software to access the projects but when it came to actually using it to connect to the repository our proxy, firewall or something was blocking me from accessing the fork. So I ended up just downloading the entire source as a ZIP from my fork and proceeded to debug it.

I quickly came to the section that’s used when the repeat direction is vertical. Below is what the code originally looked like.

 private void RenderVertical(int repeatColumns, IList <T> items)
 {
 	int rows = CalculateAmountOfRows(items.Count, repeatColumns);
 	int columns = repeatColumns;

 	int i = 0;

 	for (int row = 0; row < rows; row++)
 	{
 		Write("<tr>" );
 		for (int column = 0; column < columns; column++)
 		{
 			if (i + 1 <= items.Count)
 			{
 				if (column == 0)
 					RenderCell(items[row]);
 				else
 					RenderCell(items[((column * rows) + row)]);
 			}
 			else
 				RenderNoItemCell();
 			i++;
 		}
 		Write("</tr>" );
 	}
 }

Ok, so first up it calls the CalculateAmountOfRows method to get the number of rows it needs. Which for a collection that contains 4 items and number of columns set to 3, it will return 2 rows. Trust me it works properly. From there it starts building the output. Can you see the problems? I’ll give you a hint 🙂

Still having a hard time seeing what the issue is? Let’s walk through the loops and do the math. Remember we have a collection that has 4 items in it so we will need two rows. Below is a visual representation of what the DataList method above will output. Did you see the problems? Look closely at Row 0, Column 2. Is the “i+1” code less than or equal the items.Count? Yes it is, so it tries to render the cell. When it renders the cell it tries to do so with items[4], Does the collection have an item at an index of 4? You are correct, no it doesn’t. In a zero-based collection the highest index for our collection would be 3. And this is where the code throws the lovely message we saw above. So we throw a quick fix in that checks to make sure that the index we are looking for is not higher than the count of items in our collection. Tada! It works or so it seems. If you run the new code you would see the following cells rendered (0,0), (0,1) and (1,0). Where is the fourth item? Well if we step back and forgo the obvious fix earlier you will notice that even if the code wouldn’t throw the out-of-range error, it wouldn’t ever show the forth item because the “i + 1” at (1,1) would be 5 and the test against the item.Count would fail and it would run the RenderNoItemCell code. So now that we found the issues, how do we fix it? Well that was actually pretty easy. I just needed to look at the index to make sure it was within the bounds of the collection before attempting to render the cell. And when actually laying out how it works I realized that we didn’t need to +1 the “i” and check against the items.Count. The desired behavior only needs the “i” checked. Here is what I changed the method above to in order to fix the issue. 

 private void RenderVertical(int repeatColumns, IList <T> items)
 {
 	int rows = CalculateAmountOfRows(items.Count, repeatColumns);
 	int columns = repeatColumns;

 	int i = 0;

 	for (int row = 0; row < rows; row++)
 	{
 		Write("<tr>" );
 		for (int column = 0; column < columns; column++)
 		{
             if (i <= items.Count)
             {
                 int index = (column == 0 ? row : ((column * rows) + row));
                 if (index < items.Count)
                     RenderCell(items[index]);
                 else
                     RenderNoItemCell();
             }
             else
                 RenderNoItemCell();
 			i++;
 		}
 		Write("</tr>" );
 	}
 }

I have updated my forked version of MvcContrib and will submit a pull request for them to bring in the updated code.

Thanks, until next time… Happy Coding.

Posted by: Terry Nederveld | February 24, 2011

Lytebox Community Take Over

Folks, today I created a project on GitHub for the Lytebox code. Since it hasn’t been updated since 2007 by Markus, I figured it was time that the community take over. With the pending release of IE9 I wanted to get ahead of the game instead of finding out this code no longer works again. I will be updating my IE to 9 probably today and will start testing to make sure that the last fix I implemented still works.

I believe that we have one HUGE thing that we need to do before we can start working on enhancements or anything else. And that is:

WRITE TESTS

I personally don’t have any experience with writing tests for JavaScript. So I am open to suggestions. What to use? How to do it? If you want to spear head this email me your GitHub username and I will add you as a contributor.

You can find the project at: https://github.com/tnederveld/Lytebox

I look forward to working with you all on making Lytebox the best that it can be.

Posted by: Terry Nederveld | February 16, 2011

EditorTemplates, DataAnnotations and Telerik, Oh my.

Lately I have been having some real fun using EditorTemplates, DataAnnotations and Telerik. So I decided it was time to share my experience. To start off let me tell you what versions I am using:

  • Visual Studio 2010 Ultimate
  • ASP.NET MVC3 RTM
  • Telerik Extensions for MVC Q3 2010 SP1

Let’s begin by creating a new MVC project. Select “ASP.NET MVC Web Application”.

After clicking “Ok” a new window introduced with MVC3 will appear. This is where you choose the project template, view engine and if you want to create a unit test project. For this sample I am choosing the “Internet Application” and the “Razor” view engine. If you haven’t used the Razor view engine, I suggest you try it out. I found that once you use it and get pass the urge to use <% %> it is actually faster typing.

Once it has finished creating your project you should have a Solution that looks very similar to the image on the right. If you hit F5 right now, it will build and run your new MVC3 site. Before you do that we have to add a few things in order for Telerik to work. If you don’t have the Telerik controls for .NET you can download the open source version from their website. I am using the same version as the open source one 2010.3.1318.

The controls are installed now we can finish adding the few items to the solution in order to get Telerik working with our project. First, I always go through Windows Explorer and navigate to the “Program Files (x86)\Telerik\Extensions for ASP.NET MVC Q3 2010”, if you are not using a 64bit OS it will be in “Program Files”. From there I will go into the “Content” and “Scripts” folders and copy the “2010.3.1318″ directories to those areas of my project. “Content\2010.3.1318” is copied to the “Content” and “Scripts\2010.3.1318” is copied to the “Scripts”. That is where the Telerik().ScriptRegistrar() and the Telerik().StyleSheetRegistrar() will look first for the files it needs.

Next add a reference to the Telerik DLL. Remember to select the correct DLL for the version of MVC you are using. Since this post is using MVC3, I will be selecting the MVC3 version of the Telerik controls. You can find the DLL in the Telerik folder under your program files inside the directory called “Binaries”. You will see three different folders under that one.

Some of the following are just ways that I prefer to do things, try them out maybe you will enjoy it. First up, I always create another project that will hold constant variables, formatting functions, and etc. I call it my “Core”, so I will add a new Class Library and name it “TelerikEditorTemplates.Core”. Then I will add my data access layer (DAL), I like to call it “Infrastructure”. Following in the previous steps footsteps, add a Class Library and name it “TelerikEditorTemplates.Infrastructure”. This sample project is not going to have any database associated with it. Now you may be asking yourself, why he does that. Well the answer is: I separate them out because if I need to make a change to the formatting that a function is doing or change a constant variable, there is no need to completely recompile the actual site, I can just recompile the specific project and push that DLL to the server. Once those two projects are created go ahead and “Add Reference” to them.

In the essence of time, leave the AccountModels.cs in its current project. Remember that the AccountModel.cs is not a complete membership provider, which is why I always roll my own version of it.

Moving on to the code, there is a few items that I always do with an MVC project most of which are added to the “_Layout.cshtml”. New to MVC3 and Razor then you may be asking: What is _Layout page?

You typically want to maintain a consistent look and feel across all of the pages within your web-site/application.  ASP.NET 2.0 introduced the concept of “master pages” which helps enable this when using .aspx based pages or templates.  Razor also supports this concept with a feature called “layouts” – which allow you to define a common site template, and then inherit its look and feel across all the views/pages on your site.

~ Scott Gu’s Blog (link here)

Now that you know what the _Layout page is. I always add a couple of @RenderSection sections to my _Layout page. These sections help me organize my view code into the right spots on the page when it is rendered out to the browser. The one thing that I can tell you here is: make sure to use the override that has the required parameter. Especially if the section won’t always have something to render from the view.

For the Telerik controls to work we must add several things to the _Layout page. First, in the <head/> section of the page we need to add the Telerik StyleSheetRegistrar. Below is the code used to get the default CSS. Telerik has many options to choose from for styles. If the default style is not what you want all that is needed to change is “telerik.default.css” to which ever style floats your boat.

Another item that is needed for the Telerik controls to work properly is the ScriptRegistrar. Telerik suggests that it is the last thing before your closing body tag. Remember you will need to tell it not to load jQuery if you are already including it in the head section of the page.

Moving on, wait all is not right? You are not able to see Telerik when you type @Html? That’s because we need a using statement. Try adding the following code to the top of the _Layout page. Does it work now?

Once all the items that needed to be in the _Layout page are added it’s time to create the model for whatever it is we want to do. For this post let’s create a model for a simple Contact form. That should be very straight forward. We’ll need the following: Name, Email, Subject, and Message. In the Core project we can create the an Interface object that will control what is needed in the Model.  Again, in the sample project I will show you how I normally create it for now go ahead and create a folder called “Models” in the Infrastructure project. This is where the model for the contact form will live. After you have created the folder right click it and select “Add -> Class” and call it “ContactFormModel.cs”. We will need to make it a public class in order for it to be used so go ahead and change that now. Go ahead and copy and paste the following into your class file.

 

 namespace  TelerikEditorTemplates.Infrastructure.Models
 {
     public  class  ContactFormModel 
     {
         public  string  Name { get ; set ; }
         public  string  Email { get ; set ; }
         public  string  Subject { get ; set ; }
         public  string  Message { get ; set ; }
     }
 }

 

After you add that to your class file make sure the project gets built. If it doesn’t, then when you go to create your view it will not show up in the Model Class combo box. Now open the HomeController.cs file and add a new ContactUs method. You can copy and paste the code below into your controller.

 

 public  ActionResult  ContactUs()
 {
     var  model = new  ContactFormModel ();
     return  View(model);
 }

You will need to also add a using statement to the “TelerikEditorTemplates.Infrastructure.Models” in order for this to compile properly.

Now we add a new view that will be rendered when someone accesses “/contactus”. This process is very easy, right click inside the ContactUs method and from the context menu go ahead and select “Add View” and it will open the “Add View” dialog. The view name will be automatically populated with the name of our method; if you change it you would need to specify in your method what view you want it to return. Check the box next to “Create strongly-typed view” and it will allow you to select a model for the view. One of the good changes with MVC3 is that this now shows the model names (ContactUsModel) instead of the fully qualified names (TelerikEditorTemplates.Infrastructure.Models.ContactUsModel). Go ahead and start typing the name of the model into the combo box. Now, before clicking “Add” choose the scaffold template “Create”.  Also, if you are not using a _ViewStart.cshtml file then you will need to select the _Layout page. Your dialog should look like the following image:

Once you click “Add” it will create the new view “/Views/Home/ContactUs.cshtml”. Before we can run the project we need to do one more thing. We need to add a link to the page in the _Layout page. Go ahead and find the _Layout page, it should be under the shared views directory. Open the file and add <li> element to the menu area with @Html.ActionLink(“Contact Us”, “ContactUs”, “Home”) as the inner text.

Finished adding that to the file? Good, go ahead and press F5 and it will build and run the project.  When it opens in your browser click the “Contact Us” item and it should look like the following:

Doesn’t quite look like a contact form does it? Let’s spruce it up a bit. From MVC2 to MVC3 Microsoft made another change that happened when the view was created, did you notice it? They no longer use Html.TextBoxFor(model => model.Name) anymore, instead Html.EditorFor(model => model.Name) is used. This was changed so we can utilize DataAnnotations in order to control what is outputted for each property type from the model.

Let’s go ahead and add some DataAnnotation attributes to the model properties. Before that can be done there must be a reference to System.ComponentModel.DataAnnotations and System.Web.Mvc in our Infrastructure project. Remember to get the correct version of the MVC DLL located in your Program Files. The first DataAnnotation we will add to the model is the “Display” attribute. The model should look like this:

If the “Display” doesn’t show up as an option in your intellisense more than likely the “using System.ComponentModel.DataAnnotations” statement was missing from the class file. Once you have all the display attributes added press F5 and navigate to the page in order to see the changes.

Did you notice that the labels have changed but we didn’t even touch the view? Have you seen a contact form that didn’t have any validation associated with it? No, me either. With that in mind our next DataAnnotation attributes to add will give us control over which properties of the model are required. To make a property required we only need to use the attribute [Required]. Instead of using the default required message add “ErrorMessage=” to the attribute to control the message displayed to the end user. An example would be [Required(ErrorMessage=”My message here”)] .

Along with labels and required fields there are many other attributes that can be used. Two attributes that control what is rendered to the browser are: [DataType] and [UIHint]. With MVC3 we now also have an easy way to allow a single property the ability to allow Html code without receiving the dreaded “Potentially unsafe characters” message. That attribute is [AllowHtml], it is not a part of DataAnnotations attributes. It was introduced in the MVC3 library. In order to use it there must be a using statement to System.Web.Mvc in the class file. I have gone ahead and added all the attributes we are going to use on our model, you can view the new additions below:

After these additions have been added to your model press F5. When you are on the ContactUs page go ahead and click the “Create” button. The validation has been automatically added to the view. It should look like the following:

Look at that, without even having to touch the code in the view our site now has validation. Now we are going to touch on another subject and it will involve Telerik and EditorTemplates. Before we can dive into it a directory needs to be created. In my humble opinion I like to have all the editor templates that for site wide use in the Shared folder under Views and if it is specific to a certain controller you can put it under that controllers directory in the Views folder. For now we are going to put this under the Shared folder. Go ahead and create the directory “EditorTemplates” under the Shared folder. Once that is created, right click and select “Add View” name it “Html”. Once it has created the view. We will want to remove all the code from it and replace it with the following code:

After that code has been saved in the “Html.cshtml” file. Go ahead press F5 and navigate to the ContactUs page. If all goes well you should now see the Telerik HTML editor on the page.

Now that you have base knowledge for creating an EditorTemplate with the Telerik controls you can actually create any type you need. In the past I have used EditorTemplates for rendering controls to input currency, date/time, email, and etc. Experiment with them and it won’t take long for you are hooked by the power of DataAnnotations and EditorTemplates.

You may click here to download the sample project.

Posted by: Terry Nederveld | February 15, 2010

How to do a Column Layout in SQL Reporting Services.

For this post I am using the following:

  1. Visual Studio 2008
  2. SQL 2008 Reporting Services
  3. The Query for the reports dataset is as follows:

DECLARE @tmp TABLE(
Display VARCHAR(25)
)


INSERT INTO @tmp (Display) VALUES ('Test 1')
INSERT INTO @tmp (Display) VALUES ('Test 2')
INSERT INTO @tmp (Display) VALUES ('Test 3')
INSERT INTO @tmp (Display) VALUES ('Test 4')
INSERT INTO @tmp (Display) VALUES ('Test 5')
INSERT INTO @tmp (Display) VALUES ('Test 6')
INSERT INTO @tmp (Display) VALUES ('Test 7')
INSERT INTO @tmp (Display) VALUES ('Test 8')
INSERT INTO @tmp (Display) VALUES ('Test 9')
INSERT INTO @tmp (Display) VALUES ('Test 10')
INSERT INTO @tmp (Display) VALUES ('Test 11')
INSERT INTO @tmp (Display) VALUES ('Test 12')

SELECT * FROM @tmp

This post will guide you through how to get a columnar layout with SSRS like the images below.

 

Accomplishing this is actually an easy process once you can figure out the solution. I hope this post will help you spend less time than I had to. After you have your Dataset created on your report. All you need to do is drop a Matrix control onto the report. The magic happens in the actual row and column group. Let’s start with the Row group. You will need to right click on the row and open up the Row’s group properties. In the Group Expressions you will need to add a “Group on” if one doesn’t already exist. You are going to add the following expression to that group on.

=Ceiling(RowNumber(Nothing)/2)

The following are the descriptions that Microsoft wrote for common functions we used above.

Ceiling: Returns the smallest integer greater than or equal to the specified double-precision floating-point number.
RowNumber: Returns a running count of all rows in the specified scope.

What the code above does is it takes Dataset and basically looks at each of the rows and gives it a number. If you just did RowNumber(Nothing) it would count up 1,2,3,4, etc. for each row. The number you divide by is the amount of columns you want in the layout. For this example we will start with 2 and later I will show you the group expressions to accomplish the three column. Now this alone will not give you the results you desire. You now have to look at the Group Properties for the column group. This time you will right click on the column and go into the Group Properties for this. Just like the row you will need to add a “Group on” expression if one doesn’t exist and inside it you will need to add the following expression.

=(RowNumber(Nothing) Mod 2)

The description given by Microsoft for Mod is: Divides two numbers and returns only the remainder. Most developers have used the Mod function in the past when they wanted to alternate the color of the rows in a table they were creating with code. It is a little different then changing the color of the row this time it is telling which column the data should be in. This is how we get the layouts show in the images above. Very simple and it works.

Now I said that I would show you how to get the three column layout. Well, it is really easy and you should have already figured it out. Just go into the Group On expressions and change the two to a three.

=Ceiling(RowNumber(Nothing)/3)
=(RowNumber(Nothing) Mod 3)

Posted by: Terry Nederveld | January 12, 2010

Question: ASP.NET Window Authentication Mode

Windows authentication mode in ASP.NET used the Active Directory “Group name (pre-Windows 2000)” and I don’t understand why. Here is the background. I had an .NET MVC v1.0 project that I was trying to secure it by using Windows authentication mode. So I set the web.config to:

<authentication mode="Windows" />

And then went into my controller and did the following:

[Authorize(Roles="IT")]
public class LicenseController : Controller

In AD we have a group called “IT” and I am many others are apart of this group. Once I had this in place I started a debug session and tried going to any of the actions in that controller and I was met with a 401. I search high and low looking for somewhere that I had screwed the pooch and couldn’t find anything wrong. After a while of struggling I decided to try changing the “Authorize” to a specific user an see if that worked. So I changed it to the following:

[Authorize(Users="domain\tnederveld")]

And low and behold that worked. So I went and added a different group that I was a member of and took out the users authorize statement and that worked. I started looking into the differences between the two AD groups and the only thing that was different was on the second group I tried the “Group name (pre-Windows 2000):” were the same. The “IT” groups “Group name (pre-Windows 2000):” was “IT Associates”. So I tried changing the authorize statement to:

[Authorize(Roles="IT Associates")]

And it started working. I thought for sure this was an MVC issue, so to make sure I tried it on a regular Web Forms project and was meet with the same issue.

The real kicker is that when you use the UserPrincipal that is part of the System.DirectoryServices.AccountManagement it returns the group “IT” when using the .GetGroups() method.

Anyone know why this is happening? Along with posting it on my blog I have also posted this on StackOverflow (http://bit.ly/7UnDkU).

Posted by: Terry Nederveld | November 16, 2009

Silverlight 3 DataGrid Sorting

A little disclaimer before we go any further. Incase this doesn’t work for you, I am using Silverlight 3, .NET 3.5, RIA Services (July 2009 Preview). Moving on.

I had a task that I was trying to accomplish that lead me around in circles. A client requested that they could sort a list of tasks. So I thought what a better opportunity to take a look at Silverlight. I know, I know it is a little overkill for a simple ASP.NET DataGrid. But I wanted to learn something new. So off I went. Full steam ahead until I remembered a few things.

  1. Of course the new requirement of being able to sort.
  2. The task are using AJAX every 2 seconds to show any status changes.

So the first one was easy, setup up the .NET RIA services and in code did the following:

ServiceContext _entities = new ServiceContext();
PagedCollectionView pager;

public MainPage()
{
    InitializeComponent();
    LoadGrid();
}

private void LoadGrid()
{
    _entities.Load<Status>(_entities.GetStatusQuery());
    _entities.Load<User>(_entities.GetUsersQuery());

    LoadOperation loadOp =
        _entities.Load<Event>(_entities.GetTaskQueueQuery());
    loadOp.Completed +=
         new EventHandler(LoadTasks_Completed);
}

private void LoadTasks_Completed(object sender, EventArgs e)
{
    pager = new PagedCollectionView(
           _entities.Tasks.ToList<Task>()
           );

    dgTasks.ItemsSource = pager;
}

 

The code above populated the grid just fine. Now how do I go about getting the data into the grid every 2 seconds like the current ASP.NET page does. After searching for different ways to do it, the way that came up the most was adding a Timer into the project. I added the following code below the “LoadGrid()” call in the MainPage() function.

System.Windows.Threading.DispatcherTimer t =
    new System.Windows.Threading.DispatcherTimer();
t.Tick += new EventHandler(TickEvent);t.Interval = new TimeSpan(0, 0, 2);
t.Start();

Now I needed to add the TickEvent function.

private void TickEvent(object sender, EventArgs e)
{
    LoadGrid();
}

After I inputted that code, I went and tested it and it worked great. Until, the dreaded until, I clicked one of the headers to sort the data. Rock on it worked! Oh wait, when it refreshed the data in the grid it lost the sorting. Crap!

Ok before I freaked out to much I started looking and looking and looking and couldn’t find anything. So I went to sleep and woke up the next morning (today) and started searching again. I found a ton of stuff with really long ways to do it but I wanted something that was quick and worked without having to recode any Collections or Lists. Then I happened upon the answer, well a forum post that lead me in the right direction.

It said to use a INotifyCollectionChanged to set the CollectionChanged event on my PagedCollectionView. So I added the following code to my LoadTask_Completed event.

INotifyCollectionChanged sortchangeNotifier =
     pager.SortDescriptions as INotifyCollectionChanged;
sortchangeNotifier.CollectionChanged +=
     new NotifyCollectionChangedEventHandler(SortChanged);

Along with adding the code above I went and added the SortChaned event.

public void SortChanged(object sender,
     System.Collections.Specialized.NotifyCollectionChangedEventArgs e)
{
    // Do what you like here.
}

Now once you have this in place you use the EventArgs (e) to look at what is going on with the DataGrid. You will see an Action property that will be one of the following: Add, Remove, Replace and Reset. Since I need to preserve the sorting done by the end user I decided that I needed to store that information and then added it back into the DataGrid whenever it was refreshed. So I declared a new variable just under the PagedCollectionView.

SortDescriptionCollection sortOrder;

Then I added the following code to the SortChanged event.

if (e.Action == NotifyCollectionChangedAction.Add)
{
    SortDescriptionCollection sort = new SortDescriptionCollection();
    for (int i = 0; i < e.NewItems.Count; i++)
    {
        sort.Add(((SortDescription)e.NewItems[i]));
    }
    sortOrder = sort;
}

The code above looks to make sure the action that is taking place is an Add to the sort collection. Then it loops over the .NewItems and adds them to the sortOrder collection. Now that we have the sorting stored in our variable we need to apply them to the PagedCollectionView.

At first I just tried assigning the sortOrder variable to the PagedCollectionView.SortDescriptions (pcv.SD) property but discovered it does not like that. So I had to add them via the pcv.SD.Add(SortDescription) method. So below is the code that I used. I have the code in my LoadTasks_Completed event.

if (sortOrder != null)
    foreach (SortDescription sd in sortOrder)
    {
        pager.SortDescriptions.Add(sd);
    }

So first I check to make sure that the sortOrder collection is not null. If it is then I do nothing to the PagedCollectionView.SortDescriptions. The sortOrder will be null on the initial load of the application.

One thing that you can’t do is you can not add the code above after you have applied the INotifyCollectionChanged. Trust me. My final code ended up looking like the following:

using System;
using System.Collections.Generic;
using System.Linq;using System.Net;
using System.Windows;using System.Windows.Controls;
using System.Windows.Documents;using System.Windows.Input;
using System.Windows.Data;using System.Windows.Media;
using System.Windows.Media.Animation;using System.Windows.Shapes;
using Cliffs.Events.WebInterface;using Cliffs.Events.WebInterface.Models;
using System.Windows.Ria.Data;using System.Collections.ObjectModel;
using System.Collections.Specialized;using System.ComponentModel;

namespace Tasks.Silverlight
{
    public partial class MainPage : UserControl
    {
        ServiceContext _entities = new ServiceContext();
        PagedCollectionView pager;
        SortDescriptionCollection sortOrder;

        public MainPage()
        {
            InitializeComponent();
            LoadGrid();

            System.Windows.Threading.DispatcherTimer t = new System.Windows.Threading.DispatcherTimer();
            t.Tick += new EventHandler(TickEvent);
            t.Interval = new TimeSpan(0, 0, 5);
            t.Start();
        }

        private void LoadGrid()
        {
            _entities.Tasks.Clear();

            _entities.Load<Status>(_entities.GetStatusQuery());
            _entities.Load<User>(_entities.GetUsersQuery());

            LoadOperation loadOp = _entities.Load<Task>(_entities.GetTaskQueueQuery());
            loadOp.Completed += new EventHandler(LoadTasks_Completed);
        }

        private void TickEvent(object sender, EventArgs e)
        {
            LoadGrid();
        }

        private void LoadTasks_Completed(object sender, EventArgs e)
        {
            pager = new PagedCollectionView(
                   _entities.Tasks.ToList<Task>()
                   );

            if (sortOrder != null)
                foreach (SortDescription sd in sortOrder)
                {
                    pager.SortDescriptions.Add(sd);
                }

            INotifyCollectionChanged sortchangeNotifier = pager.SortDescriptions as INotifyCollectionChanged;
            sortchangeNotifier.CollectionChanged += new NotifyCollectionChangedEventHandler(SortChanged);

            dgTasks.ItemsSource = pager;
        }

        public void SortChanged(object sender, System.Collections.Specialized.NotifyCollectionChangedEventArgs e)
        {
            if (e.Action == NotifyCollectionChangedAction.Add)
            {
                SortDescriptionCollection sort = new SortDescriptionCollection();
                for (int i = 0; i < e.NewItems.Count; i++)
                {
                    sort.Add(((SortDescription)e.NewItems[i]));
                }
                sortOrder = sort;
            }
        }
    }
}

 

Thanks, I know that this will come in handy for myself if I forget how to do this. But I truly hope that it will help you.

Posted by: Terry Nederveld | September 4, 2009

An Adventure in jQuery

It has been a while since my last post and I hope you all are doing well. I have been waiting for a topic to hit my like a ton of books. And as you can see one has hunted me down. So here we go…

Those of you that are not a part of the internet industry may be saying to your self, “What is jQuery?” Well jQuery is a lightweight JavaScript library that helps with the interaction between the traditional JavaScript language and HTML. It first debuted in 2006 at BarCamp NYC by John Resig. It is open-source which means its FREE!!!

Now if you just read that paragraph and said, “Huh?? What is he talking about.” Stop reading now and wait until my next post about a non-technical issue. Moving on.

Recently I was reading a post by someone or listening to a Podcast (honestly, I don’t remember) and the person said that there are many different JavaScript libraries out there and that you should pick one and learn all there is to know about it. He also said that his choice was made for him by Microsoft because they have decided to build jQuery into Visual Studio 2010. So I figured it’s about time to jump in and start learning jQuery. The next project that came on my plate was getting jQuery added to it so it would force me to learn it.

First thing I ran into, the project I am working wants an image to be the background of the site. As we all know, if you just set the background to the image it doesn’t work out the way we really want it to. So we take the image and place it in a DIV that sits behind all the other content on the screen. Only problem here is that because of the images ratio you can run in to issues with it not showing properly on all different size screens. And thus, in comes JavaScript. The old way that I would have accomplished this was like so:

function resizeImg(){
     var w = 0, h = 0;
     if( typeof( window.innerWidth ) == 'number' ) {
         //Non-IE
         w = window.innerWidth;
         h = window.innerHeight;
     } else if( document.documentElement && ( 

document.documentElement.clientWidth || 

document.documentElement.clientHeight ) ) {
         //IE 6+ in 'standards compliant mode'
         w = document.documentElement.clientWidth;
         h = document.documentElement.clientHeight;
     } else if( document.body && ( document.body.clientWidth ||

 document.body.clientHeight ) ) {
         //IE 4 compatible
         w = document.body.clientWidth;
         h = document.body.clientHeight;
     }
     document.getElementById("backgroundImage").style.width = w;
     document.getElementById("backgroundImage").style.height = h;
 }

 I would have put this JavaScript inside a script block in the head of the HTML page. Then I would set the onLoad and onResize on the body tag, just to get the image to resize to the browser. Now we will look at how to accomplish this with jQuery.

First thing that we should talk about is this ‘$’ thing that jQuery coders always seems to use. Well that ‘$’ is a critical concept for jQuery. It is the alias for the namespace. So instead of having to prefix your code with jQuery you can just use the dollar sign. Cool, I don’t have to type as much.

Next on the list of things to understand are the jQuery Selectors. It is very similar to CSS. And instead of me recreating the wheel I am going to point you to a very good cheat sheet that someone pointed me to. To get the sheet follow this link: http://refcardz.dzone.com/refcardz/jquery-selectors.

Ok, let’s move on. jQuery also has some really neat things built into it, you will see a few of them in the code below. The following code will go into a script block right before your closing body tag.

$(window).ready(function(){
     $('img#backgroundImage').css("height",$(window).height());
     $('img#backgroundImage').css("width",$(window).width());
};

$(window).bind('resize',function(){
    $('img#backgroundImage').css("height",$(window).height());
    $('img#backgroundImage').css("width",$(window).width());
};

 

That was simple. But wait, is that code optimized? No. So before continuing, think about how we could optimize this code. Got it? Good. Let’s see if you would have done it the same way I would have.

function resizeImg(){
     $('img#backgroundImage').css("height",$(window).height()).css("width",$(window).width());
}

$(document).ready(resizeImg);
$(window).bind('resize',resizeImg);

I am not saying that my way is the best, I am still learning this also. If yours was different don’t beat your self up too much, put it in the comments below and let’s see who can come up with the most optimized way of doing this.

As you noticed in the code above there we can get the height/width of the window by just calling .height() or .width() on the window. jQuery automatically figures out what browser you are using and returns the correct size. Amen to that! 

You probably also noticed how I got the correct image, I didn’t need to do any of those document.getElementBy… stuff that is needed in traditional JavaScript. Same goes for the setting the size styles, I didn’t need to use “.style.width=”.

If you are like me and didn’t jump in to jQuery when it first hit the scene don’t worry to much about it and start learning it now. You can even go back through your old projects and see if there are better ways to accomplish the JavaScript tasks in jQuery.

Until next time.

Posted by: Terry Nederveld | August 6, 2009

Working Remotely

I know that there are a bunch of you that work remotely from your homes and I know some of you wish you could. Currently, I commute to my office over 40 miles away. There are some days that I wish I could go back to the 30 second commute but most days I am happy to be in an office. To give you a little background, two years ago I took a position that required me to be in the office every day. Before that I worked remotely for more than 5 years with a company that wasn’t even in the same state that I lived in. And I was not a contractor, I was a full fledge employee.  Most people when asking what I did for a living would say “Oh, you work from home? Gosh that has got to be nice.” Well sometimes it is, and sometimes it’s not. To be able to work from home every day you have to be very disciplined. Can’t get distracted to easily, and trust me there is a ton of things around to pull you every which way. Some people never understood that I worked for an actual company because that company didn’t have  a local office. Here are my tips that helped me work from home for so long.

Make sure you have a separate office away from the living area of the house. I found that if I used a laptop and roamed the house working. I would work 12, 14, even 16 hours without even knowing it. Granted that was a good thing for my employer, but not so great for my family. Keep them as separated as possible.

If you are a consultant you may not be able to do this. But I highly suggest that you have a computer that is dedicated solely to work and one for personal. Don’t have any personal items on the work computer and vice versa. That work machine is property of the company you are working for, it is not yours. I guess that is good advice even if you are in an office.

Make sure you have a reliable internet connection. This will allow you to VPN, remote desktop, and operate as though you were in the same building as everyone else. For the longest time I had DSL with 756KB down from the local internet company. It wasn’t until recently that company bumped the connections up to 5MB.

Interaction is good, you don’t realize it until you are away from it. But those little interruptions from co-workers stopping by help break up the day. If the company can, setup an extension that routes directly to your home/office/cell phone. And use it.

Make sure that you are accessible. Even though you have a lot of freedom, you don’t want your manager to be trying to reach you at 9AM and you are at your kids school (unless you told him before hand).

Do not have a TV in your office. I know some people that are able to have it going in the background. But you never know when Doctor Phil is going to have on the one handed blind teacher that slept with one of her students and whoops there goes an hour and you didn’t even know it. I always had speakers on my desktop machine and had a plethora of music to listen to.

Keep track of your home office expenses, at least in the USA you can put it on your taxes and get a little break from the big green monster (US government). We will pay taxes until we die and even some after here in America, so keep track because you can write off almost everything related to your home office. I must also say, I am not a tax accountant! You can’t say to the IRS, well Terry said so.

Find your rhythm, everyone has those optimal hours that they work well. Mine is surprisingly early. I find now that my most productive time is early in the morning. When I worked from home it was late at night. Find your time and you will be ecstatic from the amount of work you will get done in that time frame.

And sometimes you are not working from home but are traveling. Make sure  when you are traveling you have your: laptop, power supply, and network cable. Always carry a network cable, some hotels still don’t have wireless throughout the entire place and the only way to get connected is through a network cable. And most of those hotels charge for you to use theirs.

I  am sure that there is more items that you will think of. Feel free comment them below.

Posted by: Terry Nederveld | July 17, 2009

Where has technology led us?

Has it helped or hindered us? In some aspects I believe that it has hindered us. For instance, I bet if I asked my ten year old what an encyclopedia is, he will probably reply. “Is it like Wikipedia?” It is scary how dependent this new generation is on computers and the internet. Heck, I remember when there was no …

… Email, Facebook, Twitter, and MySpace. You had to write letters! If you were not happy with a companies product you had to actually write a letter to them. Now you can Email, Twitter, Facebook, and use MySpace to tell millions not just the company about how poor their product is. When was the last time you actually wrote a letter? Not typed it on the computer and printed it, but actually sat down and broke out a pen and some paper. I can’t even remember the last time.

… Online Stores. In order to buy something you had to actually get into the car, drive through traffic, try to find a parking spot, aimlessly wonder around the store, find the item and then deal with getting the item home and installed. Now if I want something I can go and use my favorite search engine to find the best price then click to the specific online store, find exactly what I was looking and get the item sent directly to my front door. 

… Kindle. This one kind of goes hand in hand with online stores. Before Kindle and online stores in order to get a book, you had to go to the book store. And if you didn’t want to purchase it, you could go to the library and borrow the book. If they didn’t have it at your local library, they could request it from another library in the county. Now, I can go online order a book and have it instantly delivered to my Kindle (if I had one).

…Online Banks, Bank Account Software, and Debit cards. In order to know how much money you had, you actually had to keep a register and make notes about all the purchases you did. You had an ATM card that only worked at an actual ATM. If you wanted to make a purchase you had to either use a cash, check or credit card. And get this, you had a monthly statement that was mailed to you (not emailed) that’s sole purpose what to reconcile your register. There was not software that would do it for you automatically, and the only real-time view of your accounts was that register.

Tivo or DVR. If you wanted to record a TV show, you had to break out the video tapes and program that VCR or be there when the show started. None of this setting a series to record and the machine would automatically record all the episodes. If you wanted to stay current on a show, there was some work to it.

I can’t help but feel as though these new technologies have taken away something from us and from generations to come. We used to live much simpler lives. It is funny to think that not so long ago we were all happy without these things. Now granted there are some things that have helped us, especially in the field of medicine. And for those of you that do not agree with me about how it has hindered us then you should have no problems giving them up.

I do know that this list could go on and on and on… feel free to continue the list in the comments section.

Older Posts »

Categories