Wednesday, March 23, 2011

Sitefinity - Custom Pollbox

I have created a custom PollBox  for Sitefinity to display Poll Questions and Results.

Why Custom PollBox?

Sitefinity  had its Rad Control to display poll questions and poll results.But the default RadChart control to display the results, uses images  to display graphical results.This is fine and working properly when we host our application on a single Web server. If we use Server farm with Load balance, We will get an error "RadChart image not found" and the results box will not display properly.

Even if we set the property 'Use Session" to false, the same error remains on the Web Farm.

Then I came up with a Custom poll box, which displays the poll results in pure html.It avoids the images and the error vanished.

Custom Pollbox Advantages:

1.)As it is showing all poll results in pure html, we have full control on Bar colors and width and heights.We can manipulate these with css.
2.) On the admin Side u can add this user control  by drag and drop as we add the default poll box.
3.) We can select the poll Id as we select it for default PollBox.
4.) We can specify User Blocking time in Hours .If we set this time,  a cookie will be created on the user machine and will block the user to vote again for a specified time in Hours.
5.) We can give our own Bar Colors and Main Colors and Horizontal Width of the Graph.
6.) We can customize this Custom Pollbox according to our requirements.

Screen shots:



Code:

you can download the code files  from the below link

https://docs.google.com/leaf?id=0B0LGUQrVMkGoNzc4ZGFhNzUtNjE4Yy00MDYyLThiYmQtM2E2MjU0YjA4MTc2&hl=en

CustomPollBox.ascx

<%@ Control Language="C#" AutoEventWireup="true" CodeFile="CustomPollBox.ascx.cs" Inherits="UC_CustomPollBox" %>
<div class="pollBox" >
<asp:Repeater runat="server" ID="rptPoll" OnItemDataBound="rptPoll_ItemDataBound" >
<ItemTemplate>
<div class="pollQuestion" >
<asp:Literal ID="litQuestion" runat="server" ></asp:Literal>
</div>
<asp:RadioButtonList ID="rblAnswers" runat="server" ></asp:RadioButtonList>
</ItemTemplate>
</asp:Repeater>

<asp:Repeater runat="server" ID="rptResults" OnItemDataBound="rptResults_ItemDataBound" Visible="false" >
<ItemTemplate>
<div class="pollQuestion" >
<asp:Literal ID="litQuestion" runat="server" ></asp:Literal>
</div>
<asp:Panel ID="pnlGraph" runat="server" ></asp:Panel>
</ItemTemplate>
</asp:Repeater>
<div class="pollBtnContainer" >
<asp:Literal ID="litTotalVotes" runat="server" Visible="false"></asp:Literal>
<asp:PlaceHolder ID="plhVoteButton" runat="server">
<a class="buttonLeftNew btn_BlueLeftNew" onmouseover="javascript:AddUndeline(this.id);" onmouseout="javascript:RemoveUndeline(this.id);" id="btnVoteLink" >
<asp:Button ID="btnVote" runat="server" Text="Submit" CssClass="btnMiddleNew btn_BlueMiddleNew buttonInput" OnClick="btnVote_Clicked" CausesValidation="true" onmouseover="javascript:AddUndeline(this.id);" onmouseout="javascript:RemoveUndeline(this.id);" />
</a>
</asp:PlaceHolder>
</div>
</div>

CustomPollBox.ascx.cs

using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.UI;
using System.Web.UI.WebControls;
using System.ComponentModel;
using Telerik.Cms.Web.UI;
using Telerik.Polls;
using System.Collections;
using System.Drawing;

public partial class UC_CustomPollBox : System.Web.UI.UserControl
{
[Description("Gets or sets the ID of the poll which will be displayed")]
[Bindable(true)]
[WebEditor("Telerik.Polls.WebControls.PollBoxEditor, Telerik.Polls")]
[DisplayName("Poll ID")]
public Guid PollID { get; set; }

[PersistenceMode(PersistenceMode.Attribute)]
[Description("Chart background main color")]
[NotifyParentProperty(true)]
[TypeConverter(typeof(ColorConverter))]
[DefaultValue(typeof(Color), "240, 248, 255")]
[DisplayName("Main Color")]
public Color MainColor { get; set; }

[NotifyParentProperty(true)]
[DefaultValue(150f)]
public float Width { get; set; }

[Description("Chart plot area main color")]
[NotifyParentProperty(true)]
[TypeConverter(typeof(ColorConverter))]
[PersistenceMode(PersistenceMode.Attribute)]
[DefaultValue(typeof(Color), "153, 209, 248")]
[DisplayName("Bar Color")]
public Color BarColor { get; set; }

[Description("Block user to resubmit the poll (in hours)")]
[DisplayName("Block Time")]
public int BlockTime { get; set; }

PollManager pollManager;


protected void Page_Load(object sender, EventArgs e)
{
pollManager = new PollManager();

if (BarColor.A == 0 && BarColor.B == 0 && BarColor.G == 0 && BarColor.R == 0)
BarColor = Color.FromArgb(153, 209, 248);

if (MainColor.A == 0 && MainColor.B == 0 && MainColor.G == 0 && MainColor.R == 0)
MainColor = Color.FromArgb(240, 248, 255);
if (Width == 0)
Width = 150;

if (BlockTime == 0)
BlockTime = 120;

if(!IsPostBack)
{
if (PollID != null)
{
double total = pollManager.GetPollById(PollID).VoterNumber;
if (Request.Cookies[PollID.ToString()] != null && total > 0)
{
DisplayPollResults();
}
else
BindQuestionsRepeater();
}
}
}

protected void rptPoll_ItemDataBound(object sender, RepeaterItemEventArgs e)
{
if (e.Item.ItemType == ListItemType.Item || e.Item.ItemType == ListItemType.AlternatingItem)
{
PollQuestion question = e.Item.DataItem as PollQuestion;
List<PollAnswer> answersList = PollHelper.GetAnswersByQuestionID(question.ID);
RadioButtonList rblAnswers = e.Item.FindControl("rblAnswers") as RadioButtonList;

Literal litQuestion = e.Item.FindControl("litQuestion") as Literal;
litQuestion.Text = question.Text;

rblAnswers.DataSource = answersList;
rblAnswers.DataTextField = "Text";
rblAnswers.DataValueField = "ID";
rblAnswers.DataBind();

}
}

protected void btnVote_Clicked(object sender, EventArgs e)
{
foreach (RepeaterItem item in rptPoll.Items)
{
RadioButtonList rblAnswers = item.FindControl("rblAnswers") as RadioButtonList;
if (!string.IsNullOrEmpty(rblAnswers.SelectedValue))
{
pollManager.IncrementAnswerCount(new Guid(rblAnswers.SelectedValue), 1);
}
}

IPollItem poll = pollManager.GetPollById(PollID);
if (poll != null)
{
poll.VoterNumber++;
pollManager.UpdatePoll(poll);
}
DisplayPollResults();
SetCookie();
Response.Redirect(Request.RawUrl);
}

private void BindQuestionsRepeater()
{
rptPoll.DataSource = PollHelper.GetQuestionsByPollID(PollID);
rptPoll.DataBind();
}

private void DisplayPollResults()
{
rptPoll.Visible = false;
plhVoteButton.Visible = false;
rptResults.Visible = true;

rptResults.DataSource = PollHelper.GetQuestionsByPollID(PollID);
rptResults.DataBind();
}

protected void rptResults_ItemDataBound(object sender, RepeaterItemEventArgs e)
{
PollQuestion question = e.Item.DataItem as PollQuestion;
List<PollAnswer> answersList = PollHelper.GetAnswersByQuestionID(question.ID);

Literal litQuestion = e.Item.FindControl("litQuestion") as Literal;
litQuestion.Text = question.Text;

Panel chartPanel = e.Item.FindControl("pnlGraph") as Panel;
chartPanel.Controls.Add(LoadGraph(question));
}


private Table LoadGraph(PollQuestion questionItem)
{
double total = pollManager.GetPollById(PollID).VoterNumber;
litTotalVotes.Text = string.Format("Total Votes: {0}", total);
litTotalVotes.Visible = true;
IList<PollAnswer> answersList = PollHelper.GetAnswersByQuestionID(questionItem.ID);

Table table = new Table();
table.CssClass = "pollBoxTable";

double iWidth = 0;
Unit uWidth = 0;
string sWidth = (int)Width + "px";
table.Width = Unit.Pixel((int)Width);

if (sWidth.IndexOf("%") > -1)
{
iWidth = Convert.ToInt32(sWidth.Substring(0, sWidth.IndexOf("%")));
iWidth = iWidth / 10;
}
else
{
if (sWidth.IndexOf("px") > -1)
{
iWidth = Convert.ToInt32(sWidth.Substring(0, sWidth.IndexOf("px")));
}
else
{
iWidth = Convert.ToInt32(sWidth);
}
iWidth = iWidth / 100;
}

for (int i = 0; i < answersList.Count; i++)
{
TableRow tr = new TableRow();

TableCell td1 = new TableCell();
tr.Cells.Add(td1);


Panel container = new Panel();
container.BackColor = MainColor;
container.BorderColor = Color.White;
container.BorderWidth = Unit.Pixel(1);

Label lblBar = new Label();
double dblPercentage = (answersList[i].VoteCount/total) * 100;
lblBar.Width = Unit.Pixel(Convert.ToInt32(dblPercentage * iWidth));
lblBar.Height = Unit.Pixel(20);
lblBar.BackColor = BarColor;
lblBar.Text = answersList[i].VoteCount.ToString();
lblBar.CssClass = "chartBar";

Label lblPercentage = new Label();
lblPercentage.Text = answersList[i].Text + "&nbsp;/&nbsp;" + Math.Round(dblPercentage, 2).ToString() + "%<br/>";
td1.Controls.Add(lblPercentage);


td1.Controls.Add(container);
container.Controls.Add(lblBar);


table.Rows.Add(tr);
}

return table;
}

/// <summary>
/// Returns the width set as pixels or percentage
/// </summary>
/// <param name="width"></param>
/// <returns></returns>
private Unit GetWidth(string width)
{
Unit retVal = new Unit(0);
try
{
int iWidth = 0;
if (width.IndexOf("%") > -1)
{
iWidth = Convert.ToInt32(width.Substring(0, width.IndexOf("%")));
retVal = Unit.Percentage(iWidth);
}
else
{
if (width.IndexOf("px") > -1)
{
iWidth = Convert.ToInt32(width.Substring(0, width.IndexOf("px")));
}
else
{
iWidth = Convert.ToInt32(width);
}
retVal = Unit.Pixel(iWidth);
}
return retVal;
}
catch { return retVal; }
}

/// <summary>
/// Sets a cookie. Prevents multiple entries from a computer
/// </summary>
private void SetCookie()
{
HttpCookie cookie = new HttpCookie(PollID.ToString(), DateTime.Now.ToString());
cookie.Expires = DateTime.Now.AddHours(BlockTime);
Response.Cookies.Set(cookie);
}


}

App_Code/PollHelper.cs

using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Data.SqlClient;
using System.Configuration;

/// <summary>
/// Summary description for PollHelper
/// </summary>
public class PollHelper
{
//public static PollHelper PollHelper = new PollHelper();
    public PollHelper()
    {
        
    }

public static List<PollQuestion> GetQuestionsByPollID(Guid pollID)
{
List<PollQuestion> pollQuestions = new List<PollQuestion>();
SqlConnection connection = new SqlConnection(ConfigurationManager.ConnectionStrings["Sitefinity"].ConnectionString);
using (connection)
{
try
{
connection.Open();
SqlCommand commad = new SqlCommand(string.Format("select * from dbo.sf_Polls_QuestionData where PollID = @PollID"), connection);
SqlParameter parameter = new SqlParameter("PollID", System.Data.SqlDbType.UniqueIdentifier);
parameter.Value = pollID;
commad.Parameters.Add(parameter);
SqlDataReader reader = commad.ExecuteReader(System.Data.CommandBehavior.CloseConnection);

while (reader.Read())
{
pollQuestions.Add(new PollQuestion((Guid)reader["ID"], (string)reader["Text"], (Guid)reader["PollID"]));
}
}
finally
{
connection.Close();
}
}
return pollQuestions;
}

public static List<PollAnswer> GetAnswersByQuestionID(Guid questionID)
{
List<PollAnswer> pollAnswers = new List<PollAnswer>();
SqlConnection connection = new SqlConnection(ConfigurationManager.ConnectionStrings["Sitefinity"].ConnectionString);
using (connection)
{
try
{
connection.Open();
SqlCommand commad = new SqlCommand(string.Format("select * from dbo.sf_Polls_AnswerData where QuestionID = @QuestionID"), connection);
SqlParameter parameter = new SqlParameter("QuestionID", System.Data.SqlDbType.UniqueIdentifier);
parameter.Value = questionID;
commad.Parameters.Add(parameter);
SqlDataReader reader = commad.ExecuteReader(System.Data.CommandBehavior.CloseConnection);

while (reader.Read())
{
pollAnswers.Add(new PollAnswer((Guid)reader["ID"], (string)reader["Text"], (Guid)reader["QuestionID"], (int)reader["VoteCount"]));
}
}
finally
{
connection.Close();
}
}

return pollAnswers;
}

}

public class PollQuestion
{
private Guid iD;
private string text;
private Guid pollID;

public Guid ID
{
get
{
return iD;
}
set
{
iD=value;
}
}

public Guid PollID
{
get
{
return pollID;
}
set
{
pollID=value;
}
}

public string Text
{
get
{
return text;
}
set
{
text=value;
}
}

public PollQuestion()
{
}

public PollQuestion(Guid ID,string Text,Guid PollID)
{
this.iD = ID;
this.pollID = PollID;
this.text = Text;
}
}


public class PollAnswer
{
private Guid iD;
private string text;
private Guid questionID;
private int voteCount;

public Guid ID
{
get
{
return iD;
}
set
{
iD = value;
}
}

public Guid QuestionID
{
get
{
return questionID;
}
set
{
questionID = value;
}
}

public string Text
{
get
{
return text;
}
set
{
text = value;
}
}

public int VoteCount
{
get
{
return voteCount;
}
set
{
voteCount = value;
}
}

public PollAnswer()
{
}

public PollAnswer(Guid ID, string Text, Guid QuestionID,int VoteCount)
{
this.iD = ID;
this.questionID = QuestionID;
this.text = Text;
this.voteCount = VoteCount;
}
}








 

Wednesday, September 09, 2009

Billiards Game developed in Silverlight

I have developed Billiards game in Silverlight .This game supports 8 ball and Pool. Below are the screens of this game and to play this game please click here



How to get content and text of each element of a Window

 Some times it is needed to get the content/text of  the children of a control.Then we have to iterate through all elements and should know its type.After comparing its type with the predefined types, we can cast that UIElement object to the particular object type.Then we can get/set its text/content values.Here is the sample code.

        foreach (UIElement oObject in this.LayoutRoot.Children)
            {

                Type type= oObject.GetType();
                string name=oObject.GetValue(NameProperty).ToString();
                if (type == typeof(TextBlock))
                {
                    TextBlock textBlock = oObject as TextBlock;
                    if (textBlock != null)
                    {
                        MessageBox.Show(textBlock.Text);
                    }
                }

                if (type == typeof(TextBox))
                {

                    TextBox textBox = oObject as TextBox;
                    if(textBox != null)
                    {

                        MessageBox.Show(textBox.Text);
                    }
                }
                if(type == typeof(ComboBox))
                {
                    ComboBox comboBox = oObject as ComboBox;

                    if(comboBox != null)
                    {

                        MessageBox.Show(comboBox.SelectedItem.ToString());

                    }

                }

                if(type==typeof(Button))

                {

                    Button button = oObject as Button;

                    if(button != null)

                    {

                        MessageBox.Show(button.Content.ToString());

                    }
                }        
}

Tuesday, September 08, 2009

.Net Technology Quest: Silverlight ComBoBox Selected Item not Setting

.Net Technology Quest: Silverlight ComBoBox Selected Item not Setting

Silverlight ComBoBox Selected Item not Setting

Here is the code I developed to Bind data to a ComboBox and set the selected Item. This code is tested and working fine. Xaml page

<UserControl x:Class="WorldOfVenkat.Page" xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" Width="900" Height="600">

<Canvas x:Name="LayoutRoot" Background="Black">

<ComboBox Name="comBoBox" Width="400" Height="30" ></ComboBox>

</Canvas>

</UserControl>

Code behind in C#

public partial class Page : UserControl

{ public Page()

{

InitializeComponent(); BindComBoBox(); }

private void BindComBoBox()

{

List<Country> coutries = new List<Country>();

Country India = new Country(1,"India");

Country USA = new Country(2, "USA");

Country Canada = new Country(3,"Canada");

coutries.Add(India);

coutries.Add(USA);

coutries.Add(Canada);

comBoBox.ItemsSource = coutries; comBoBox.DisplayMemberPath = "Name"; comBoBox.SelectedItem = Canada;

}

public class Country

{

public int ID { get; set; }

public string Name { get; set; }

public Country(int id,string name)

{

ID = id;

Name = name;

}

} }

Thursday, July 16, 2009

Fix Windows Live Messenger Not Remembering ID and Password

Suddenly my Windows live messenger stopped 'Auto login' even when I select the check boxes 'Remember me' and 'Remember my password'.This is because of Yahoo tool bar. Here is the fix for this problem.Please go through the below article posted by Raymond. Fix Windows Live Messenger Not Remembering ID and Password

Thursday, February 19, 2009

How to Enable Silver light Debugging


If we try to add a new silver light project to a solution, then Visual studio prompts with the following dialogue box.



So that we can enable debugging on this newly created silver light application. However if we wanted to add an existing silver light application to a solution which contains a website project then we have to explicitly enable debugging on this silver light application, otherwise Visual studio wont debug this silver light application, when we set the Web application as the start up project.


To enable debugging on this newly added existing silver light project.
1) In solution Explorer, Right click on the Web Project and select ‘Property Pages’ .Here is the screen shot to select ‘Property Pages’



2) In ‘Property pages’ Window in ‘Start Options’ , make sure that the check boxes ‘ASP.NET’ and ‘Silverlight ‘ both are selected.



3) Select ‘Silverlight Application’ then Click on the ‘Add’ button, it will open the following window. Select the check box ‘Enable Silverlight Debugging’ then press ‘Apply’ then ‘Ok’.


Tuesday, February 03, 2009

CSS: Shared Classes

CSS: Shared Classes

Summary: You can group styles common to different rules into their own classes to save repeating yourself. By applying multiple classes to one element in CSS you can modularize your code to help optimize your style sheets.

You can group styles common to different rules into their own classes to save repeating yourself. CSS2-compliant browsers can reference multiple classes within individual elements.

For example:

<div id="nav" class="nav center">...</div>

This ability to reference multiple classes gives authors newfound options when styling their content. For elements that share the same styles (text-align:center for example), you can group these shared styles into one shared class. So this:

<style type="text/css">

.nav{color:red; text-align:center;}

.main{color:#000; text-align:center;}

</style>

...

<div id="nav" class="nav">...</div>

<div id="main" class="main">...</div>

Becomes this after grouping the common center style into one shared class:

<style type="text/css">

.nav{color:red;}

.main{color:#000;}

.ctr{text-align:center;}

</style>

...

<div id="nav" class="nav ctr">...</div>

<div id="main" class="main ctr">...</div>

The third .ctr class groups the common styles (in this case the center declaration) into a class now shared by two elements. The additional class saves space by eliminating redundant common declarations, which can add up for larger style sheets. In effect, you are normalizing your CSS.

Here is a small example about styles with classes and Id.

<%@ Page Language="C#" AutoEventWireup="true" CodeFile="Default2.aspx.cs" Inherits="Default2" %>

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">

<html xmlns="http://www.w3.org/1999/xhtml">

<head>

<title>Shared Classes</title>

<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1" />

<style type="text/css">

body {

width: 40em;

font-family: Arial, Helvetica, sans-serif;

}

h1 {

font-size: 1.5em;

}

h2 {

font-size: 1.2em;

margin-top: 40px;

}

h3 {

font-size: 1.0em;

font-weight: bold;

}

h4 {

text-transform: uppercase;

font-size: 1.0em;

}

/*----these are the test classes and ids----*/

.orange {

color: orange;

}

.bold {

font-weight: bold;

}

#boldness {

font-weight: bold;

}

.orangegrouped.boldgrouped {

color:orange;

font-weight: bold;

}

#boldgroup.orangegroup {

color: orange;

font-weight: bold;

}

</style>

</head>

<body>

<h1>Applying multiple styles to HTML elements</h1>

<h2>Case I: Two separate classes applied to one element</h2>

<p class="orange bold">This text should be orange and bold. Two classes are applied to the <p> tag, "orange"

and "bold."</p>

<h2>Case II: A class and an ID applied to one element</h2>

<p class="orange" id="boldness">This text should be orange and bold. The <p> tag has the class "orange"

applied to it, and is assigned the id "boldness."</p>

<h2>case III: Two grouped classes applied to one element</h2>

<p class="orangegrouped boldgrouped">This text should be orange and bold. Two classes are applied to the <p>

tag, "orangegrouped" and "boldgrouped", which are defined together in the CSS.</p>

<h2>Case IV: Two grouped classes applied to one element in the opposite order</h2>

<p class="boldgrouped orangegrouped">This text should be orange and bold. Two classes are applied to the <p>

tag, "orangegrouped" and "boldgrouped", which are defined together in the CSS but in

the opposite order than they are applied in the <p> tag.</p>

<h2>Case V: A class and an ID grouped and applied to one element</h2>

<p class="orangegroup" id="boldgroup">This text should be orange and bold. The <p> tag has the class "orangegroup"

as well as the id "boldgroup" applied to it, which are defined together in the CSS.</p>

</body>

</html>

Conclusions

Netscape 4.x for Windows and Mac cannot support the application of multiple classes to a single element. It results in ignoring all classes. (Cases I, III, IV) It can, however, understand the application of a class and an id to a single element. (Case II) This technique only works, however, if the class and id are defined separately in the style sheet, not grouped together. (Test Case V)

Internet Explorer 4.x for Windows cannot support the application of multiple classes to a single element. It results in ignoring all classes. (Cases I, III, IV) It can, however, understand the application of a class and an id to a single element. (Case II) This technique works even if the class and id are grouped together in the style sheet, not defined separately. (Test Case V) In this respect IE 4.x differs from NN 4.x.