Implement PostBackUrl in Custom controls

One of the challenges I faced today is to create a custom  control that implement IButtonControl, everything works fine until I try to implement IPostBackUrl property. it never works for me, after a lot of research on the internet I didn’t find anything useful so I started to implement it myself. ok let’s get to the point, implementing PostBackUrl consists of 3 parts

1- implementing the property itself.

it’s the easy part, either save it in ViewState or in private variable, Let's just implement it as an automatic property.

 

public string PostBackUrl{ set; get;}

 

2- add a helper method to build the PostBackOption.

 

protected virtual PostBackOptions GetPostBackOptions() 
{ 
    PostBackOptions postBackOptions = new PostBackOptions(this, string.Empty); 
    postBackOptions.ClientSubmit = false; 
if (!string.IsNullOrEmpty(this.PostBackUrl)) 
{ 
        postBackOptions.ActionUrl = HttpUtility.UrlPathEncode(base.ResolveClientUrl(this.PostBackUrl)); 
} 
if (this.CausesValidation && this.Page != null && this.Page.GetValidators(this.ValidationGroup).Count > 0) 
{ 
        postBackOptions.PerformValidation = true; 
        postBackOptions.ValidationGroup = this.ValidationGroup; 
} 
return postBackOptions; 
}

 

direct the postback to another page, all you need to do is to put the other url in postbackoptions.ActionUrl. and then register this postback option. so in this part we build our postback options, the first line just create a new PostBackOptions object pass a control reference and argument if needed in its constructor in our situation I just pass an empty string as argument cuz I don’t need arguments.

if the postbackurl is not empty resolve the postbackurl and put it in ActionUrl property, carful to set the ActionUrl you need to pet it as available client url no ~/ sign allowed.

the next few lines allows the control to performe validation before postback. you can use it if your control need to cause validation.

3- the last part is to register this postbackoption to the control

 

protected override void AddAttributesToRender(HtmlTextWriter writer)

{

var postBackOptions = GetPostBackOptions();

string postBackEventReference = page.ClientScript.GetPostBackEventReference(postBackOptions, false);

writer.AddAttribute(HtmlTextWriterAttribute.Onclick, postBackEventReference);

}

 

the best place to register the postbackoptions is in the AddAttributesToRender which is called during the render. to add the valid attributes to the control.

there is a very helpful method in the Page.ClientScrip which is GetPostBackEventReference, this method translate the postbackoption object into a simple javascript method it also ensure the render of the available asp.net script that allow postbacks.

the last thing is to tie the javascript with a client event I picked the OnClick Event to do this but we can use any client event like blur, change or anything else based on the html tag we render.

In Conclusion.

PostBackUrl is very useful is some cases, you can use PreviosePage reference too. all you need is to create a postbackoption object set the ActionUrl to the other postbackurl you want. get the postbackUrlEventReference from the client script and tie it with a  client script event. and that’s it.

How to write a new BlogEngine.Net 2.0 theme

in this article i would like to show some basic steps to write a blogengine.Net theme.

there is 3 basic steps to write a theme for blogine

1- Create MasterPage
2- Create PostView.ascx
3- Create CommentView.ascx

 

- Download the blogengine.Net from http://blogengine.codeplex.com/ (source version),
- Open the solution with visual studio 2010.
- In the Folder “themes” Create a new folder with your theme name, it is preferable to add anything you need in this folder and do not modify any other folder in the site, I will referrers to this folder in this article as your Theme folder

Create your MasterPage theme.

in your theme folder add a new MasterPage call it “site.master” do not try to change the master page name. the name must be “site.master”.

Dynamic ITemplate

for Page developers ITemplate no a strange word, they never use it, but when you come to Control Developers, I faced it many times.

so what is Itemplate? Itemplate is any template you use in your asp.net web page. like the ItemTamplate, HeaderTemplate and FooterTemplate in the Repeater / DataList controls, by default asp.net compiler translate these templates into a separate class that inherits from System.Web.UI.Control, and add it in the control hierarchy. that's why you don't have access to any control in a template.

going to the point,  the problem here is that you want to set the Itemplate from code behind, lets say you want a custom grid view with Checkboxes as the first row whish is a common need. the straight forward solution is to create a new class that implements ITemplate. Itemplate has only one method InitializeIn and create your control hierarchy in there, in this situation is separated your logic in 2 classes one of them just contain 1 or 2 lines of code.

HERE COMES THE DYNAMIC ITEMPLATE, Dynamic Itemplate is a simple solution to this problem, its just an implementation to Itemplate that takes an Action<Control> as a parameter

public class DynamicTemplate : ITemplate
    {
        private readonly Action<Control> _templateBuilder;

        public DynamicTemplate(Action<Control> templateBuilder)
        {
            _templateBuilder = templateBuilder;
        }

        #region ITemplate Members

        public void InstantiateIn(Control container)
        {
            _templateBuilder(container);
        }

        #endregion
    }

as simple as that, of course we must add some validation if the Action is null. but for simplicity i will just leave it as it is.

if you just want to add a simple checkbox to your template you can use lambda expression to do so.

TemplateField checkBoxColumn = new TemplateField();
checkBoxColumn.ItemTemplate = new DynamicTemplate(
                        container => container.Controls.Add(new CheckBox()));

also if you have a complex controls you want to add just create your function and put it inside the constructor. so Dynamic Template is simply let you make all your control logic in your control class.  

Distinct By Property

In many many cases we use the Linq Methid 'Distinct', distinct is translated in many ways.

But in all cases it just has 2 overload, the first one take nothing as parameter, for linq to sql to is just translate the query to DISTINT Select in sql,for linq to object it checks for duplicated references, the second one takes IComparer to make the comparison between the 2 objects,

So I figure out why there is no overload that takes a lamda expression insted of IComparer, after moments of thinking got  a solution with the groupby method, we can group by the IEnumerable with a lamda selector then take the first of each group, like this :

List.GroupBy(t => t.PropertyToBeUsedForDistinct).Select(t => t.First());

to make it generic i made a simple function of one line of code.

public static IEnumerable Distinct(this IEnumerable list, Func comparer)
{
   return list.GroupBy(t => comparer.Invoke(t)).Select(s => s.First());
}

and then you can use it like this  

List<Entity> lst = GetList();
lst = lst.Distinct( e => e.Id);

maybe it is not the obtimum but as start i will share it with you, 
please dont use it with Linq To Sql, it will hit the database each time it uses the first method, maybe I will post a solution for linq to sql in later posts.

Comparing overlaped Dates

A new requirment came up this morning, a simple one too we need to compare 2 time periods if they are overlaped or not. simple tasks always take less time.

so i opend my visual studio, and start doing it , and BAM ... all the ideas that poup on my miend wont fix the issue. ok then google is the solution, another shok for today, I didnt got any answer. so i figure out lets start thinking again. and this time the solution come up simply.

so what is dates overlaping ? lets just represent these dates as rectangles

case 1 if the first date before the second and end before it

case 2 if the first date start after the second and end after it

case 3 if the first date start before the second and end after it.

so in short lets get the maximum start time and the minimum end time. this will retrive the intersection part of the date, if there is an intersection so there is an overlapping if no intersection so there isnt.

here is the code

int maximumStartDate = Math.Max(clinic.StartTime.Value.Ticks, 
                                       currentClinic.StartTime.Value.Ticks);
int minimumEndDate = Math.Min(clinic.EndTime.Value.Ticks, 
                                       currentClinic.EndTime.Value.Ticks);
return maximumStartDate <= minimumEndDate;

est voila. thats it .. a simple solution for a simple requirment ... cheers ...