Saturday, June 20, 2009

Bing : Not a search engine, but decision engine??

I am an active contributor to the MSDN WPF Forums and most of the times I go to the forums through the search engine. And being an ardent supporter of Microsoft, I made Bing my default search engine on my home desktop. So I searched for “MSDN Social” and look what one of the sponsored result is!

image

seriously we are in the 21st century. And BING “decided” for me that I want to visit BAD GIRLS IN MY AREA! when all I wanted to do was to visit MSDN Social Forums. Bing – get a life.

Friday, June 05, 2009

GridViewColumn CellTemplate does not work?

Well, today I came across this interesting question on WPF regarding setting the DataTemplate of a GridViewColumn not working properly. Everything looks fine in the code (assuming his DataTemplate generating method was fine) which got me interested to figure out what the issue is.

And then I made up this sample application whose XAML is shown below.

<Window x:Class="Window1" 
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Title="Window1" Height="300" Width="300" Loaded="Window_Loaded">
<StackPanel>
<ListView Name="lv" ItemsSource="{Binding Items}">
<ListView.View>
<GridView></GridView>
</ListView.View>
</ListView>
</StackPanel>
</Window>


The code-behind is simple. It sets the DataContext to itself and then fetches sample data using GetData() call. Then the GridView for the ListView is obtained and a new gridviewcolumn is added programatically. The CellTemplate is set on the GridViewColumn using SampleTemplate() method. The SampleTemplate() method constructs a DataTemplate programatically using the FrameworkElementFactory class and returns the same.





 
Private Sub Window_Loaded(ByVal sender As System.Object, _
ByVal e As System.Windows.RoutedEventArgs)
Me.DataContext = Me 'set the datacontext
Items = GetData()
Dim gv As GridView = CType(lv.View, GridView)
Dim gvc As New GridViewColumn
gvc.Header = "Test"
'Display member binding
gvc.DisplayMemberBinding = New Binding(".")
gvc.CellTemplate = SampleTemplate()
gv.Columns.Add(gvc)
End Sub

Private Function SampleTemplate() As DataTemplate
Dim dt As New DataTemplate
dt.DataType = GetType(String)
Dim fef As New FrameworkElementFactory(GetType(TextBox))
Dim bd As New Binding(".")
fef.SetBinding(TextBox.TextProperty, bd)
dt.VisualTree = fef
Return dt
End Function

Public Property Items() As IEnumerable(Of String)
Get
Return GetValue(ItemsProperty)
End Get

Set(ByVal value As IEnumerable(Of String))
SetValue(ItemsProperty, value)
End Set
End Property

Public Shared ReadOnly ItemsProperty As DependencyProperty = _
DependencyProperty.Register("Items", _
GetType(IEnumerable(Of String)), GetType(Window1), _
New FrameworkPropertyMetadata(Nothing))

Function GetData() As IEnumerable(Of String)
Dim x As New ObservableCollection(Of String)
x.Add("Item 1")
x.Add("Item 2")
x.Add("Item 3")
Return x
End Function




And when I run the application all I see is …



image



Ok the binding works and I see my data but somehow the celltemplate is not being reflected. So, I was able to reproduce the issue the question presented.



So I dig around and looked in the documentation for CellTemplate where I found the following.



image



So it basically means that if DisplayMemberBinding is used, then CellTemplate would be ignored and so on with the CellTemplateSelector. So I comment the line that sets DisplayMemberBinding and run again.



image







Yes! its working as expected.



So whats the moral of the story? Actually there are three morals:



1. First of all, when using CellTemplate, do not set DisplayMemberBinding.

2. Refer to the documentation, especially the remarks and code samples section for a method or property. MSDN folks did an amazing job (ofcourse the WPF guys as well).


3. MSDN WPF Forums is amazing and overall Microsoft.NET folks rocks big time.

Thursday, June 04, 2009

What’s wrong with this code?

image

The breakpoint at line 18 never hits.

This is a really silly bug :D.

Leave comments if you know what is wrong.

.NET Funda : MemoryStream ToArray() vs. GetBuffer()

Look at the following program.

 class Program
{
static void Main(string[] args)
{
MemoryStream ms = new MemoryStream();
//write 10 bytes to the memory stream.
for (byte i = 65; i < 75; i++)
ms.WriteByte(i);

System.Console.WriteLine("MemoryStream.GetBuffer() : {0}",
ms.GetBuffer().Length);
System.Console.WriteLine("MemoryStream.ToArray() : {0}",
ms.ToArray().Length);

System.Console.WriteLine("GetBuffer() BytesToString : {0}",
FromBytesToString(ms.GetBuffer()));
System.Console.WriteLine("ToArray() BytesToString : {0}",
FromBytesToString(ms.ToArray()));

ms.Close();
System.Console.WriteLine("GetBuffer() BytesToString : {0}",
FromBytesToString(ms.GetBuffer()));
System.Console.WriteLine("ToArray() BytesToString {0}",
FromBytesToString(ms.ToArray()));
}

public static string FromBytesToString(byte[] b)
{
return ASCIIEncoding.Default.GetString(b);
}
}


In the above code, we use a MemoryStream and write 10 bytes (from A(65) to J(74)).  Running the program gives the following result.



image



The first two print statements displays the length of the byte[] array returned by both GetBuffer() and ToArray(). Now, both these methods returns the byte[] written to the memory stream but the difference is that GetBuffer() returns the allocated byte buffer used by the memory stream and this also includes the unused bytes where as ToArray() returns only the used bytes from the buffer.



Since a memory stream is initialized with a byte array of size 256, even though only 10 bytes have been written to the stream, the buffer returned is of size 256 (of which only 10 bytes are used). Printing the Bytes to string, thus displays a long series of empty lines where as ToArray() returns only 10 bytes that were used and displays the string exactly of size 10.



Note that both these methods work even when the stream is closed (demonstrated by the last two print lines in the code above).



The usage becomes important especially when you are trying to perform in-memory deserialization of some object from the memory stream for reasons like the binary data would be totally different from what was written actually, when using  GetBuffer().

Tuesday, June 02, 2009

WPF Databinding : Using CompositeCollection

The goal is to have a ComboBox whose ItemsSource should bind to more than one collection. In order to this, we make use of CompositeCollection as shown below.

XAML

<StackPanel>
<ComboBox Name="cb" ItemsSource="{Binding MoreThanOneCollection}">
</ComboBox>
</StackPanel>



Code-behind




Private _moreThanOneCollection As New CompositeCollection

Public Property MoreThanOneCollection() As CompositeCollection
Get
Return _moreThanOneCollection
End Get
Set(ByVal value As CompositeCollection)
_moreThanOneCollection = value
End Set
End Property

Private Sub Window_Loaded(ByVal sender As System.Object, _
ByVal e As System.Windows.RoutedEventArgs)
Me.DataContext = Me 'set the datacontext
BindData()
BindMoreData()
End Sub


Sub BindMoreData()
Dim data2 As New CollectionContainer
data2.Collection = GetData().Reverse()
'another set of data, just for the heck of it
MoreThanOneCollection.Insert(0, data2)
End Sub


Sub BindData()
Dim container = New CollectionContainer
container.Collection = GetData() ' the first data
MoreThanOneCollection.Add(container)
End Sub

Function GetData() As IEnumerable(Of String)
Dim x As New ObservableCollection(Of String)
x.Add("Item 1")
x.Add("Item 2")
x.Add("Item 3")
Return x
End Function


Just for practise purpose, I thought I would create the composite collection in code. This can also be done in XAML.

Loading BitmapImage from disk

While loading image in XAML is pretty easy (use <Image Source="xx.jpg"/>), it is not so straight forward to load an ImageSource from a file. (I always forget how to do this). So here is the code which might help you all. I have also specified some commented code which can be used to get thumbnails out of the image and other options like caching, etc.


ImageSource LoadImage(string filePath)
{
BitmapImage img = new BitmapImage();
try
{

img.BeginInit();
img.UriSource = new Uri(filePath, UriKind.RelativeOrAbsolute);
img.CacheOption = BitmapCacheOption.OnLoad;
//img.CreateOptions = BitmapCreateOptions.DelayCreation;
img.DecodePixelWidth = 50;
//img.DecodePixelHeight = 200;
img.EndInit();
}

catch
{
}
return img;

}

By the way, I have at last set up SyntaxHighlighter for my blog! this is sweet. Thanks to this post for the instructions.

Monday, June 01, 2009

Real world – really simple Composite WPF application for Twitter

Well, the name says it all. In this post, I would like to talk about how to implement a very basic (emphasis on very) twitter application as a Composite WPF application. I would like to demonstrate as many concepts in PRISM (Composite WPF) as possible and the following is the list that I am looking at.

1. Getting hold of CAL libraries.
2. Setting up the WPF shell – working with Bootstrapper.
3. Working with Regions – simple and nested regions.
4. Implementing modules and integrating them on to the defined.
5. Using Commanding framework in the application.
6. Communication between the modules – the PRISM way.
7. Last but not the least, we will be using the excellent Tweet#. Get the library from here.

Side-concepts about WPF includes MVVM (as I understand, I am not a guru), defining templates for ListView, etc.

For those expecting wonders, this app does not do anything but implement what http://search.twitter.com does. Give in a search term and it returns you the results. Screenshot shown below. If you like it, then you can proceed and read this long story, otherwise thanks for visiting.

image

Getting the Composite Application Library for WPF & Silverlight

I would not be stressing much on this, just a walkthrough. The composite application library does not ship binaries and ships source instead.

1. Download the latest CA L from codeplex. The actual download site is on the Microsoft Servers – direct download link. Extract/Install the CAL.

2. I placed the extracted files in Development\prism folder. Inside this folder, you see a CAL folder which contains the VS solution files.

image

3. Open the CompositeApplicationLibrary_Desktop.sln in Visual Studio 2008 and build the solution. (I built mine with Debug configuration).

4. Now go into Desktop folder and you see a whole bunch of Composite.* folders. Now the libraries that we would use are the output of the projects that you see in here. To save time, instead of going into individual folders, you can directly go into Composite.UnityExtensions folder/bin/<Debug or Release>. You should see the following libraries (assuming your build was successful).

image

Copy both the DLL and PDB files into a separate folder of your choice. I typically copy mine into a “libraries” folder inside the project that I am working on. It is from here that I add references. I also copied the Tweet# libraries (Dimebrain.TweetSharp.dll and NewtonSoft.Json.dll) into the same folder.

image

Now lets get on with the development.

STEP 1 : The WPF Shell.

1. Create a new WPF application project and name it as you want, I named mine as tru-twitter.

Add references to the Composite libraries that we saved previously. Some prefer not to build the libraries separately. Instead they add the CAL solution using the project linker shipped along with CAL distribution. But I like to keep my projects simple.

2. Now, all composite applications are hosted inside a shell. This shell would be implemented by using the simple steps described next. The shell is created via a bootstrapper which shows the shell (no magic, a shell is just a window which acts as the container for our application) and does other ground-work some of which include setting up the Inversion Of Control Container (Unity is the default with composite app library and this can be replaced, which is a different topic altogether), configures modules, etc.

3. So we need a bootstrapper. For this, add a new file to your project and name it as Bootstrapper.cs. Make your Bootstrapper class public sealed (which I like to do since sealed classes, i think, are more optimization-friendly and design friendly as well). The bootstrapper class should extend the UnityBootstrapper class. You can right click on the UnityBootstrapper and resolve the usages. Then you have to override “CreateShell()” method to say the least. Look at the code below which is pretty much self-explanatory.

public class Bootstrapper : UnityBootstrapper



    {     



        public readonly string ModulePath = Settings.



                                            Default.



                                            Properties["Modules"].



                                            DefaultValue.ToString();



 



        /// <summary>



        /// The CreateShell method instantiates the shell window.



        /// It is also responsible to show the window.



        /// </summary>



        /// <returns>The shell that was shown.</returns>



        protected override System.Windows.DependencyObject CreateShell()



        {



            //get the shell using IOC.



            var shell = Container.Resolve<Shell>();



            shell.Show();



            //RegisterGlobalServices();



            return shell;



        }



 



        /// <summary>



        /// Configure what kind of Module Catalog you would be using.



        /// This application uses the DirectoryModuleCatalog.



        /// All modules placed within ModulePath are loaded.



        /// </summary>



        /// <returns></returns>



        protected override IModuleCatalog GetModuleCatalog()



        {



            return new DirectoryModuleCatalog()



            {



                ModulePath = ModulePath



            };



        }



    }




The Window1.xaml has been renamed to Shell.xaml. Note that using Refactor option within Visual Studio to rename the class would be the best way to go since it can track all the places where Window1 was used.



4. Now open the App.xaml in XAML View and remove the “StartupUri” attribute. You have seen that the boot strapper takes care of showing the window. Now inside App.xaml.cs, modify the OnStartup() as shown below.





public partial class App : Application



    {



        protected override void OnStartup(StartupEventArgs e)



        {



            // let the base class do whatever it does.



            base.OnStartup(e);



 



            //create the bootstrapper



            var bs = new Bootstrapper();



            //call the Run() method on the bootstrapper.



            bs.Run();



        }



    }




The bootstrapper is triggered by the Run() method which is called from the OnStartup. The bootstrapper then does a lot of things (i dont know the list exactly but it configures your container, your module catalog loader and then invokes CreateShell method in which you show the window). Thus, on startup, the shell is created and is shown. Run the application to see it works without any issues. If you are unable to see the window, then there might be two issues – not calling the method Run() on the Bootstrapper or failing to invoke Show() method in the CreateShell().



5. Now we have the shell up and running. What ever the shell hosts (user controls), they are to be implemented as a modules. Before that lets tell the shell where to put the modules.



6. To do that shell should have Regions defined. Any container that contains a region is managed by the global “RegionManager” which takes helps in adding/removing views. For our application, we have one region within the shell. To define a region, open Shell.xaml in XAML view. Since there would be only one view, we define a ContentControl and give it a region name as shown below.





<Window x:Class="tru.twitter.Shell"



        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"



        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"



        xmlns:cal="clr-namespace:Microsoft.Practices.Composite.Presentation.Regions;assembly=Microsoft.Practices.Composite.Presentation"



        xmlns:helpers="clr-namespace:tru.twitter.common.Helpers;assembly=tru.twitter.common"



        Title="tru-Twitter!"



        WindowState="Maximized"



        >



    <ContentControl cal:RegionManager.RegionName="{x:Static helpers:RegionNames.SearchRegion}"/>



</Window>




Now you can notice two additional xml namespaces being added to the Window element. The “cal” namespaces allows us to access members of the “Microsoft.Practices.Composite.Presentation.Regions” namespace where as the “helpers” namespace refers to a custom library (just a class library) which contains my RegionNames. I prefer to have all my region names stored in a separate class and exposed as static members such that changes to the names would be rather easy and prevents us from hard-coding at several places.



The above XAML shows setting the RegionName (an attached property) and also shows how to access static members of the region names class.








7. Now that the region name is ready, let us add a new module to our project. Add a new Class library project to your existing solution.



I named it as “tru.twitter.search” which is not a good choice. I often name my module projects with “modules” in the name such that it tells me that this project is a module and not to be referenced directly in any other project. The modules are great since they are completely decoupled and I could replace the modules completely as I wish. The project structure should now include the shell project, search module project and the library project(tru.twitter.common, which contains code that is shared across all the projects, like the region names wrapper, services that I use, etc).



8. Modify the project properties of the module (right click => properties) to set the build output directory to where the ModulePath property points to in the Bootstrapper.cs file. Mine points to the “Modules” folder within the shell output directory.



image



For any module that you add, you should be doing this. Also note that the setting depends on the current build configuration. If you change the configuration from debug to release, you have to reset the path again.



9. Each module should have a module initializer class which implements the “IModule” interface. So, first of to resolve IModule interface, add all the composite library dll that were in the libraries folder. Then select these dll in the references and go to the properties. Set “Copy To Output” as false. These libraries are already being used by the shell and they would be reused by the modules are runtime.



10. The module initializer class – SearchModule should implement IModule interface and should define the “Initialize()” method. Since this module has UI elements which should be loaded into the regions, the module should have access to the Region Manager. The module also can use the IOC container to resolve objects which keeps the design much simpler, so it should also have access to the IOC container. Thus the module constructor would have the region manager and container as parameters. The module loader resolves this module during which the registered container and region manager are automatically passed to the constructor.



image



You can notice that my Initialize method registers services and views. So add the stubs for these two methods. Also make sure you add private fields for IRegionManager and IUnityContainer.



11. Let us test the set up so far. Build the solution and verify if the module is copied where it was supposed to be (remember we set the project output path earlier). Now, place a breakpoint at first line of constructor and inside the Initialize() method and run the application.



When the constructor breakpoint is hit, you should see both “rm” and “ctr” to not be null and instead they would be instances of IRegionManager and IUnityContainer. These instances are singleton and the same are used across the application.



After the constructor is hit, the Initialize() method should also be hit.



12. Now in the RegisterViews() method, we create the view we want to and add it to the region manager. Let us say that we have one single view called “SearchView” which should be loaded into the SearchRegion that was defined in the Shell.xaml. The RegisterViews() method should then be implemented as shown below.





private void RegisterViews()



        {



            LoadSearchRegion();



        }



 



        private void LoadSearchRegion()



        {



            var searchView = _container.Resolve<SearchView>();



            var searchRegion = _regionManager.Regions[RegionNames.SearchRegion];



            searchRegion.Add(searchView);



            searchRegion.Activate(searchView);



            //The search view region consists of SearchInput view and a results view.



            //By default only search input region is loaded.



            //Search Results would be loaded on demand - when search button is pressed.



            LoadSearchInputRegion();



        }




We shall get back to the LoadSearchInputRegion() shortly.



To avoid confusion, look at the screenshot below. The whole UI you see is the SearchView loaded into the Window (shell). The SearchView has two regions – Search Input Region (contains the SearchInputView) and the search results region.



When the application starts, only the search input view would be shown. Thus you can only see the LoadSearchInputRegion() method being called inside the LoadSearchRegion().



When the user presses the search button, the results are retrieved and the results view would be added.



image



The search input region is marked in yellow and the search results view is marked in blue.



13. Now let us implement the SearchView (the one which contains both the search input view at the top and search results at the bottom). Add a new WPF user control and name it as SearchView.xaml. Modify the XAML as shown below.





<UserControl x:Class="tru.twitter.search.Views.SearchView"



             xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"



             xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"



             xmlns:cal="clr-namespace:Microsoft.Practices.Composite.Presentation.Regions;assembly=Microsoft.Practices.Composite.Presentation"



             xmlns:helpers="clr-namespace:tru.twitter.common.Helpers;assembly=tru.twitter.common"



             >



    <Grid>



        <Grid.RowDefinitions>



            <RowDefinition Height="Auto" />



            <RowDefinition/>



        </Grid.RowDefinitions>



        <ContentControl cal:RegionManager.RegionName="{x:Static helpers:RegionNames.SearchInputRegion}"



                        Grid.Row="0"



                        />



        <TabControl cal:RegionManager.RegionName="{x:Static helpers:RegionNames.SearchResultsRegion}"



                    Grid.Row="1">



        </TabControl>



    </Grid>



</UserControl>




It has two rows in the grid – one for input region and one for results region. We just defined the regions and the views are loaded into these regions when the Add(view) is invoked on the region manager and then the views appear when Activate(view) is invoked. While the input region is simple, just like the one that we defined in the shell. Note that even though the regions in search view appear as if there are regions inside the region (SearchRegion in the shell), we would still be using the same region manager but nothing any fancy. The region manager is global and it figures out the regions, however nested they are.



We have already looked at ContentControl region. Now if you notice the search results region is defined as a TabControl. This is another control whose RegionAdapter is already implemented in the CAL. Another control with ready to use region adapter is the ItemsControl. (which we would not be looking at today).





<TabControl cal:RegionManager.RegionName="{x:Static helpers:RegionNames.SearchResultsRegion}"



                    Grid.Row="1">



</TabControl>




You have already observed that the same RegionNames class is being used even in this project – therefore you should not forget to add reference to the tru.twitter.common library and set the reference property “Copy to output” to false.



14. We now have two more regions for which views has to be implemented. So first let us implement the SearchInputView which sits in the SearchInputRegion.



15. Add a new user control called SearchInputView.xaml. Also add a new C# class called SearchInputViewModel. Those familiar with MVVM can see that I am trying to burn my hands with MVVM. One advice up here is to place all views inside a “Views” folder and View models inside “ViewModels” folder within the project.



image



Let us first look at LoadSearchInputRegion() implementation inside the SearchModule.cs





private void LoadSearchInputRegion()



       {



           var searchInputView = _container.Resolve<SearchInputViewModel>().View;



           var searchInputRegion = _regionManager.Regions[RegionNames.SearchInputRegion];



           searchInputRegion.Add(searchInputView);



           searchInputRegion.Activate(searchInputView);



       }




Notice that it is the ViewModel that is being resolved first and the view is obtained via the “View” property. The region is obtained using the regionManager instance that was obtained via the constructor and passing the region name to the “Regions” property.



So first of all, the ViewModel should have a “View” property. The ViewModel also should provide the properties which the View binds to. And for the data binding to auto-manage changes between the View and the ViewModel properties, the ViewModel should implement INotifyProperty changed interface. Thus far, we can deduce that any viewmodel should implement a view property as well as the INotifyPropertyChanged interface. So we place this common functionality inside a separate class called “ViewModelBase” (place it in the commons library project).





public abstract class ViewModelBase<T> : INotifyPropertyChanged where T : UserControl



    {



        //View is of type T, which essentially is a UserControl.



        public T View { get; set; }



 



        public ViewModelBase(T view)



        {



            this.View = view;



            View.DataContext = this;



        }



 



        protected void RaisePropertyChanged(string propThatChanged)



        {



            if (PropertyChanged != null)



                PropertyChanged(this, new PropertyChangedEventArgs(propThatChanged));



        }



 



        public event PropertyChangedEventHandler PropertyChanged;



    }




The abstract class defines a parameterized constructor which takes in the instance of the View. This instance would be automatically created by the Container#Resolve<>() method. But this also tells us that the ViewModel implementation should invoke this constructor. Let us look at the SearchInputViewModel class.





public class SearchInputViewModel : ViewModelBase<SearchInputView>



    {



 



        public SearchInputViewModel(SearchInputView view)



            : base(view)



        {



            InitializeCommands();



        }



 



        private string _search;



        public string Search



        {



            get { return _search; }



            set



            {



                _search = value;



                RaisePropertyChanged("Search");



            }



        }



}




The “Search” property should be bound to the textbox which accepts the user input. The XAML for SearchInputView is shown below.





<Grid>



       <Grid.ColumnDefinitions>



           <ColumnDefinition Width="*" />



           <ColumnDefinition Width="70" />



       </Grid.ColumnDefinitions>



       <TextBox Background="#AABBCCDD"



                Foreground="Black"



                FontFamily="Verdana"



                FontSize="24"



                Text="{Binding Search}"



                Width="Auto"



                VerticalContentAlignment="Center"



                VerticalAlignment="Center"



                HorizontalAlignment="Stretch"



                />



       <Button Grid.Column="1" TextBlock.FontFamily="Impact"



               TextBlock.FontSize="15"



               Foreground="Black"



               Background="AntiqueWhite"



               Margin="5" Padding="5"



               Content="Search"



               HorizontalAlignment="Stretch"



               VerticalAlignment="Stretch"



               >



       </Button>



   </Grid>


















Again the XAML is simple and straight forward.



16. Using Commanding in Composite WPF apps.



The rule for proper implementation of the MVVM pattern is to keep the code-behind for the view with no code at all. The interaction between the ViewModel and the View would be via data binding (which we used in the Textbox which binds to Search property in the ViewModel) and the user events like button click should be implemented via "Commanding”.



To implement command, modify the button XAML in the search input view as shown.



image



The DataContext for this view was already set in the ViewModelBase class. So the “SearchCommand” would be looked in the current ViewModel which is SearchInputViewModel.



To implement commanding, add a new property of type DelegateCommand<object>. Then the command is instantiated in the constructor. The modified ViewModel is shown below.



image



The DelegateCommand<object> constructor takes in two delegates one which is used to determine if the command can be executed and one which is invoked when the command is executed. The above code shows that the command is only executed when the “Search” property has some input entered. (see second parameter). When the command is executed, the “search service” is used executed. Notice ethat the constructor is modified to include a reference to the search service that would be used. We will get there in a while.



Note that the instance of the search service is also resolved using the IOC container, which by itself is sweet! But the container has to know which implementation should be used for the ISearchService, so we register the service.



17. The Twitter Search Service – Publishing events in Composite WPF world.



The twitter service is something that we would be using throughout the application and therefore it is like a global service. So we place the implementation in the common library where as register the service in the Bootstrapper as shown.





private void RegisterGlobalServices()



        {



            Container.RegisterType<ISearchService,TwitterSearchService>(



                                   new ContainerControlledLifetimeManager()



                                   );



        }






The RegisterGlobalServices() method is invoked in the CreateShell() method ( which was previously uncommented).



Following shows the ISearchService implementation.





public class TwitterSearchService : tru.twitter.common.Services.ISearchService



    {



        private EventAggregator _eventAgg;



 



        public TwitterSearchService(EventAggregator eventAggregator)



        {



            this._eventAgg = eventAggregator;



        }



 



        public void ExecuteSearch(string searchKey)



        {



            //get twitter results



            var req = FluentTwitter.CreateRequest()



                         .Search()



                         .Query()



                         .Containing(searchKey)



                         .AsJson();



            req.CallbackTo((s, e) =>



            {



                var result = e.Response.AsSearchResult();



                _eventAgg.GetEvent<SearchCompletedEvent>().Publish(result);



            }).RequestAsync();



        }



    }




In the ExecuteSearch() method you can notice that once the result from Twitter is obtained, the result is published as an event using the EventAggregator provided by the composite application library. Note that this is not the best implementation. Because the service is now dependent on the CAL which makes it less decoupled. This is one area where the code has to be refactored (we will look into that in the future articles).



The EventAggregator can publish an event. When an event is published, those who have “subscribed” to the event would be notified. Let us first look at the SearchCompletedEvent which is a C# class that just derives from CompositePresentationEvent<>. Since the result is an instance of “TwitterSearchResult”, it is passed to the generic type. The implementation is shown below.





public class SearchCompletedEvent : CompositePresentationEvent<TwitterSearchResult>



    {



    }






Now we have a service that when executed and completed the search raises the SearchCompletedEvent. So we should have a subscriber which can be notified when the event is published. The subscriber would then create the SearchResultsView and add the view to the search results region.



18. Subscribing the events in composite WPF.



Now we shall look at how subscriber should be implemented and also look at how views are loaded into regions on demand.



image



Go to SearchModule.cs and modify the RegisterServices() method as shown above. In this method we obtain the instance of the event aggregator with the help IOC container. Then we obtain the event using GetEvent<event type> method on the event aggregator. Then using the Subscribe() method we subscribe to the event. When the search completed event is published, the Action (as a lambda) passed to the subscribe method is invoked. We also specify that the event subscription action would be invoked at the UIThread. Look into the documentation for more information on this. In this method we simply load the search results tab view.



Note that the SearchResultsTabView is just a user control like any other one. But because the SearchResults region was a tab control, the TabControlRegionAdapater comes into play and automatically adds a TabViewItem to the TabControl and sets the content to the SearchResultsView. The TabControlRegionAdapter is already implemented in the CAL and we need not worry about it. The LoadSearchResultsTabView(result) is shown below.





private void LoadSearchResultsTabView(TwitterSearchResult res)



{



            //get the view model



            var searchResultsVM = _container.Resolve<SearchResultsViewModel>();



            //set the result to the "Model" property of the view model.



            searchResultsVM.Model = res;



            //get the View using the View property.



            var searchResultsView = searchResultsVM.View;



            //get the region, add and activate.



            var searchResultsRegion = _regionManager.Regions[RegionNames.SearchResultsRegion];



            searchResultsRegion.Add(searchResultsView);



            searchResultsRegion.Activate(searchResultsView);



}






Please read the comments for the code to make more sense.



19. Implementing the SearchResultsView/ViewModel.



Add a new C# class called “SearchResultsViewModel”. This class should derive from ViewModelBase which takes in SearchResultsView as the generic parameter. The ViewModel should pass in the View to the base constructor and then also define properties like “Model” and “SearchedFor”. The whole implementation is shown below.





class SearchResultsViewModel : ViewModelBase<SearchResultsView>



    {



        public SearchResultsViewModel(SearchResultsView view)



            : base(view)



        {



        }



        private TwitterSearchResult _model;



 



        public TwitterSearchResult Model



        {



            get { return _model; }



            set



            {



                _model = value;



                base.RaisePropertyChanged("Model");



            }



        }



 



 



        private string _searchedFor;



        public string SearchedFor



        {



            get



            {



                if (_searchedFor == null)



                    _searchedFor = Model.Query;



                return _searchedFor;



            }



            set



            {



                _searchedFor = value;



                RaisePropertyChanged("SearchedFor");



            }



        }



 



    }






Add the SearchResultsView as new WPF UserControl. The XAML is simple – display the list of “Statuses”, a property that is exposed in the “TwitterSearchResult” class.





<ListView DataContext="{Binding Model}"



              ItemsSource="{Binding Path=Statuses}" 



              HorizontalContentAlignment="Stretch"



              ScrollViewer.CanContentScroll="True"



              ScrollViewer.VerticalScrollBarVisibility="Visible"



              >



        <ListView.ItemTemplate>



            <DataTemplate>



                <Border CornerRadius="5" 



                        Background="AntiqueWhite" 



                        HorizontalAlignment="Stretch"



                        Margin="5"



                        Padding="5"



                        >



                    <Border.Effect>



                        <DropShadowEffect BlurRadius="3"/>



                    </Border.Effect>



                    <StackPanel>



                        <Label Content="{Binding Id}"/>



                        <Label Content="{Binding Text}"/>



                    </StackPanel>



                </Border>



            </DataTemplate>



        </ListView.ItemTemplate>



</ListView>




Observe the ListView’s DataContext property has been set to the Model. (The user control’s DataContext property is already set to the ViewModel in the ViewModelBase). The ItemsSource property is set to “Statuses”, which is defined as a property inside “Model”. To enable scrolling, the ScrollViewer.XXX properties are set.



The ListView then defines an ItemTemplate, which tells the WPF engine on how each item (each status, of type TwitterSearchStatus) is rendered. It is the “template” for each TwitterSearchStatus item. For cosmetic reasons, I have included a Border with a DropShadowEffect applied. Inside the border is a stack panel which displays the Id of the status and the status text.



SOURCE CODE



Well, what I promised at the start of the article, I have covered the most. The source for the application is available for download at my skydrive. I have not included the dependency libraries (CAL, Tweet#) since I am not sure about their licensing. License?? Use the code as you like, you can do whatever you feel like.



What next?



1. The current implementation, though adds a new TabItem for each search, it does not display the tab header. The tab header should show the “SearchedFor” property.



2. As you type in the search, the “Search” button is not enabled until the search is tabbed out. But the ideal implementation would be when the user enters the first character, the button should be enabled and when the user presses enter, search should be executed.



3. Add the ability to auto refresh the results.



4. Implement paging, as of now, the application displays only the first 15 status. TweetSharp library, by the guys from Dimebrain (they make wonderful mini-screencasts and of course this excellent library) returns the first 15 status in the first page and they provide excellent FluentInterface to twitter which makes it easy to retrieve the rest of the pages.



5. Finally, implement a fully functional Twitter client – Yeah, Yet Another Twitter Client and I have some nice functionality ideas to implement which I would share in the future.



6. Refactoring the code to make it well designed.



If you have survived until this point, then I am doing a pretty good job at writing. I know its a long article and I have written the whole thing at one go ( after working for 8 hours, for a living). So kindly let me know for any bugs in this article.

ListView/ListBox Selected Item Color – Active and Out of Focus

The following snippet of XAML can help you set a fixed color scheme for a selected item in the list controls whether the control has focus or not.

   1: <StackPanel Orientation="Vertical">


   2:         <ListView Background="SeaGreen">


   3:           <ListView.Resources>                        


   4:             <SolidColorBrush x:Key="{x:Static SystemColors.HighlightBrushKey}" Color="Red"/>


   5:             <SolidColorBrush x:Key="{x:Static SystemColors.ControlBrushKey}">            


   6:                   Red


   7:             </SolidColorBrush>


   8:             <Style TargetType="{x:Type ListViewItem}">


   9:               <Style.Triggers>


  10:                 <Trigger Property="IsSelected" Value="True">


  11:                   <Setter Property="Foreground" Value="Black"/>


  12:                 </Trigger>


  13:               </Style.Triggers>


  14:             </Style>


  15:           </ListView.Resources>


  16:             <ListViewItem>String 1</ListViewItem>


  17:             <ListViewItem>String 2</ListViewItem>


  18:             <ListViewItem>String 3</ListViewItem>


  19:         </ListView>


  20:         <Button>Button 1</Button>


  21:     </StackPanel>


Declaring Empty String in XAML

Shown below is a code snippet which does not work.

   1: <ListView xmlns:System="clr-namespace:System;assembly=mscorlib">


   2:     <ListView.ItemsSource>


   3:      <coll:ArrayList>


   4:           <System:String></System:String>


   5:           <System:Int32>34</System:Int32>


   6:     </coll:ArrayList>  


   7:     </ListView.ItemsSource>


   8:   </ListView>






One would notice the following error when the above XAML is parsed.



Cannot create object of type “System.String”. CreateInstance failed, which can be caused by not having a public default constructor for ‘System.String’.



The reason for this error is that the “System.String” class does not provide a default constructor and this disallows declaring empty string.



What’s the fix?





   1: <ListView xmlns:System="clr-namespace:System;assembly=mscorlib">


   2:     <ListView.ItemsSource>


   3:      <coll:ArrayList>


   4:             <!-- notice empty string via usage of x:Static -->


   5:           <x:Static Member="System:String.Empty" />          


   6:           <System:Int32>34</System:Int32>


   7:     </coll:ArrayList>  


   8:     </ListView.ItemsSource>


   9:   </ListView>





Hope this helps.

Friday, May 29, 2009

Using WCF + Silverlight 2 + PRISM : Gotchas

In this entry, I would be talking about the issues that I have encountered when developing a Silverlight application structured with PRISM principles and that is driven by a WCF service. Some of the issues that I mention here are applicable even when making just Silverlight applications (like Data Binding Hello World!).

Gotcha 1 : Working with Data Binding

Shown below is the code snippet for startup xaml page – XAML code on the top and code behind at the bottom half.

image

If you observe the XAML, it simply contains a textblock and a textbox which both binds to the same property called “Debug”.

So in the codebehind, I created a property called “Debug” and in the constructor for the page (my page is called Shell), I have set the DataContext to itself. So the Binding Source should be the DataContext of the UserControl which points to itself (the instance of Shell). So Debug property should be taken from the property listed in the Shell class.

While this setup works well in a WPF application, running in Silverlight terminates the application. I have noticed that when “this.DataContext = this” is placed in a Silverlight page, the application would terminate with an exception [AG_E_PARSER_BAD_PROPERTY_VALUE(Line: 8 Position: 42)].

image

Apparently, this.DataContext = this is not being liked by the Silverlight engine. You can comment the XAML inside StackPanel and then try running the application again. You would still notice that the application fails to execute.

So, the lesson learnt here is “unlike in WPF, Silverlight does not like DataContext of a UserControl to be set to itself”.

So how am I going to make it work?

Shown below is the fixed version. We have a  ShellViewModel which is instantiated within the constructor and then the data context is set to this instance.

image

Gotcha 2: Missing Event Handler Methods can terminate your application

Sometimes it so happens that you specify an EventHandler method in XAML but forget to implement the method in code. In that case, the compiler does not throw an error and instead a runtime exception would terminate the application. If you would like to experiment, remove the empty “private void Text….” method inside Shell class and run the application.

Gotcha 3 : Data Binding makes no sense without INotifyPropertyChanged.

If you look at the last code snippet, in the XAML section, both TextBlock and TextBox bind to the same “Debug” property. Now in the TextBlock LeftMouseButtonUp event handler, lets add a line which changes the value of the “Debug” property, like shown below.

image

Now, if you run the application, and left click on the TextBlock, the event handler would be executed, the value of Debug would be updated but the UI would still show the same “Click Me!” (the default value for Debug) since it has no idea that the Debug property has been modified.

To fix this and to make the UI thread aware of any changes made to the properties it binds to, the properties should either be made as Depdendency Properties or the Data Context should implement INotifyPropertyChanged and the setter of the properties should raise the PropertyChanged event.

Using INotifyPropertyChanged

Shown below is the modified ShellViewModel which implements INofityPropertyChanged.

image

Using INotifyPropertyChanged is probably a better way to do things and in fact much simpler to use. In every property, the setter should raise the PropertyChanged event. Thats it!

Now the application works as expected. When you click on the textblock, both the TextBlock and TextBox changes.

image

Gotcha 4 : Be aware of Data Binding Default Mode.

If you come from a WPF background, like me, then the same set up (XAML + code as shown until now) would behave differently in Silverlight. In WPF, if you change the text inside the textbox and tab out, you would notice the text in the text block change as well. But this does not happen in case of Silverlight. Proof ?? Try it or believe what is shown in the picture below.

image

Notice that the text block still shows the old text in spite of the text changed in the textbox (which also binds to the same property as the text block). The reason for this not to work is that in WPF the default Binding Mode is TwoWay, while in Silverlight its OneWay. For those who do not know, TwoWay means changes in the source (data) would also update the target (UI) while OneWay only updates the source when the target is changed by the user (at least that is what I understand they mean).

What’s the fix?

image

image

Silverlight Dependency Properties

Look at this article : http://blogs.sqlxml.org/bryantlikes/archive/2008/12/15/silverlight-dependency-properties.aspx

 

Now that I have talked about some fundamental issues one might face when starting Silverlight development, I thought I would dig more into gotchas encountered when working with Composite Silverlight applications driven by WCF services.

Gotcha 5: Composite Silverlight Applications – Bootstrapper, ModuleCatalog using XAML

Assumptions : I assume you have downloaded the Composite WPF/Silverlight (PRISM) and built the CAL. Shown below are the Silverlight libraries that I have on my machine. I also assume you have basic understanding of what a composite application is, what silverlight module is, etc.

image

In the Silverlight project, add reference to the above libraries. Then the first step is to create a Bootstrapper. The bootstrapper performs all the required initialization and configuration for the application. Shown below is my Bootstrapper that I have used in one of my silverlight prism applications.

 image

The bootstrapper 1) creates the shell, 2) tells how your modules are cataloged and 3) additionally, it adds new RegionAdapters to existing ones.

The fun part here is the ModulesCatalog.xaml. This XAML file is used to configure my modules and the  contents would be shown in a while. The package uri used is always annoying to me, so I use this URI as a reference and it works. You are free to use this as a reference. Anyway, lets look at the modules catalog.

image

Even though each XAP file has only one module, I noticed that for the Module configuration to work properly for both WhenAvailable/OnDemand, ModuleInfoGroup has to be used.

Before we look into how to make each module as a separate XAP file, lets look at how the bootstrapper has been used.  The App.xaml.cs has to be modified in the Application_Start method to reflect the following.

image

Gotcha 6 : Preparing a Silverlight module as a XAP File

When you create a new Silverlight Library, the output of the project would be a silverlight dll which cannot be used for On Demand loading for PRISM applications. So you have to make your modules to be generated as a XAP files (which are just ZIP files). Follow the steps shown below and you would be good.

1. Add a new Silverlight application project to the solution. Stress on “Silverlight Application” not a Silverlight library.

image

Make sure you link the control but you uncheck “Add a test page that references the application”.

2. Delete the App.xaml file.Build the solution. You should see the .xap file added to the ClientBin along with the shell project. Shown below is my project structure after the build. (Notice ethe maya.sample.module.xap and also missing App.xaml inside the module project).

image

Sub-Gotcha: What if you already have a silverlight library project and you wish the build to generate a XAP file instead?

You have to right click on the silverlight library project and “Edit Project file”. This unloads the project and opens the project file inside XML editor within Visual Studio. (Or you can open it manually in editor of your choice). The first PropertyGroup section would like shown below. Notice the SilverlightApplication is set to false.

image

Make changes such that it looks like shown below. You have to add XapOutputs element and set it to true.

image

Now reload the project. Open the project folder in Windows Explorer and go to the Properties folder. Add a new file  called AppManifest.xml with the contents as shown below.

   1: <Deployment xmlns="http://schemas.microsoft.com/client/2007/deployment"


   2:         xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"


   3: >


   4:     <Deployment.Parts>


   5:     </Deployment.Parts>


   6: </Deployment>




Now come back to Visual Studio and click on the “Show All files” icon in Visual Studio Solution Explorer selecting the library project.



image



You should see AppManifest.xml without any icon associated. Right click on the xml file and click “Include in Project”.



Now go to the properties. The Silverlight tab should look like shown below. Specify the Xap Filename as you wish. Typically, I name it same as the Assembly name.



image



My modified Silverlight Build options screen is shown below.



image



Notice that I have also set the Manifest File template to the file that we added previously.



Sub - Gotcha : This generates the XAP file. But it isn’t being copied to the ClientBin



If you build the library project with the changes mentioned above, you can see the XAP file  generated in the Debug folder but it would not automagically sit inside the ClientBin for the Web application project. To make this happen automatically, you have to modify the web application project properties. Right click on the web application project that contains your ClientBin. Go to the Silverlight Applications tab. Click on Add. Select your project and uncheck the “add a test page that references the control” since we do not want that. Shown below is that “Add Silverlight Application” screen. Finally click “Add”.



image



Now build your solution and you should notice the XAP file being copied into the ClientBin folder.



Gotcha 6 : Configuring Modules using XAML – ModuleCatalog : Always place the modules inside ModuleInfoGroup.



Like mentioned previously, modules can be configured via an XAML file. This configuration allows one to specify if the modules be loaded as soon as they are available or when demanded. Lets assume that you have a XAP module which is to be loaded on demand and one which is to be loaded when available. Shown below is segment of my ModulesCatalog.xaml file whose complete version has been presented previously. Somehow, ModuleInfo when placed inside ModuleInfoGroup works where as just a ModuleInfo by itself always seemed not to work (may be I did something wrong).



image



So how to demand a module?



_moduleManager.LoadModule("PerformanceCounterModule");



Where _moduleManager refers to the current ModuleManager instance. The best way to get this is to add ModuleManager parameter to the constructor and use UnityContainer to resolve the object. For example, shown below is one of the ViewModels that I use which has an instance of ModuleManager passed to its constructor. The ViewModel is not instantiated directly but instead obtained via “container.Resolve<>()” call.



image



Unless implemented once, these concepts are rather difficult to understand. May be I will do a walkthrough for WPF based Twitter client very soon during which we can look at how it works out. For now, I assume you understand what I am talking about.



Gotcha 7 :  WCF Service with Silverlight Applications – Deployment, Libraries, etc….



First of all, lets say you have a WCF service hosted inside the Web application. Lets say you created a Silverlight library which consumes this service, thereby you get to have a ServiceReferences.ClientConfig inside this helper client library but would not be present inside the shell application. Later when you deploy the service, it would be required that you modify the configuration files since the deployed service might have a different URI than the one at development. So to overcome this, shown below is one way that I often use. This simply obtains the service end point address and it assumes that the silverlight application and the service are both hosted within the same web application. All you need to look at is the way “_remoteAddress” is determined using Application.Current.Host.Source.



image



Now lets look at the application set up. Shown below is the shell project and the helper library which consumes the WCF service. Like I said before the library would be referenced and the WCF service is used instead of consuming the WCF service directly. (highlighted in the picture).



image



So if you try and consume the service within the shell application you would compile and build without any issues. The namespaces would be figured out nicely (or use Ctrl + . in Visual Studio to resolve the namespace). But as you execute the application, you would face the exception shown below.



image



The message says “Cannot find ‘ServiceReferences.ClientConfig’ in the .xap application package”. And clearly we did not place one. But if we place one in here, it might be redundant and may later cause conflict issues which is not so easy to identify (since we might forget – remember DRY).



To resolve this, on the shell application (named maya in my case),



1. Right click on the project and click “Add Existing Item”. Navigate to the library which has the actual ClientConfig file.



2. Select the file (ServiceReferences.ClientConfig) and then instead of clicking add, click the arrow next to “add” and click “Add as Link”.



3. Remember we are adding a link. One mistake that I often do is to first click “Add as Link” and then select the file followed by clicking on "Add” button. I assumed the drop down whenever clicked would change the behavior of the “Add” button but this isn’t the case. You have to first select the file and then click on “Add as Link”.



image



4. You can verify that its a linked copy by opening the shell application folder and you should not see any ClientConfig file. It should only be in the service layer library we added.



image



Gotcha 8 : Last one … Silverlight XAP File size, Performance settings.



1. Not sure if it matters much but you can actually extract the XAP file and re-zip it with a better utility like WinRar or 7-Zip and gain much smaller sized XAP files.



2. In the ASPX page that hosts the Silverlight content, you can add an attribute “MaxFrameRate” and set it to a lower value like 10. I have to be honest that I do not know if this setting would improve performance for any kind of silverlight applications or just the ones with media in it. Anyway I do it for any application I use.



I hope this post is informative enough and slightly well organized. I am not an expert in any of the technologies – composite silverlight apps, wcf or even Visual Studio. But i thought it would be a nice thing to share my observations with the community. So please be gentle if there is a mistake in my approach or my concepts and I would be glad to rectify them.



Thank you.

Wednesday, May 27, 2009

Running KirbyBase on IronPython

As I was looking for embedded database systems, I came across this pure python database called KirbyBase. So I decided that I would make it run on IronPython. So this post describes on how to make KirbyBase run on IronPython and using ipy.exe. Note that I am not looking at integrating this database into C# application yet. [may be in the future post]

So what are the steps?

1. Get the latest IronPython and install it on your machine. You should be seeing ipy.exe in the installation directory.

2. Get the KirbyBase download from its website.

3. Download and install Python 2.6 whose libraries are required to run the database tests.

4. Once Kirbybase and Python 2.6 are installed, look for kbtest.py inside kirbybase installation directory.

5. Copy the kbtest.py into the directory which has ipy.exe (the IronPython installation directory).

6. Modify the kbtest.py to include the Python and KirbyBase directories into the path. The final result should look something like shown below.

image

Notice that I have moved “import sys” statement ahead of “import os”. The lines 2 and 3 adds the directories for Python2.6 and KirbyBase to the path.

Then from command prompt type in the following

ipy kbtest.py

The result should look like shown below.

image

May be next time, I would like to see what it takes to integrate this database into C# application. Until then, have a nice time. Let me know if you have better approaches than what I did here. Thank you.

Tuesday, May 26, 2009

Debugging W3WP with “Attach to Process”

When trying to load SOS.dll while the debugger is attached to the w3wp process, if you encounter the following message.

SOS not available while Managed only debugging.  To load SOS, enable unmanaged debugging in your project properties.

Then, stop the debugging session and in the “attach to process” dialog, select your process and click on the “select” button. Then you can pick what kind of debugging sessions would you like to permit.

image

By default, the code to debug is automatically determined in which case only Managed and T-SQL debugging is enabled.

Another useful feature would be using “New Breakpoint” functionality. This would be useful when you are using  Attach to Process and do not have the source code opened as a project. In this case, you can go to Debug->New Breakpoint-> Break at function.

image

Once you are in this window, give the function name where you want to break and then click OK. Ignore any warning messages that it gives and then it would hit the breakpoint if the function you named would be executed. I will be posting more as I learn more about using SOS.dll with W3WP.

Wednesday, May 20, 2009

Using Blueprint CSS in ASP.NET MVC

I know my previous post on the blog is incomplete but I promise to get back to that complete as soon as possible. In the meantime, here is a quick info on how to include Blueprint CSS files within ASP.NET MVC applications. I add this to my Site.Master page.

   1: <link href="<%=Url.Content("~/Content/Site.css") %>" rel="stylesheet" type="text/css" />


   2:     <!-- Framework CSS -->


   3:     <link rel="stylesheet" href="<%= Url.Content("~/Content/blueprint/screen.css")%>"


   4:         type="text/css" media="screen, projection">


   5:     <link rel="stylesheet" href="<%= Url.Content("~/Content/blueprint/print.css")%>"


   6:         type="text/css" media="print">


   7:     <%="<!--[if IE]>"%>


   8:     <link rel="stylesheet" href="<%= Url.Content("~/Content/blueprint/ie.css")%>" type="text/css"


   9:         media="screen, projection">


  10:     <%="<![endif]—>"%>





More later..

Thursday, May 14, 2009

Working with Blueprint CSS Framework!

It has been a long time since I wrote something on my blog. I have been extremely busy as well as lazy to make any updates up here. The last time I talked about detecting prime numbers using python list comprehensions and made a failed attempt to optimize it. I could not find time to work on that again, so I skipped it. Anyway, from then I made significant progress in upgrading my silverlight/wpf/PRISM skills. [More on that sometime later] And then I decided that I would be working on some ASP.NET MVC project which I hope to bring online by the end of June.

As a part of that, I have been looking at evaulating CSS Frameworks – some think CSS frameworks suck, but used appropriately they do save us a lot of time. Every one who is moderately versed with CSS begins to say that using a framework is not a good idea and they miss the point of CSS. Come on, seriously, I looked at two popular CSS frameworks – Blueprint CSS and 960.gs and they are extremely cool. Before I go into any more details on how to use Blueprint CSS, I would like to point out that 960.gs is pretty good and there is a screencast on nettuts.com. If you watch the screencast, it would help you understand the basic concepts which I would not talking about in this post. So please watch the screencast if possible or I assume what ever I write makes sense to you.

Shown below is what we would be trying to achieve. It is very simple to do, once you have the basic understanding of blueprint CSS Framework.

image

DISCLAIMER: Neither I am an author of Blueprint CSS Framework or any of its plug-ins nor am I am any kind of expert in web design. I just know how to survive as a web developer/designer.

My application setup is as follows. I have the blueprint download from their website(http://blueprintcss.org). Once your extract the archive that you have downloaded, you can pick the "blueprint" folder and copy into your website folder. Then in the website, within the same folder where you copied the blueprint folder, create a sample.html.

Firstly, add the links to the CSS stylesheets.
<!-- Blueprint CSS -->
    <link rel="stylesheet" href="blueprint/screen.css" type="text/css" media="screen, projection">
    <link rel="stylesheet" href="blueprint/print.css" type="text/css" media="print" />
    <!--conditional CSS makes the site slightly slower -->
    <!--[if IE]>
        <link   rel="stylesheet"
                href="blueprint/ie.css"
                type="text/css" media="screen, projection">
    <![endif]-->
<!-- End of Blueprint CSS -->
I hope you know that CSS links are added in the <head> section.

CSS frameworks does not give you everything you want and does not prevent you from customizing your html, just like you did when not using the frameworks. The biggest advantage that I see when using the framework is the amount of time you have invest in resetting the browser settings and then time required to test each and every change on your layout. Trust me, it is painful.
Anyway we would stil