I am working on a forum application using SQL Server and ASP.Net.
The application has facilities for creating topics and posting replies to specific topics. It must also have a facility for marking specific replies as accepted answers in which case the row gets highlighted in green color [very much like the facility we have
in our forum here]. There is a field in the database called 'AcceptedAnswer'[it belongs to a table called 'ForumMessages'] which is a bit type field. On marking an answer this should get updated to 'True'[by default it is 'False']. I have written the code
for implementing this but it is not working as per desired. The database is being updated as expected but the corresponding row in the databound control is not changing its color on clicking the button. I have used a datalist control to show messages and put
the button inside it. There is also a hiddenfield control which binds the value of the 'AcceptedAnswer' retrieved from database through stored procedure. To change the color dynamically I have used the 'onitemdatabound' attribute of the datalist.
Here is the mark up for the datalist::---
<asp:DataList ID="dLMessages" OnItemDataBound="dLMessages_DataBound" DataKeyField="MessageID" runat="server">
<ItemTemplate>
<table width="100%" style="background-color:#BCDDFE">
<tr>
<td valign="top">
<asp:Image ID="Image1" Width="40px" Height="40px" runat="server" ImageUrl="~/Styles/Messages-Icon.png" />
<b>Re:</b>
<asp:Label ID="Label1" runat="server" Text='<%# Eval("TopicSubject") %>' ForeColor="#FF3300" Font-Underline="True"></asp:Label>
<asp:HiddenField ID="hdnfld1" runat="server" Value='<%# Eval("AcceptedAnswer") %>' />
<asp:HiddenField ID="hdnfld2" runat="server" Value='<%# Eval("UserID") %>' />
<asp:HiddenField ID="hdnfld3" runat="server" Value='<%# Eval("MessageID") %>' />
</td>
</tr>
<tr>
<td valign="top">
<i>
<asp:Label ID="Label2" runat="server" Text='<%# Eval("MessageBody") %>'></asp:Label></i>
</td>
</tr>
<tr>
<td><b>
<asp:Label ID="Label4" runat="server" Text='<%# Eval("USignature") %>'></asp:Label></b></td>
</tr>
<tr>
<td><b>By:</b>
<asp:Label ID="lblAuthor" runat="server" Text='<%# Eval("Username") %>'></asp:Label>
</td>
</tr>
<tr>
<td><b>Posts</b>
<asp:Label ID="Label3" runat="server" Text='<%# Eval("PostCount") %>'></asp:Label>
</td>
</tr>
<tr style="background-color:Teal">
<td>
<table>
<tr>
<td>
<asp:Button ID="btnEditPost" runat="server" Text="EDIT" BackColor="#000066" ForeColor="Yellow" /></td>
<td>
<asp:Button ID="btnAcceptAnswer" CommandArgument='<%# Eval("MessageID") %>' OnClientClick="return confirm('Are you sure you want to mark this answer as accepted?')" OnClick="btnAcceptAnswer_Click" BackColor="#000066" ForeColor="Yellow" runat="server" Text="ACCEPT" />
</td>
</tr>
</table>
</ItemTemplate>
<SeparatorTemplate>
<hr style="color:Blue" />
</SeparatorTemplate>
</asp:DataList>
Here is the code block I am using to change color and to update the database::---
protected void btnAcceptAnswer_Click(object sender, EventArgs e)
{
Button btn = (Button)sender;
int messageid = Convert.ToInt32(btn.CommandArgument);
objbll.MarkAnswer(messageid);
this.BindPosts();
}
protected void dLMessages_DataBound(object sender, DataListItemEventArgs e)
{
if (e.Item.ItemType == ListItemType.Item)
{
HiddenField hdn = (HiddenField)e.Item.FindControl("hdnfld1");
if (Convert.ToBoolean(hdn.Value) == true)
{
dLMessages.ItemStyle.BackColor = Color.FromName("#A0FE96");
}
}
}
Here MarkAnswer() is the corresponding method in the BLL. This part is working fine but not the color changing operation. I have place the whole thing inside an update panel and a content template. Why is my code not working? Please help me find a solution
by steering my in the right direction and point out the errors in my code snippets. Look forward to receiving some active help on this one.
Many thanks in anticipation.
There are more wonders in this world of ours than you can wonder.....
From what I see you're binding hdnFld1 to AcceptedAnswer, which I guess is type of boolean, also I assume your DataSource returns whether the particular DataItem is AcceptedAnswer or not, so you can grab DataSource Item in ItemDataBound event, and check
whether AcceptedAnswer is true, here is some code snippet
Note thou that I assumed that you're binding to DataTable object. If it's some kind of collection of custom objects, make appropriate cast, and check the property on the object, and if you noticed I've added || condition to check if ItemType is AlternatinItem as well.
YourCustomObject msgItem = e.Item.DataItem as YourCustomObject;
// use msgItem.AcceptedAnswer;
I am using a stored procedure to fetch the data from database. In the business logic layer i have written the codes for fetching the data and returing a dataset which I have used in the code behind to bind to the datalist.
Here is the code block from the BLL::---
public DataSet GetPosts()
{
DataSet ds=new DataSet();
Hashtable ht = new Hashtable();
ht.Add("@ForumID", this.ForumID);
ht.Add("@TopicID", this.TopicID);
return objdal.ExecuteSelectSP(ds, ht, "sproc_GetPosts");
}
and this is the stored procedure I am using::---
CREATE procedure [dbo].[sproc_GetPosts]
@ForumID bigint,
@TopicID bigint
as
begin
select A.TopicSubject,
B.MessageBody,
B.MessageID,
B.CreationDate,
B.AcceptedAnswer,
C.Username,
C.UserID,
C.USignature,
C.PostCount
from ForumTopics A
join ForumMessages B
on A.TopicID =B.TopicID
join ForumUsers C
on C.UserID=B.UserID
where B.ForumID=@ForumID and B.TopicID=@TopicID
order by B.CreationDate asc
end
This is the code block where I am binding the dataset to the datalist::---
public void BindPosts()
{
DataSet ds = new DataSet();
objbll.ForumID = Convert.ToInt32(Session["forumid"].ToString());
objbll.TopicID = Convert.ToInt32(Session["topicid"].ToString());
ds = objbll.GetPosts();
pds.DataSource = ds.Tables[0].DefaultView;
pds.PageSize = 20;
pds.AllowPaging = true;
pds.CurrentPageIndex = CurrentPage;
dLMessages.DataSource = pds;
dLMessages.DataBind();
}
I don't understand what casts you are talking about. Please kindly explain it in a bit more totality with reference to the code blocks I have pasted here. It would be of much help to me.
Many Thanks.
There are more wonders in this world of ours than you can wonder.....
Item.DataItem represents data for each Item in your DataList, because your dataSource is list of DataRowViews, you need to cast Item.DataItem to DataRowView ( because Item.DataItem return type of object ). Then you need to check AcceptedAnswer on your datasource,
to see whethere backcolor should be seted or not.
here pds is an object of the paged data source class which I have used since I want to enable paging for the datalist. The data source for this 'pds' is the dataset returned by the method from the business access layer. I hope this is right with respect
to what I am trying to do.
As you can make sure from the link below, when you're calling DefaultView on DataTable, the return type is DataView. Did you tried the approach I suggest ? Are you facing issues, or you didn't even try ?
I am trying to incorporate your code. But there is another problem. After msgitem.Row intellisense isn't giving Item. Instead it is giving ItemArray. And there is an error.
This is the code block I am trying to use:---
protected void dLMessages_DataBound(object sender, DataListItemEventArgs e)
{
if (e.Item.ItemType == ListItemType.Item || e.Item.ItemType==ListItemType.AlternatingItem)
{
DataRowView msgitem = e.Item.DataItem as DataRowView;
if (msgitem != null)
{
if(Convert.ToBoolean(msgitem.Row.ItemArray["AcceptedAnswer"].ToString()))<---- this part is showing error.
}
}
}
There are more wonders in this world of ours than you can wonder.....
Problem not yet solved. I don't knwo what is happening. I tried to integrate the following piece of code but it is not working as per desired. The code is creating a series of outlines in that color specified insteAad of changing the color of the particular
row to that specified color. Everything seems ok with the code apparently. But I'm sure I'm making some silly mistake somewhere. Please help me with this typical situation.
PGChoudhury
Member
11 Points
131 Posts
Datalist Color Changing on Clicking a Button ---
Apr 27, 2012 11:01 AM|LINK
I am working on a forum application using SQL Server and ASP.Net.
The application has facilities for creating topics and posting replies to specific topics. It must also have a facility for marking specific replies as accepted answers in which case the row gets highlighted in green color [very much like the facility we have in our forum here]. There is a field in the database called 'AcceptedAnswer'[it belongs to a table called 'ForumMessages'] which is a bit type field. On marking an answer this should get updated to 'True'[by default it is 'False']. I have written the code for implementing this but it is not working as per desired. The database is being updated as expected but the corresponding row in the databound control is not changing its color on clicking the button. I have used a datalist control to show messages and put the button inside it. There is also a hiddenfield control which binds the value of the 'AcceptedAnswer' retrieved from database through stored procedure. To change the color dynamically I have used the 'onitemdatabound' attribute of the datalist.
Here is the mark up for the datalist::--- <asp:DataList ID="dLMessages" OnItemDataBound="dLMessages_DataBound" DataKeyField="MessageID" runat="server"> <ItemTemplate> <table width="100%" style="background-color:#BCDDFE"> <tr> <td valign="top"> <asp:Image ID="Image1" Width="40px" Height="40px" runat="server" ImageUrl="~/Styles/Messages-Icon.png" /> <b>Re:</b> <asp:Label ID="Label1" runat="server" Text='<%# Eval("TopicSubject") %>' ForeColor="#FF3300" Font-Underline="True"></asp:Label> <asp:HiddenField ID="hdnfld1" runat="server" Value='<%# Eval("AcceptedAnswer") %>' /> <asp:HiddenField ID="hdnfld2" runat="server" Value='<%# Eval("UserID") %>' /> <asp:HiddenField ID="hdnfld3" runat="server" Value='<%# Eval("MessageID") %>' /> </td> </tr> <tr> <td valign="top"> <i> <asp:Label ID="Label2" runat="server" Text='<%# Eval("MessageBody") %>'></asp:Label></i> </td> </tr> <tr> <td><b> <asp:Label ID="Label4" runat="server" Text='<%# Eval("USignature") %>'></asp:Label></b></td> </tr> <tr> <td><b>By:</b> <asp:Label ID="lblAuthor" runat="server" Text='<%# Eval("Username") %>'></asp:Label> </td> </tr> <tr> <td><b>Posts</b> <asp:Label ID="Label3" runat="server" Text='<%# Eval("PostCount") %>'></asp:Label> </td> </tr> <tr style="background-color:Teal"> <td> <table> <tr> <td> <asp:Button ID="btnEditPost" runat="server" Text="EDIT" BackColor="#000066" ForeColor="Yellow" /></td> <td> <asp:Button ID="btnAcceptAnswer" CommandArgument='<%# Eval("MessageID") %>' OnClientClick="return confirm('Are you sure you want to mark this answer as accepted?')" OnClick="btnAcceptAnswer_Click" BackColor="#000066" ForeColor="Yellow" runat="server" Text="ACCEPT" /> </td> </tr> </table> </ItemTemplate> <SeparatorTemplate> <hr style="color:Blue" /> </SeparatorTemplate> </asp:DataList> Here is the code block I am using to change color and to update the database::--- protected void btnAcceptAnswer_Click(object sender, EventArgs e) { Button btn = (Button)sender; int messageid = Convert.ToInt32(btn.CommandArgument); objbll.MarkAnswer(messageid); this.BindPosts(); } protected void dLMessages_DataBound(object sender, DataListItemEventArgs e) { if (e.Item.ItemType == ListItemType.Item) { HiddenField hdn = (HiddenField)e.Item.FindControl("hdnfld1"); if (Convert.ToBoolean(hdn.Value) == true) { dLMessages.ItemStyle.BackColor = Color.FromName("#A0FE96"); } } }Here MarkAnswer() is the corresponding method in the BLL. This part is working fine but not the color changing operation. I have place the whole thing inside an update panel and a content template. Why is my code not working? Please help me find a solution by steering my in the right direction and point out the errors in my code snippets. Look forward to receiving some active help on this one.
Many thanks in anticipation.
_Manvel_
Contributor
4240 Points
922 Posts
Re: Datalist Color Changing on Clicking a Button ---
Apr 27, 2012 11:36 AM|LINK
From what I see you're binding hdnFld1 to AcceptedAnswer, which I guess is type of boolean, also I assume your DataSource returns whether the particular DataItem is AcceptedAnswer or not, so you can grab DataSource Item in ItemDataBound event, and check whether AcceptedAnswer is true, here is some code snippet
if (e.Item.ItemType == ListItemType.Item || e.Item.ItemType == ListItemType.AlternateItem) { DataRow msgItem = e.Item.DataItem as DataRow if(msgItem != null) { if(Convert.ToBoolean(msgItem["AcceptedAnswer"].ToString()) { dLMessages.ItemStyle.BackColor = Color.FromName("#A0FE96"); } } }Note thou that I assumed that you're binding to DataTable object. If it's some kind of collection of custom objects, make appropriate cast, and check the property on the object, and if you noticed I've added || condition to check if ItemType is AlternatinItem as well.
Hope this helps
PGChoudhury
Member
11 Points
131 Posts
Re: Datalist Color Changing on Clicking a Button ---
Apr 27, 2012 11:48 AM|LINK
I am using a stored procedure to fetch the data from database. In the business logic layer i have written the codes for fetching the data and returing a dataset which I have used in the code behind to bind to the datalist.
Here is the code block from the BLL::--- public DataSet GetPosts() { DataSet ds=new DataSet(); Hashtable ht = new Hashtable(); ht.Add("@ForumID", this.ForumID); ht.Add("@TopicID", this.TopicID); return objdal.ExecuteSelectSP(ds, ht, "sproc_GetPosts"); } and this is the stored procedure I am using::--- CREATE procedure [dbo].[sproc_GetPosts] @ForumID bigint, @TopicID bigint as begin select A.TopicSubject, B.MessageBody, B.MessageID, B.CreationDate, B.AcceptedAnswer, C.Username, C.UserID, C.USignature, C.PostCount from ForumTopics A join ForumMessages B on A.TopicID =B.TopicID join ForumUsers C on C.UserID=B.UserID where B.ForumID=@ForumID and B.TopicID=@TopicID order by B.CreationDate asc end This is the code block where I am binding the dataset to the datalist::--- public void BindPosts() { DataSet ds = new DataSet(); objbll.ForumID = Convert.ToInt32(Session["forumid"].ToString()); objbll.TopicID = Convert.ToInt32(Session["topicid"].ToString()); ds = objbll.GetPosts(); pds.DataSource = ds.Tables[0].DefaultView; pds.PageSize = 20; pds.AllowPaging = true; pds.CurrentPageIndex = CurrentPage; dLMessages.DataSource = pds; dLMessages.DataBind(); }I don't understand what casts you are talking about. Please kindly explain it in a bit more totality with reference to the code blocks I have pasted here. It would be of much help to me.
Many Thanks.
_Manvel_
Contributor
4240 Points
922 Posts
Re: Datalist Color Changing on Clicking a Button ---
Apr 27, 2012 12:00 PM|LINK
Look at your DataSource
where pds is DataView, which means you need to cast DataItem to DataRowView. So you will have
protected void dLMessages_DataBound(object sender, DataListItemEventArgs e) { DataRowView msgItem = e.Item.DataItem as DataRowView if(msgItem != null) { if(Convert.ToBoolean(msgItem.Row.Item["AcceptedAnswer"].ToString()) { dLMessages.ItemStyle.BackColor = Color.FromName("#A0FE96"); } } }Item.DataItem represents data for each Item in your DataList, because your dataSource is list of DataRowViews, you need to cast Item.DataItem to DataRowView ( because Item.DataItem return type of object ). Then you need to check AcceptedAnswer on your datasource, to see whethere backcolor should be seted or not.
PGChoudhury
Member
11 Points
131 Posts
Re: Datalist Color Changing on Clicking a Button ---
Apr 27, 2012 12:24 PM|LINK
here pds is an object of the paged data source class which I have used since I want to enable paging for the datalist. The data source for this 'pds' is the dataset returned by the method from the business access layer. I hope this is right with respect to what I am trying to do.
Here::---
DataSet ds = new DataSet(); objbll.ForumID = Convert.ToInt32(Session["forumid"].ToString()); objbll.TopicID = Convert.ToInt32(Session["topicid"].ToString()); ds = objbll.GetPosts(); pds.DataSource = ds.Tables[0].DefaultView;_Manvel_
Contributor
4240 Points
922 Posts
Re: Datalist Color Changing on Clicking a Button ---
Apr 27, 2012 12:29 PM|LINK
As you can make sure from the link below, when you're calling DefaultView on DataTable, the return type is DataView. Did you tried the approach I suggest ? Are you facing issues, or you didn't even try ?
http://msdn.microsoft.com/en-us/library/system.data.datatable.defaultview.aspx
PGChoudhury
Member
11 Points
131 Posts
Re: Datalist Color Changing on Clicking a Button ---
Apr 27, 2012 12:41 PM|LINK
I am trying to incorporate your code. But there is another problem. After msgitem.Row intellisense isn't giving Item. Instead it is giving ItemArray. And there is an error.
This is the code block I am trying to use:---
protected void dLMessages_DataBound(object sender, DataListItemEventArgs e) { if (e.Item.ItemType == ListItemType.Item || e.Item.ItemType==ListItemType.AlternatingItem) { DataRowView msgitem = e.Item.DataItem as DataRowView; if (msgitem != null) { if(Convert.ToBoolean(msgitem.Row.ItemArray["AcceptedAnswer"].ToString()))<---- this part is showing error. } } }_Manvel_
Contributor
4240 Points
922 Posts
Re: Datalist Color Changing on Clicking a Button ---
Apr 27, 2012 01:31 PM|LINK
Yeah my bad, sry I made a mistype, it should be ItemArray, instead of Item. If it shows an error, please post here the message of error.
PGChoudhury
Member
11 Points
131 Posts
Re: Datalist Color Changing on Clicking a Button ---
Apr 29, 2012 02:54 PM|LINK
Problem not yet solved. I don't knwo what is happening. I tried to integrate the following piece of code but it is not working as per desired. The code is creating a series of outlines in that color specified insteAad of changing the color of the particular row to that specified color. Everything seems ok with the code apparently. But I'm sure I'm making some silly mistake somewhere. Please help me with this typical situation.
protected void dl_RowDataBound(object sender, DataListItemEventArgs e) { if(e.Item.ItemType==ListItemType.Item||e.Item.ItemType==ListItemType.AlternatingItem) { DataRowView drv=(DataRowView)(e.Item.DataItem); if(drv!=null) { if(drv.Row["AcceptedAnswer"].ToString()=="True") { e.Item.BackColor=Color.LightCyan; } } } }Kindly help me out.
_Manvel_
Contributor
4240 Points
922 Posts
Re: Datalist Color Changing on Clicking a Button ---
Apr 29, 2012 04:50 PM|LINK
Try this
protected void dl_RowDataBound(object sender, DataListItemEventArgs e) { if(e.Item.ItemType==ListItemType.Item||e.Item.ItemType==ListItemType.AlternatingItem) { DataRowView drv=(DataRowView)(e.Item.DataItem); if(drv!=null) { if(drv["AcceptedAnswer"].ToString()=="True") { e.Item.BackColor=Color.LightCyan; } } } }