|
Hi!
I have wasted lots of time. could someone please advise if its possible or not so that i could start thinking of alternative solution. I am trying to build a tree level datagrid. the datastructure looks something like below.
1 Vehicle
2 Clothing
1 Holden
2 Pants
1 Barina
2 Astra
3 Jeans
4 Cotton
ASPX
<asp:DataGrid id="dgA" DataKeyField="aid" runat="server" Width="100%" AutoGenerateColumns="False">
<Columns>
<asp:BoundColumn DataField="aid" HeaderText="Id" Visible="false"></asp:BoundColumn>
<asp:TemplateColumn>
<ItemTemplate>
<asp:ImageButton id="btnA" runat="server" Width="9px" Height="9px" ImageUrl="/Images/Plus.gif" CommandName="ExpandA"></asp:ImageButton>
</ItemTemplate>
</asp:TemplateColumn>
<asp:BoundColumn DataField="aname" HeaderText="Name"></asp:BoundColumn>
<asp:TemplateColumn>
<ItemTemplate>
<asp:PlaceHolder ID="phExpandA" Runat="server" Visible="False">
</td></tr>
<tr><td > </td>
<td colspan="11">
<asp:DataGrid id="dgB" DataKeyField="bId" runat="server" Width="100%" AutoGenerateColumns="False">
<Columns>
<asp:BoundColumn DataField="bid" HeaderText="Id" Visible="false"></asp:BoundColumn>
<asp:TemplateColumn>
<ItemTemplate>
<asp:ImageButton id="btnB" runat="server" Width="9px" Height="9px" ImageUrl="/Images/Plus.gif" CommandName="ExpandB"></asp:ImageButton>
</ItemTemplate>
</asp:TemplateColumn> <asp:BoundColumn DataField="bname" HeaderText="Name"></asp:BoundColumn>
<asp:TemplateColumn>
<ItemTemplate>
<asp:PlaceHolder ID="ExpandB" Runat="server" Visible="False">
</td></tr>
<tr><td > </td>
<td colspan="11">
<asp:DataGrid ID="dgC" runat="server" Width="100%" AutoGenerateColumns="False">
<Columns>
<asp:BoundColumn DataField="cId" HeaderText="Id" ItemStyle-Wrap="true">
</asp:BoundColumn>
<asp:BoundColumn DataField="cName" HeaderText="Name" ItemStyle-Wrap="true">
</asp:BoundColumn>
</Columns>
</asp:DataGrid>
</asp:PlaceHolder>
</ItemTemplate>
</asp:TemplateColumn>
</Columns>
</asp:DataGrid>
</asp:PlaceHolder>
</ItemTemplate>
</asp:TemplateColumn>
</Columns>
</asp:DataGrid>
VB
Protected Sub Page_Load(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.Load
Dim conn As New SqlConnection("...")
Dim cmd As SqlCommand = conn.CreateCommand()
Dim dsA As New DataSet
Dim daA As SqlDataAdapter
cmd.CommandText = "select * from A"
conn.Open()
daA = New SqlDataAdapter(cmd.CommandText, conn)
daA.Fill(dsA)
If Not dsA Is Nothing Then
'fill parent datagrid
If Not IsPostBack Then
dgA.DataSource = dsA
dgA.DataBind()
End If
End If
End Sub
Private Sub dgA_ItemDataBound(ByVal sender As Object, ByVal e As System.Web.UI.WebControls.DataGridItemEventArgs) Handles dgA.ItemDataBound
If e.Item.ItemType = ListItemType.Item Or e.Item.ItemType = ListItemType.AlternatingItem Then
Dim dgGridB As DataGrid = CType(e.Item.FindControl("dgB"), DataGrid)
AddHandler dgGridB.ItemCommand, AddressOf dgGridB_ItemCommand
Dim conn As New SqlConnection("...")
Dim cmd As SqlCommand = conn.CreateCommand()
Dim dsB As New DataSet Dim daB As SqlDataAdapter
cmd.CommandText = "select * from B"
conn.Open()
daB = New SqlDataAdapter(cmd.CommandText, conn)
daB.Fill(dsB)
If Not dsB Is Nothing Then
dgGridB.DataSource = dsB
dgGridB.DataBind()
End If
End If
End Sub
Private Sub dgA_ItemCommand(ByVal source As Object, ByVal e As System.Web.UI.WebControls.DataGridCommandEventArgs) Handles dgA.ItemCommand Select Case e.CommandName
Case "ExpandA"
Dim img As ImageButton img = e.Item.Cells(1).FindControl("btnA")
If img.ImageUrl = "/Images/Plus.gif" Then
img.ImageUrl = "/Images/Minus.gif"
Else
img.ImageUrl = "/Images/Plus.gif"
End If
Dim phExpandSummary As PlaceHolder
phExpandSummary = e.Item.Cells(1).FindControl("phExpandA")
phExpandSummary.Visible = Not phExpandSummary.Visible
End Select
End Sub
Private Sub dgGridB_ItemCommand(ByVal sender As Object, ByVal e As System.Web.UI.WebControls.DataGridCommandEventArgs)
'TODO
Select Case e.CommandName
Case "ExpandB"
Dim img As ImageButton img = e.Item.Cells(1).FindControl("btnB")
If img.ImageUrl = "/Images/Plus.gif" Then
img.ImageUrl = "/Images/Minus.gif"
Else
img.ImageUrl = "/Images/Plus.gif"
End If
Dim phExpandSummary As PlaceHolder
phExpandSummary = e.Item.Cells(1).FindControl("phExpandB")
phExpandSummary.Visible = Not phExpandSummary.Visible
End Select
If e.Item.ItemType = ListItemType.Item Or e.Item.ItemType = ListItemType.AlternatingItem Then
Dim dgGridC As DataGrid = CType(e.Item.FindControl("dgC"), DataGrid)
Dim conn As New SqlConnection("...")
Dim cmd As SqlCommand = conn.CreateCommand()
Dim parentDS As New DataSet
Dim parentDA As SqlDataAdapter
cmd.CommandText = "select * from C"
conn.Open()
parentDA = New SqlDataAdapter(cmd.CommandText, conn)
parentDA.Fill(parentDS)
If Not parentDS Is Nothing Then
'fill parent datagrid
If Not IsPostBack Then
dgGridC.DataSource = parentDS
dgGridC.DataBind()
End If
End If
End If
End Sub
|
|
|
|
|
|
hi thanks but all of them are only for two level grid navigation and upto 2 level mine works perfectly. the problem is when i need to fire an event from datagrid B so that I can populate datagrid C.
please help
|
|
|
|
|
It's the same technique whether it is two levels or 12 levels! Buy a third party control then, like Telerik or Infragistics.
only two letters away from being an asset
|
|
|
|
|
thanks for your reply. could you just please tell me how could i fire my event dgGridB_ItemCommand ?
|
|
|
|
|
i am using this to redirect
GridView2.DataSource = dummy_rules;
GridView2.DataBind();
foreach (GridViewRow row in GridView2.Rows)
((LinkButton)row.Controls[0].Controls[0]).Attributes.Add("onclick", "window.showModalDialog('CreateRule.aspx?new=editM',null, 'status:no;dialogWidth:555px;dialogHeight:425px;di alogHide:true;help:no;scroll:no')");
the dialog box appears but i need the gridview there.........but when i use Prevouspage it throws exception Object reference not set to an instance of an object
i have added the directive
]]>;
|
|
|
|
|
What do you mean, "the dialog box appears but i need the gridview there"? You want a gridview in the createrules.aspx page that appears in your modalDialog? What are you trying to accomplish with the PreviousPageType, and why is it in a CDATA ?
only two letters away from being an asset
|
|
|
|
|
i have added
%@ PreviousPageType VirtualPath ="~/StartPage.aspx" %
in my dialog page
i want to access Gridview of StartPage.aspx which is the previous page but in the dialog page the previous page is null
Thanks
|
|
|
|
|
Do you need to access the control or the data in the control? PreviousPage is of course going to be null because you are opening the page via a JavaScript function. There is no Postback occurring for ASP.NET to set the value.
only two letters away from being an asset
|
|
|
|
|
i want to access the data of the gridview controll.
|
|
|
|
|
Then call the same method you use to populate the grid on the first page.
only two letters away from being an asset
|
|
|
|
|
i want to get column2 value of the selected row on startPage.aspx
|
|
|
|
|
So pass the id of the row as a querystring to the page you are trying to open. Then get the data and access that row. It really isn't as difficult as you are trying to make it.
only two letters away from being an asset
|
|
|
|
|
thanks
but the actual problem is this i have a number of controls not only the gridview...... i thought there may be a way to access values of controls instead of passing values of all the controls in querystring
|
|
|
|
|
PreviousPage property of the page is set only if it is requested as a result of cross page post-back. In your case you are redirecting from the other page using modal dialog or smth like that. To have a cross page post back you can set PostBackUrl property of your LinkButton to the second page instead of setting onclick handler as an attribute. However in this case you won't have the modal dialog.
|
|
|
|
|
Hi, I'm trying to insert some text from the page's QueryString into a LayoutTemplate inside a ListView, but something so seemingly simple is proving to be very difficult (for me, at least). Here's the code I have for my LayoutTemplate:
<LayoutTemplate>
<h1><%# Request.QueryString["itemtype"] %> Items</h1>
<asp:PlaceHolder ID="itemPlaceholder" runat="server"></asp:PlaceHolder>
</LayoutTemplate>
The problem is that only "Items" shows up. I have also tried the <%= tag, but then it tells me the control cannot be modified because it contains code blocks. I'm running out of ideas, so any help would be greatly appreciated. Thanks.
modified on Monday, February 11, 2008 8:46 PM
|
|
|
|
|
I'm not a fan of this asp-style coding so I can't really help you unless you're willing to use the asp.net-style code-behind feature... but if you are, run the heading tag on the server and set it's text programmatically:
.aspx:
<h1 id="heading" runat="server" />
Code-behind (.aspx.cs or .vb or ... - I choose C#):
void Page_Load(object sender, EventArgs e)
{
heading.InnerHtml = Request.Params["itemtype"] + " Items";
}
Notice that this solution has the additional benefit of protecting against script injections because the parameter will be interpreted as HTML code, not just literal text. Hence, a user putting
p.aspx?itemtype=<script>close()</script>
in the adress bar (or more problematically, manages to save an itemtype named so the database, causing other users to be directed to such a url) will render the > and < characters as > and < hence just displaying the text rather than execute the script!
|
|
|
|
|
Hi,
we're making use of the CallContext class (System.Remoting.Runtime.Messaging.CallContext) to easily share information among objects participating in the same threads. We have a base page class from which we derive our pages, and we initialize this context by handling the Init event in the base page. This seems to work rather brilliantly.
Just to be sure: It is reasonable, isn't it, to assume that this would either *always* work or *never* work? In other words, since the callcontext travels along the logical thread, the init event will never be executed on a different thread from other events in ASP.NET?
|
|
|
|
|
You know that the aspnet process does sometimes get reset...
I've nevered needed to use messaging in ASP.Net, can I ask what information you need in multiple threads that can't be stored in the Application state?
I didn't get any requirements for the signature
|
|
|
|
|
Hi Todd,
I'm afraid you've misunderstood. The CallContext is not for sharing information between threads, but between objects participating in the same thread. ASP.NET itself uses it to provide access to the "intrinsic" objects Request, Response, Server, Handler, Session and so on.
The main reason we can't use asp.net intrinsics such as Session or Application state is that our business layer runs in a non-web context as well. Specifically, we have a windows service that implements a scheduler. This being .net, there should be no problem using the same business layer in the web app and the service, but this of course means the business layer cannot rely on anything asp.net specific.
Another reason is that we perform many long-running tasks which cannot be performed in a synchronous "request - do the work - create the response" manner, but must instead use one request to start work, then go into polling until the work is finished, then get the results. So another reason to avoid relying on the web context is that it enables us to provide identical execution contexts in the threads our code creates as well as those created by asp.net, so business logic can be developed without having to know in advance whether it will take part in "background" threads or not. We keep only a small amount of information here, but it is absolutely essential: The identity of the user, and database connection information. (It is a distributed system and a single application instance can connect to any number of database instances, while also any number of application instances can connect to any given database instance. Hence we need to know on a user-by-user basis what database the user is "logged on to", though we do of course use connection pooling.)
Not using session or app state of course doesn't automatically imply using the CallContext, but it is extremely convenient because it provides isolation between threads, and also because references put into it are removed when the thread ends, so clean-up is automatic much in the same way as with local variables that simply go out of scope.
If anyone has the inside knowledge to answer my actual question rather than try to second-guess what I'm asking (no offense, I appreciate the attempt!) then please let me know. I'm really quite convinced though that it is the same logical thread: asp.net events happen in stages and I can see no reason why one would want to complicate matters by switching threads along the way, when the processing anyway must occur in a linear fashion.
|
|
|
|
|
I should be more precise about one thing because reading my post I see that I am inviting one misunderstanding: I say that the CallContext is used to provide access to the intrinsic asp.net objects, and that is true. However, I should be more explicit, because otherwise people will think I'm confusing CallContext and HttpContext.
So just to be clear, it is the reference to the current HttpContext which is kept in the CallContext, and the other intrinsics come from that one again.
Basically what we're doing is a sort of simplistic mimicking of the way it's done in asp.net, believing that this design isn't too bad. You could say our business logic relies on a thread context that has been initialized by our own code rather than one initialized by asp.net framework code; thus enabling us to do such initialization in both our scheduler service and the web application.
|
|
|
|
|
dojohansen wrote: If anyone has the inside knowledge to answer my actual question rather than try to second-guess what I'm asking (no offense, I appreciate the attempt!) then please let me know.
What are you talking about?
I didn't try to second guess anything. I've never used messaging in asp.net and I wanted to learn more about it. That's why I asked you...
I didn't get any requirements for the signature
|
|
|
|
|
I just meant that it seemed you tried to think about state management in general, hence suggesting application state, when in fact my question was whether or not the entire asp.net pipeline is processed on the same logical thread or not. I didn't mean to upset you, so sorry if I did.
I know from when I try to help people that it is often useful to understand the context though, so I try to explain the motivation behind using it.
My testing seems to indicate that Global_BeginRequest and EndRequest fire on a different thread from the page processing, but all events fired on the page appear to always belong to the same thread.
|
|
|
|
|
I'd bet money that all page processing occurs on one thread.
I did find this on google.
http://dotnet.org.za/armand/archive/2004/04/07/985.aspx[^]
So it seems you could store and pass data using the CallContext, however judging that only 4 results come back when you google System.Remoting.Runtime.Messaging.CallContext you might have trouble getting any help with this.
I didn't get any requirements for the signature
|
|
|
|
|
We're pretty much doing the same thing. It is perfect for providing "execution context" information like who is the current user, what's the current database, and so on.
I'm going off on a tangent here, but I actually believe what we've done can be quite useful for others as well.
Our design follows this simple pattern: All instance members are private, as are all constructors. The public interface is static, but public members do nothing but find the right instance and call the corresponding instance member. References to instances are stored in the thread context, hence only one thread can access each instance, so the design is inherently thread-safe.
A snippet demonstrates the pattern implemented in C#:
public class Connection
{
const string threadKey = "Connection";
Connection(string cnxStr) { ... }
int transactionLevel;
SqlTransaction transaction;
SqlConnection sqlConn;
...
void beginTransaction()
{
...
}
Connection current
{
get
{
Connection c = CallContext.GetData(threadKey) as Connection;
if (c == null)
{
string cnxStr = ...;
c = new Connection(cnxStr);
}
return c;
}
}
static public void BeginTransaction()
{
current.beginTransaction();
}
}
We couple this with our own custom-written "Thread class" (Thread is sealed so our type is not really a thread, but it has the same interface as a thread so where our code was creating threads we just switched the type to our own) which copies the execution context of the thread that creates it, and we have a wonderfully simple to use solution with a minimum of code redundancy. (The "where do connection info come from" logic was all over the place before, and we had problems knowing when we should clone connections and when we should not, because the method using a connection would sometimes be called as part of a transaction and sometimes without one, sometimes in a thread processing a page request and sometimes in a background thread... Using the call context and our pretend-thread class solved all these problems and simplified the programming of application logic to boot!
The code it leads to is just as simple as code reading or writing a Session variable, though of course there are many session instances at any given time in the application domain. Only it is even better because no reference to the object exists outside the type itself, making it far easier to avoid memory leaks.
In the past we even had business objects that contained a reference to an instance of HttpSessionState,
myObj.Session = Session;
and this sort of terrible thing too is avoided with this design, at the expense of a larger number of lookups of course. The overhead doesn't seem to be that big though. In 1.x the HttpContext.Current also came from here (I checked with Reflector) so I'm figuring it can't be that bad.
This of course is all proprietary information
|
|
|
|