Archive for August, 2006

31AugObjectdatasource, gridview and custom paging

I’ve spent the last couple of hours trying to work something out that boggled my mind.

I have a base4 class that I wrapped in a Dataobject in my Businesslayer.

On my page (actually in a user control) i have a gridview that binds to an object datasource and stores the list of retrieved values in the viewstate. The business object is paged server side and supports sorting.

The business object looks at it’s simplest like this :

There are 2 methods for every retrieval function. the first method is the method that fetches the list of data to display and the second method just gives the full row count. There are 2 methods because their signatures need to be the same.

What i then did was handle the objectSelected event of the object datasource and pass the e.ReturnValue to a property of my control that stores the list in viewstate.
When i select something in the gridview I always got an exception thrown telling me that the variable in viewstate was null.

After a lot of debugging sessions (in a solution that takes about 10 minutes or a little longer to build) I found out that i get a value in the viewstate but then lost it again in the same operation.

And that’s when it hit me. The object datasource selected event gets also fired for the count method and empties the viewstate. So now I have a second round trip to my database to stick the values in the viewstate and everything works.

So if anybody comes across a similar problem this is how i got around it.
I do realize the importance of caching ;)

The objectdatasource definition:

“ObjectDataSource1″ runat=“server” DataObjectTypeName=“Smap.Data.Contact”
EnablePaging=“True” MaximumRowsParameterName=“pageSize” OldValuesParameterFormatString=“original_{0}”
SelectCountMethod=“GetByCompanyNameCount” SelectMethod=“GetByCompanyName” SortParameterName=“sortExpression”
TypeName=“Smap.Businesslogic.Contacts.ContactSource” EnableViewState=“true” OnSelected=“ObjectDataSource1_Selected”>

“SearchList” Name=“searchString” PropertyName=“Text”
Type=“String” />
“sortExpression” Type=“String” />
“startRowIndex” Type=“Int32″ />
“pageSize” Type=“Int32″ />

And the objectdatasource selected event :

    protectedvoid ObjectDataSource1_Selected(object sender, ObjectDataSourceStatusEventArgs e)

    {

        if (e.OutputParameters.Keys.Count > 0)

        {

            foreach (object key in e.OutputParameters.Keys)

            {

                Response.Write(string.Format(“Key: {0}, Value: {1}, Type: {2}
,key,e.OutputParameters[key],e.OutputParameters[key].GetType()));

            }

        }

        Contacts = source.GetByCompanyNameByPage(SearchList.Text, gvContacts.SortExpression, gvContacts.PageIndex, gvContacts.PageSize) asItemList<Contact>;

    }




The business object :

using System;

using System.Collections.Generic;

using System.Text;

using System.ComponentModel;

using Smap.Data;

using Base4.Storage;

 

namespace Smap.Businesslogic.Contacts

{

    [DataObject]

    publicclassContactSource

    {

        [DataObjectMethod(DataObjectMethodType.Select,true)]

        publicIItemListContact> GetByCompanyName(string searchString, string sortExpression, int startRowIndex, int pageSize)

        {

            //Set the default sortexpression is none is provided.

            if (string.IsNullOrEmpty(sortExpression))

                sortExpression = “CompanyName”;

 

            //The objectdatasource returns the index of the first row that is to be retrieved

            //Base4 needs the page number

            int pageNumber = getPageNumber(startRowIndex, pageSize);

 

            //initialise the object path with the sort expression

            ObjectPath path = initialiseObjectPath(sortExpression);

 

            //Add our parameter

            path.New(“CompanyName”).LIKE(string.Format(“%{0}%”, searchString));

 

            //Tell base4 which pages that need to be retrieved.

            path.PageNumber = pageNumber;

            path.PageSize = pageSize;

 

            //Return our list to the object datasource

            returnStorageContext.FindContact>(path);

        }

 

        [DataObjectMethod(DataObjectMethodType.Select, true)]

        publicIItemListContact> GetByCompanyNameByPage(string searchString, string sortExpression, int pageNumber, int pageSize)

        {

            //Set the default sortexpression is none is provided.

            if (string.IsNullOrEmpty(sortExpression))

                sortExpression = “CompanyName”;

 

            //initialise the object path with the sort expression

            ObjectPath path = initialiseObjectPath(sortExpression);

 

            //Add our parameter

            path.New(“CompanyName”).LIKE(string.Format(“%{0}%”, searchString));

 

            //Tell base4 which pages that need to be retrieved and their length.

            //The gridview returns the page index which is zero-based, base4 asks for a page number which starts at 1.

            path.PageNumber = ++pageNumber;

            path.PageSize = pageSize;

            returnStorageContext.FindContact>(path);

        }

 

 

        publicint GetByCompanyNameCount(string searchString, string sortExpression, int startRowIndex, int pageSize)

        {

            //Gets the count of all the contacts.

            returnStorageContext.FindAllContact>().Count;

        }

 

 

        privateObjectPath initialiseObjectPath(string sortExpression)

        {

            ObjectPath path = newObjectPath();

            if (sortExpression.Trim().Length > 0)

            {

                string[] sortParams = sortExpression.Split(“,”.ToCharArray());

 

                foreach (string s in sortParams)

                {

                    OrderByDirection direction = s.IndexOf(“DESC”) > -1 ? OrderByDirection.Descending : OrderByDirection.Ascending;

 

                    string orderby = s.Substring(0, s.IndexOf(“DESC”) > -1 ? s.IndexOf(“DESC”) : s.Length);

 

 

                    path.AddOrderBy(orderby, direction);

                }

            }

 

            return path;

        }

 

        privateint getPageNumber(int startRowIndex, int pageSize)

        {

            //if the start index is smaller than 0 return 0 otherwise return the index of the current page.

            int number = startRowIndex <= 0 ? 0 : (int)Math.Ceiling(Convert.ToDouble(startRowIndex / pageSize));

 

            //make our zero-based index into a number starting at 1;

            return ++number;

        }

 

    }

}

29AugDid Teched have an impact

In my case I guess it did.

First of all there were the presentations on Presentation Foundation which were really cool and made me want to start playing with it right away.

Unfortunately for my playing time, currently I am in a really busy period professionally so I’ll just have to stick with what I know already.

However I will start using communication foundation whenever possible as well as workflow foundation these two pieces are too useful for me not to use them.
Also it made me rethink the way I’ve been using atlas and how I’ve been evolving with the development of websites in atlas.

In the beginning I was doing atlas I used update panels like everybody else. But soon I came across a lot of limitations of the update panel. Where they weren’t flexible enough etc. That’s when I started talking to webservices directly and did to everything client-side. This had as drawback that once you started to put a reasonable amount of functionality in the page the initialisation process takes a really long time. In meantime atlas has evolved for the better I must say. Also the control toolkit has grown a lot.

Now the control toolkit holds the control I’ve anticipated the most : the animation control. Also for about every bit of functionality you have a blueprint in the control toolkit that let you extend every server control on your page to do pretty much anything you want.

Where I was in doubt last week if atlas was really the best choice to go the ajax route. Now these doubts have been erased.

At tech ed I got a chance to have a chat with Scott Guthrie, who for a really smart guy knows how to communicate really well and certainly better than me :) , and he couldn’t say what was on the horizon atlaswise but just that it was going to be really cool. Even cooler than Nikhil Kothari’s script sharp, I for one can’t wait to set what they have in store for us.

In short teched was excellent in my case and would love to do it again :)

29AugA generic builder for unit tests

I’ve been using base4 quite a lot lately :) . And obviously I like it. But anyway for unit testing i found myself writing
virtually the same builder class over and over again.

And since it is just test data that needs to be removed later it is always
very similar. I started thinking about my problem and came to the conclusion
that I could easily enough build a generic class that iterates over the object
and takes all the properties that belong to that type and not to any of the
parent types and fill them with valid data for their returntype.

I got to work and not so long after that I came up with the following class:

using System;

using System.Collections.Generic;

using System.Text;

using Base4.Storage;

 

namespace NBlogr.NUnitTests.HelperClasses

{

    publicclassBuilder where T : class,IItem,new()

    {

        privateList items;

 

        publicList Items

        {

            get

            {

                if (items == null) items = newList();

                return items;

            }

            set { items = value; }

        }

 

        publicvirtual T Add()

        {

            return Add(null);

        }

 

        public T Add(int? index)

        {

            T t = new T();

            return Add(t, index, true);

        }

 

        publicvirtual T Add(T t, int? index, bool generateValues)

        {

            IItem item = t;

            if (generateValues)

            {

                foreach (PropertyImpl p in item.TypeDefinition.Properties)

                {

                    switch (p.ReturnTypeName)

                    {

                        case“bool”:

                        case“Boolean”:

                        case“System.Boolean”:

                            item[p.Name] = index.HasValue;

                            break;

                        case“string”:

                        case“String”:

                        case“System.String”:

                            if (index.HasValue)

                                item[p.Name] = string.Format(“Unittest {0} {1}”, item.TypeDefinition.Name, index);

                            else

                                item[p.Name] = string.Format(“Unittest {0}”, item.TypeDefinition.Name);

                            break;

                        case“uint”:

                        case“short”:

                        case“int”:

                        case“long”:

                        case“Int16″:

                        case“Int32″:

                        case“Int64″:

                        case“System.Int16″:

                        case“System.Int32″:

                        case“System.Int64″:

                            item[p.Name] = index.HasValue ? index.Value : newRandom().Next();

                            break;

                        case“byte”:

                        case“Byte”:

                        case“System.Byte”:

                            item[p.Name] = index.HasValue ? Convert.ToByte(index.Value) : newbyte();

                            break;

 

                        case“double”:

                        case“Double”:

                        case“System.Double”:

                            item[p.Name] = index.HasValue ? Convert.ToDouble(index.Value) : newRandom().NextDouble();

                            break;

 

                        case“byte[]“:

                        case“Byte[]“:

                        case“System.Byte[]“:

                            Byte[] bytes = newbyte[128];

                            Random rnd = newRandom();

                            rnd.NextBytes(bytes);

                            item[p.Name] = bytes;

                            break;

 

                        case“Guid”:

                        case“System.Guid”:

                            item[p.Name] = Guid.NewGuid();

                            break;

                    }

                }

            }

            item.Save();

 

            items.Add((T)item);

 

            return item as T;

        }

 

        publicvoid BuildList()

        {

            BuildList(5);

        }

 

        publicvoid BuildList(int length)

        {

            if (items == null) items = newList();

 

            for (int i = 0; i < length; i++)

            {

                int index = i + 1;

 

                Add(index);

            }

 

        }

 

        publicvoid CleanUp()

        {

            if (items != null && items.Count> 0)

            {

                foreach (IItem item in items)

                {

                    item.Delete();

 

                }

            }

        }

    }

}

24AugAptana for writing atlas script

I write quite a lot of javascript code these days and have been looking for a couple of months for ways to make my life easier.

Easier would mean in my opinion to get some kind of intellisense or autocomplete while writing javascript.

As it turns out in visual studio orcas these features will be available so I’ll be a very happy vs orcas user i guess :) .  But in the meantime there is a free eclipse based IDE around aptana that let’s you take advantage of autocomplete etc.

I added the atlas debug files to the default code profile and I was in business.

18AugNew Base4 CTP a must have

I’ve been playing with the new base4 ctp that was released yesterday. And I must say that schema website thingy … NICE ;-)

I had trouble working out the joins from time to time but now I just browse my schema and it will show me the syntax if i click on a onetomany relationship which is SO cool.

 

I’d say Alex keep doing what you’re doing :D

16AugMake the object datasource support relations

One of the shortcomings of the object datasource is that it doesn’t support relations properly. It only gives you a single table view of an object if that object is a dataset or datatable.

But what about the relationships etc. Well my first choice was to create specific views etc. But I found it to be a real hassle combined with stored procedures to maintain once the project starts growing a bit.

From the dataset I want a structure that looks like my database. Nothing more nothing less. The same relations and constraints there etc.

How do you accomplish that ? Well it’s going to be a bit of a lengthy post this one because it’s a lot of code.

This is the schema I’ll be talking about :

I have a series of objects in my business layer .. all wrappers around tableadapters. to give you an idea of the complexity of the other classes.

I should also mention that I made the Connection property public on the dataset so that I could open it at will in my business object and save some time opening and closing objects.

I use a base class for all the datasource objects (this is not production code and has now been completely changed to use base4)

This would be the base class :

    1 using System;

    2 using System.Collections.Generic;

    3 using System.Text;

    4 using NBlogr.Dal.NBlogrDataSetTableAdapters;

    5 using NBlogr.Dal;

    6 using System.ComponentModel;

    7 using System.Web;

    8 using System.Data.SqlClient;

    9 using System.Configuration;

   10 using System.Data;

   11 

   12 namespace NBlogr.Bll.Base

   13 {

   14     publicabstractclassDataSourceObject

   15     {

   16         protectedHttpContext _context;

   17         System.Web.Security.MembershipUser _user;

   18 

   19         privateNBlogrDataSet dataSet;

   20         privateSqlConnection connection;

   21         privatebool autoPersist;

   22         privateConnectionState previousState;

   23 

   24         publicbool AutoPersist

   25         {

   26             get { return autoPersist; }

   27             set { autoPersist = value; }

   28         }

   29 

   30 

   31         publicSqlConnection Connection

   32         {

   33             get

   34             {

   35                 if (connection == null)

   36                     this.connection = newSqlConnection(ConfigurationManager.ConnectionStrings["NBlogr.DAL.Properties.Settings.NBlogrConnectionString"].ConnectionString);

   37                 returnthis.connection;

   38             }

   39             set

   40             {

   41                 this.connection = value;

   42             }

   43         }

   44 

   45         publicNBlogrDataSet DataSet

   46         {

   47             get

   48             {

   49                 if (dataSet == null)

   50                     dataSet = newNBlogrDataSet();

   51                 return dataSet;

   52             }

   53             set { dataSet = value; }

   54         }

   55 

   56 

   57         public System.Web.Security.MembershipUser User

   58         {

   59             get {

   60                 if (_user == null)

   61                     _user = System.Web.Security.Membership.GetUser();

   62                 return _user; }

   63             set { _user = value; }

   64         }

   65 

   66         publicGuid UserId

   67         {

   68             get

   69             {

   70                 return (Guid)User.ProviderUserKey;

   71             }           

   72         }

   73 

   74         public DataSourceObject()

   75         {

   76             _context = HttpContext.Current;

   77         }

   78 

   79         protectedvoid OpenConnection(){

   80                 previousState = this.Connection.State;

   81             if (this.Connection.State != ConnectionState.Open)

   82                 Connection.Open();

   83         }

   84 

   85         protectedvoid CloseConnection(bool force)

   86         {

   87             if (previousState == ConnectionState.Closed||force)

   88             {

   89                 Connection.Close();

   90             }

   91         }

   92         protectedvoid CloseConnection()

   93         {

   94             CloseConnection(AutoPersist);

   95         }

   96     }

   97 }


 


And this is the object that gets the complete entries from the database and saves them again.


 

    1 using System;

    2 using System.Collections.Generic;

    3 using System.Text;

    4 using NBlogr.Dal.NBlogrDataSetTableAdapters;

    5 using System.ComponentModel;

    6 using NBlogr.Dal;

    7 using System.Web;

    8 using System.Transactions;

    9 

   10 namespace NBlogr.Bll

   11 {

   12     [DataObject]

   13     publicclassFullEntry : Base.DataSourceObject

   14     {

   15         Entry entryObject;

   16         Comment commentObject;

   17         Category categoryObject;

   18         Attachment attachmentObject;

   19         Blog blogObject;

   20         EntryTableAdapter taEntry = newEntryTableAdapter();

   21         CategoryTableAdapter taCategory = newCategoryTableAdapter();

   22 

   23         EntryCategoryTableAdapter taEntryCategory;

   24         EntryAttachmentTableAdapter taEntryAttachment;

   25 

   26         public FullEntry()

   27         {

   28             entryObject = newEntry(false);

   29             commentObject = newComment(false);

   30             categoryObject = newCategory(false);

   31             attachmentObject = newAttachment(false);

   32             blogObject = newBlog(false);

   33 

   34             taEntryAttachment = newEntryAttachmentTableAdapter();

   35             taEntryCategory = newEntryCategoryTableAdapter();

   36             taEntryCategory.ClearBeforeFill = false;

   37             taEntryAttachment.ClearBeforeFill = false;

   38             entryObject.Connection = commentObject.Connection = entryObject.Connection = categoryObject.Connection =

   39                 taEntryCategory.Connection = taEntryAttachment.Connection = this.Connection;

   40             entryObject.DataSet = commentObject.DataSet = entryObject.DataSet = categoryObject.DataSet = this.DataSet;

   41         }

   42 

   43         publicNBlogrDataSet.EntryRow GetById(Guid Id)

   44         {

   45             OpenConnection();

   46 

   47             attachmentObject.GetByEntry(Id);

   48             commentObject.GetByEntry(Id);

   49             categoryObject.GetByEntry(Id);

   50             taEntryCategory.FillByEntry(DataSet.EntryCategory, Id);

   51             taEntryAttachment.FillByEntry(DataSet.EntryAttachment, Id);

   52 

   53             NBlogrDataSet.EntryRow entry = entryObject.GetRow(Id);

   54 

   55             blogObject.FindById(entry.BlogId);

   56 

   57             CloseConnection(true);

   58 

   59             return entry;

   60         }

   61 

   62         [DataObjectMethod(DataObjectMethodType.Select)]

   63         publicNBlogrDataSet.EntryDataTable GetEntryListByBlogId(Guid BlogId)

   64         {

   65             OpenConnection();

   66 

   67             categoryObject.GetByBlog(BlogId);

   68             taEntryCategory.FillByBlogId(DataSet.EntryCategory, BlogId);

   69             entryObject.GetByBlog(BlogId);

   70 

   71             CloseConnection(true);

   72 

   73             return DataSet.Entry;

   74         }

   75 

   76         [DataObjectMethod(DataObjectMethodType.Select)]

   77         publicNBlogrDataSet.EntryDataTable GetFrontpageEntryList(Guid BlogId)

   78         {

   79             OpenConnection();

   80 

   81             categoryObject.GetByBlog(BlogId);

   82             taEntryCategory.FillByBlogId(DataSet.EntryCategory, BlogId);

   83             entryObject.GetFrontPage(BlogId);

   84 

   85             CloseConnection(true);

   86 

   87             return DataSet.Entry;

   88         }

   89 

   90         [DataObjectMethod(DataObjectMethodType.Select)]

   91         publicNBlogrDataSet.EntryDataTable GetEntryListByMonthYear(decimal Month, decimal Year, Guid BlogId)

   92         {

   93             OpenConnection();

   94 

   95             categoryObject.GetByBlog(BlogId);

   96             taEntryCategory.FillByBlogId(DataSet.EntryCategory, BlogId);

   97             entryObject.GetByMonthYear(BlogId, Month, Year);

   98 

   99             CloseConnection(true);

  100 

  101             return DataSet.Entry;

  102         }

  103 

  104         [DataObjectMethod(DataObjectMethodType.Select)]

  105         publicNBlogrDataSet.EntryDataTable GetEntryListByCategory(string CategoryName, Guid BlogId)

  106         {

  107             OpenConnection();

  108 

  109             Guid categoryId = categoryObject.GetIdByName(CategoryName);

  110             categoryObject.GetById(categoryId);

  111             taEntryCategory.FillByCategory(DataSet.EntryCategory, categoryId);

  112             entryObject.GetByCategory(categoryId,BlogId);

  113 

  114             CloseConnection(true);

  115 

  116             return DataSet.Entry;

  117         }

  118 

  119         publicNBlogrDataSet.BlogRow GetDefaultBlog()

  120         {

  121             return blogObject.GetDefault()[0];

  122         }

  123 

  124 

  125         publicvoid AddComment(Guid Id, string Body, string AuthorName, string AuthorEmail, string AuthorHomepage, string AuthorIpAddress)

  126         {

  127             commentObject.Add(Id, Body, AuthorName, AuthorEmail, AuthorHomepage, AuthorIpAddress);

  128         }

  129 

  130         publicvoid AddFiles(HttpFileCollection files)

  131         {

  132             foreach (HttpPostedFile file in files)

  133             {

  134                 attachmentObject.Save(file);

  135             }

  136         }

  137 

  138         publicGuid AddEntry(Guid BlogId, string Title, string Body, bool IsPublic, bool Syndicated, bool ShowOnFrontPage, bool AllowComments, DateTime? CreateDate, List<Guid> Categories)

  139         {

  140             Guid Id = Guid.Empty;

  141             OpenConnection();

  142 

  143             try

  144             {

  145                 Id = entryObject.Add(BlogId, Title, Body, IsPublic, Syndicated, ShowOnFrontPage, AllowComments, CreateDate);

  146 

  147                 entryObject.Persist();

  148 

  149                 foreach (Guid category in Categories)

  150                 {

  151                     taEntryCategory.Insert(category, Id);

  152                 }

  153             }

  154             catch { }

  155             finally

  156             {

  157 

  158                 CloseConnection(true);

  159             }

  160 

  161             return Id;

  162         }

  163 

  164         publicvoid UpdateEntry(Guid BlogId, string Title, string Body, bool IsPublic, bool Syndicated, bool ShowOnFrontPage, bool AllowComments, DateTime? CreateDate, List<Guid> Categories, List<Guid> RemovedCategories, Guid Original_Id)

  165         {

  166 

  167             OpenConnection();

  168 

  169             try

  170             {

  171                 entryObject.Update(BlogId, Title, Body, IsPublic, Syndicated, ShowOnFrontPage, AllowComments, CreateDate,Original_Id);

  172 

  173                 entryObject.Persist();

  174 

  175                 taEntryCategory.FillByEntry(DataSet.EntryCategory, Original_Id);

  176 

  177                 foreach (Guid category in Categories)

  178                 {

  179                     if (DataSet.EntryCategory.FindByCategoryIdEntryId(category, Original_Id) == null)

  180                         taEntryCategory.Insert(category, Original_Id);                   

  181                 }

  182                 foreach (Guid category in RemovedCategories)

  183                 {

  184                     if (DataSet.EntryCategory.FindByCategoryIdEntryId(category, Original_Id) != null)

  185                         taEntryCategory.Delete(category, Original_Id);

  186                 }

  187             }

  188             catch { }

  189             finally

  190             {

  191 

  192                 CloseConnection(true);

  193             }

  194         }

  195 

  196         publicvoid DeleteEntry(Guid EntryId)

  197         {

  198             OpenConnection();

  199 

  200             NBlogrDataSet.EntryRow entry = GetById(EntryId);

  201 

  202             foreach (NBlogrDataSet.EntryAttachmentRow attachment in DataSet.EntryAttachment)

  203             {

  204                 attachment.Delete();

  205             }

  206             foreach (NBlogrDataSet.EntryCategoryRow category in DataSet.EntryCategory)

  207             {

  208                 category.Delete();

  209             }

  210             foreach (NBlogrDataSet.CommentRow comment in DataSet.Comment)

  211             {

  212                 comment.Delete();

  213             }

  214 

  215             entry.Delete();

  216 

  217             taEntryAttachment.Update(DataSet.EntryAttachment);

  218             taEntryCategory.Update(DataSet.EntryCategory);

  219             commentObject.Persist();

  220             entryObject.Persist();

  221 

  222             CloseConnection();

  223         }

  224 

  225     }

  226 }

 

Then all that is left to do is show you the code from the page and you know how I did it with success

 

So this is the declarative part :

 

<%
@

Page
Language
=”C#”
MasterPageFile
=”~/NBlogrMaster.master”
AutoEventWireup
=”true”
CodeFile
=”Default.aspx.cs”
Inherits
=”_Default”
Title
=”NBlogr – Open Source Atlas Blogging”
%>


 

<
asp
:
Content

ID
=”Content2″
ContentPlaceHolderID
=”SideBarTop”
runat
=”Server”>


 


asp
:
Content
>

<
asp
:
Content

ID
=”Content1″
ContentPlaceHolderID
=”Main”
Runat
=”Server”>


    



                



   
<
asp
:
GridView
ID
=”gvEntries”
AutoGenerateColumns
=”false”
DataSourceID
=”odsFullEntry”
Width
=”100%”
GridLines
=”none”
runat
=”server”
ShowHeader
=”false”
OnRowDataBound
=”gvEntries_RowDataBound”
DataKeyNames
=”Id”
>


       
<
Columns
>


           
<
asp
:
TemplateField
>


               
<
ItemTemplate
>


                   



            
       
<
asp
:
Image
SkinID
=”postbullet”
ID
=”postBullet”
AlternateText
=’
<%# Eval(“Title”) %>runat=”server”/><b><%# Eval(“Created”,”{0:dddd, dd MMMM yyyy}”) %>b>


                   
<
hr
/>


                   
<
div
>


      
                   
<
h5
><
asp
:
HyperLink
ID
=”hlTitle”
NavigateUrl
=’
<%# Eval(“Id”,”~/Detail.aspx?entry={0}”) %>Text=’<%# Eval(“Title”) %>runat=”server”>asp:HyperLink>h5>


      
                   
<%
# Eval(“Body”) %>                     


                   

div
>


                   
<
hr
/>


                   
<
div
style
=”float:right”><
asp
:
Literal
ID
=”litCategories”
runat
=”server”>
asp
:
Literal
>
div
>


                   
<%
# Eval(“Created”,”{0:r}”) %>


               

ItemTemplate
>


              



           

asp
:
TemplateField
>


       

Columns
>


       
<
EmptyDataTemplate
>


            There are currently no posts available. Try again later.


       

EmptyDataTemplate
>


   

asp
:
GridView
>


   
<
asp
:
ObjectDataSource
ID
=”odsCategories”
runat
=”server”
InsertMethod
=”Add”
OldValuesParameterFormatString
=”original_{0}”


           
SelectMethod
=”GetAll”
TypeName
=”NBlogr.BLL.Category”>


           
<
InsertParameters
>


               
<
asp
:
ControlParameter
Name
=”Name”
Type
=”String”
ControlID
=”Category”
PropertyName
=”Text”
/>


           

InsertParameters
>


       

asp
:
ObjectDataSource
>
   



 



   
<
asp
:
ObjectDataSource
ID
=”odsFullEntry”
runat
=”server”
OldValuesParameterFormatString
=”original_{0}”
OnObjectCreated
=”odsFullEntry_ObjectCreated”
SelectMethod
=”GetFrontpageEntryList”
TypeName
=”NBlogr.Bll.FullEntry”>


       
<
SelectParameters
>


           
<
asp
:
SessionParameter
Name
=”BlogId”
SessionField
=”CurrentBlog”
Type
=”Object”
/>


       

SelectParameters
>


   

asp
:
ObjectDataSource
>
      



   
<
asp
:
ObjectDataSource
ID
=”odsFullEntryMonthYear”
runat
=”server”
OnObjectCreated
=”odsFullEntry_ObjectCreated”
OldValuesParameterFormatString
=”original_{0}”
SelectMethod
=”GetEntryListByMonthYear”
TypeName
=”NBlogr.Bll.FullEntry”
>


       
<
SelectParameters
>


           
<
asp
:
QueryStringParameter
Name
=”Month”
QueryStringField
=”month”
Type
=”Decimal”
/>


           
<
asp
:
QueryStringParameter
Name
=”Year”
QueryStringField
=”year”
Type
=”Decimal”
/>


           
<
asp
:
SessionParameter
Name
=”BlogId”
SessionField
=”currentBlog”
Type
=”Object”
/>


       

SelectParameters
>


   

asp
:
ObjectDataSource
>


   
<
asp
:
ObjectDataSource
ID
=”odsFullEntryCategory”
runat
=”server”
OnObjectCreated
=”odsFullEntry_ObjectCreated”
OldValuesParameterFormatString
=”original_{0}”
SelectMethod
=”GetEntryListByCategory”
TypeName
=”NBlogr.Bll.FullEntry”>


       
<
SelectParameters
>


           
<
asp
:
QueryStringParameter
Name
=”CategoryName”
QueryStringField
=”category”
Type
=”String”
/>


           
<
asp
:
SessionParameter
Name
=”BlogId”
SessionField
=”CurrentBlog”
Type
=”Object”
/>


       

SelectParameters
>


   

asp
:
ObjectDataSource
>


asp
:
Content
>


 


 





 

And here is the code behind. The bit you’re interested in, is the gvEntries_RowDataBound and setDataSource method:

 

    1 using System;

    2 using System.Data;

    3 using System.Configuration;

    4 using System.Collections;

    5 using System.Web;

    6 using System.Web.Security;

    7 using System.Web.UI;

    8 using System.Web.UI.WebControls;

    9 using System.Web.UI.WebControls.WebParts;

   10 using System.Web.UI.HtmlControls;

   11 using NBlogr.Bll;

   12 using NBlogr.Dal;

   13 using System.Collections.Generic;

   14 using System.Collections.Specialized;

   15 using NBlogr.Dal.NBlogrDataSetTableAdapters;

   16 

   17 publicpartialclass_Default : System.Web.UI.Page

   18 {

   19 

   20     FullEntry entryObject = newFullEntry();

   21 

   22 

   23     public _Default()

   24     {

   25 

   26         this.LoadComplete += newEventHandler(_Default_LoadComplete);

   27     }

   28 

   29     void _Default_LoadComplete(object sender, EventArgs e)

   30     {

   31         if (!IsPostBack)

   32         {

   33             setDataSource();

   34         }

   35     }

   36 

   37     privateBlogListRetrieval displayMode()

   38     {

   39         if(!string.IsNullOrEmpty(Request.QueryString["category"])) returnBlogListRetrieval.ByCategory;

   40 

   41         string year = Request.QueryString["year"];

   42         string month = Request.QueryString["month"];

   43         if (!string.IsNullOrEmpty(year) && !string.IsNullOrEmpty(month))

   44         {

   45                 returnBlogListRetrieval.ByMonthYear;

   46         }

   47         returnBlogListRetrieval.HomePage;

   48     }

   49 

   50     protectedvoid Page_Load(object sender, EventArgs e)

   51     {

   52     }

   53     privatevoid setDataSource()

   54     {

   55         gvEntries.DataSource = null;

   56         switch (displayMode())

   57         {

   58             default:

   59             caseBlogListRetrieval.HomePage:

   60                 gvEntries.DataSourceID = odsFullEntry.ID;

   61                 break;

   62             caseBlogListRetrieval.ByMonthYear:

   63                 gvEntries.DataSourceID = odsFullEntryMonthYear.ID;

   64                 break;

   65             caseBlogListRetrieval.ByCategory:

   66                 gvEntries.DataSourceID = odsFullEntryCategory.ID;

   67                 break;

   68 

   69         }

   70 

   71     }

   72 

   73     protectedvoid gvEntries_RowDataBound(object sender, GridViewRowEventArgs e)

   74     {

   75         if (e.Row.RowType == DataControlRowType.DataRow)

   76         {

   77             if (e.Row.RowState == DataControlRowState.Normal || e.Row.RowState == DataControlRowState.Alternate)

   78             {

   79                 Literal litCategories = ((Literal)e.Row.FindControl(“litCategories”));

   80                 litCategories.Text = “”;

   81                 NBlogrDataSet.EntryCategoryRow[] entrycats = entryObject.DataSet.Entry[e.Row.DataItemIndex].GetEntryCategoryRows();

   82                 foreach (NBlogrDataSet.EntryCategoryRow entrycat in entrycats)

   83                 {

   84 

   85                     litCategories.Text += entrycat.CategoryRow.Name + ” | “;

   86                 }

   87                 if (entrycats.Length > 0)

   88                     litCategories.Text = litCategories.Text.Remove(litCategories.Text.LastIndexOf(” | “));

   89 

   90             }

   91             elseif(e.Row.RowState == DataControlRowState.Edit)

   92             {

   93                 CheckBoxList lst = (CheckBoxList)e.Row.FindControl(“CategoryList”);

   94                 NBlogrDataSet.EntryCategoryRow[] entrycats = entryObject.DataSet.Entry[e.Row.RowIndex].GetEntryCategoryRows();

   95                 foreach (NBlogrDataSet.EntryCategoryRow entrycat in entrycats)

   96                 {

   97                     lst.Items.FindByValue(entrycat.CategoryId.ToString()).Selected = true;

   98                 }

   99 

  100             }

  101         }

  102 

  103 

  104     }

  105 

  106 

  107     protectedvoid odsFullEntry_ObjectCreated(object sender, ObjectDataSourceEventArgs e)

  108     {

  109         e.ObjectInstance = entryObject;

  110     }

  111 }

15AugThe thing I re-learned again

I feel so stupid sometimes and today was such a day.. I’d been putting of reinstalling my pc for a  while now.
I had installed vista on it but my machine just isn’t fast enough.

The thing I’ve re-learned today is when installing a pc install the virus scanner last or disable it  during the install period. It shaved about 1 hour of my visual studio installation.

All in all I think that feature saves me about 6 hours over the whole install.

11AugThis blog has joined technorati

I am now listed on technorati

Technorati Profile

11AugFaces for Lebanon

A while ago I decided that I wouldn’t reblog somebody else’s posts. But I have to make an exception today because of what’s going on in the world.

People that have the chance to meet me in person can ask me for my view on that whole situation but I don’t want to write a whole book here.



As my friend Miel blogs :


Faces4Lebanon.org

seeks to demonstrate the solidarity of people with Lebanon and the Lebanese people. Millions of people around the world are calling for an immediate halt of all acts of aggression against Lebanon, and the humanitarian catastrophe that is worsening everyday.


Faces4Lebanon.org

aims to spread the words of millions who want to send a message to the world that they are against all acts of violence and aggression. By publishing your photo on

Faces4Lebanon.org

, you will contribute to the buzz we want to create globally and attract as much media attention as possible in a highly civilized and unique manner. Furthermore, your contribution will document the world’s solidarity with Lebanon and the widespread infuriation from this aggression on Lebanon.

Stop the madness! War isn’t the answer! It never is!

 

11AugUser group atlas presentations

This week I went to do a couple of presenations on atlas in the regional user groups here in New Zealand.

At first I was really nervous, so I apologise to the people in hamilton for not getting the best presenation I could give you, I even forgot some stuff that would make all the pieces fit together.

But after the first talk I started to get the hang of it, and now I regret that I can’t do more talks but who knows what the future brings.

It was really interesting to see that there are a lot of really skilled people with a passion for programming in New Zealand.

 

So in all I would like to thank everybody for taking the time to come and listen to my ramblings on Atlas.
And perhaps we’ll meet on Teched next week.

 


Recent Flickrs

    Blogroll

    Recent Listening

    Scrobbler