Showing posts with label custom. Show all posts
Showing posts with label custom. Show all posts

Wednesday, March 28, 2012

Asp.net ajax in Custom Control

I'm beginner in asp.net ajax.

Now I have to writecustom control and apply machanismpartial updating(which can be applied for User Control)

Could I can applyasp.net ajax forCustom Controlor not , and how to do this ?

Thanks a lot !

Thank you very much !

In fack UpdatePanel can be added to Custom Control !

But I have one problem more !

For creating Custom Control Im using the command in Console

csc /t:library /out:MGR.dll /r:System.dll /r:System.Web.dllMGR.cs

MGR is the name of Custom Control class

after compiling I got the error "the type or namespace name 'UpdataPanel' could not be found (are you missing directive or an assembly referrence?)"

I modified the command to

csc /t:library /out:MGR.dll /r:System.dll /r:System.Web.dll /r:Microsoft.Web.Atlas.dll MGR.cs

but got the same error !

I don't know why ? do you know why this error occured ?

HTD


I dont know exactly what your control will be doing, but all you should need to do is design the whole control in an asp.net ajax update panel.


My goal is "Partial Updating" in Control(which include TextBox and GridView). How you can add Update Panel in Custom Control ??

(In User Control, it's easy to do )


Open your Control.ascx file.

Drag and drop a update panel on to your page.

Select everything but the update panel.

Drag and drop your selection into the update panel.

That's everything you need to do to set up the control.

Anytime you use your control in your application, make sure you have the "Script Manager" Ajax extension on that page.


My deverloping Control is Custom Control, it's not User Control !

HTD


You should b eable to add it like any other control... ?

UpdatePanel panel = new UpdatePanel();

etc.


you can add a custom control class to a updatepanel like this

myControl ctrl =new MyControl();UpdatePanel1.ContentTemplateContainer.Controls.Add(ctrl);

Monday, March 26, 2012

ASP.NET AJAX Breaks with Custom Url Rewriting

I am having two related issues with ASP.NET AJAX. I used the AtlasToolkit PopupControlExtender to create a very simple Popup Calendar. I have created a custom HtmlTextWriter and HttpModule to rewrite incoming url's based on incoming path. So essiently if I nav /This/Page/Does/Not/Exist.aspx, the module will check the file system to see if that page physically exists, and if not then check the database for the corresponding PageId and rewrite it ~/Page.aspx?PageId=DoesNotExistId. Then I have overriden Render and written a custom HtmlTextWriter that looks for <form action=""> and sets that attribute equal to the fully qualified url requested.

The problem goes like this. Anytime before I do any ASP.NET UI events, everything is fine. After an ASP.NET AJAX UI event the Form.Action attribute reads Page.aspx?pageid=blah. Is there anyway to override this behavior?

Thank you,

Jason Lind

I'm like 99% sure this a bug. The line of js that causes this most of the time will do nothing, except when you're rewriting and then it breaks your application

See lines 1061 through 1069 in MicrosoftAjaxWebForms.js (the debug version) pasted here for your convienance:

if (handler) { handler(this,this._getPageLoadingEventArgs()); }if (formActionNode) {this._form.action = formActionNode.content;this._form._initialAction =this._form.action; }

Basically on any ASP.NET AJAX ui event the form.action is being reset to the response. I can see no reason for doing this, for as far as I can tell there is no information being added to the action. My guess is at some version in development this was the case and that approach was later dropped and this code never was refactored.

Can someone on the ASP.NET AJAX team please confirm this and assure me that in some later release this won't be an issue, maybe even commentif (formActionNode) {this._form.action = formActionNode.content;this._form._initialAction =this._form.action; } out and issue me a hot fix?

Thank you,

Jason Lind

Lead Software Engineer / Triton Tek


<script type="text/javascript">
Type.registerNamespace("ScriptLibrary");
Sys.WebForms.PageRequestManager.getInstance().add_endRequest(pageLoaded);
function pageLoaded(sender, args) {
document.forms[0].action = requestUrl;
document.forms[0]._initialAction = requestUrl;
}
var requestUrl = "";
function body_onload()
{
requestUrl = document.forms[0].action;
}
</script>

Still should be fixed.


Kinda hard to say what's going on here, but first here's why we do that form action stuff. When modules such as session and authentication rewrite the URL in their cookieless modes, we need to reset the form action to be whatever the rewritten URL is. We do it in a manner similar to what you're doing by checking the form's action and grabbing whatever it has.

However, in your case it sounds like you're using a customwriter to do the work, which might be the problem in this scenario. Instead you should override the form's rendering functionality and just change the action there. Then Atlas will pick it up and use whatever you set. Here are a couple of articles on the subject:

General URL rewriting:http://msdn.microsoft.com/library/default.asp?url=/library/en-us/dnaspp/html/urlrewriting.asp (but, ignore the part where it says to write an actionless URL!)
Atlas URL rewriting:http://geekswithblogs.net/lazydeveloper/archive/2006/08/17/88247.aspx (this is the important part)

Thanks,

Eilon

ASP.NET AJAX + JSON: Custom Grid with paging + sorting

Hi,

I am looking for the following solution:

I replaced myUpdatePanel with a client-side PageMethod to a Webservice webmethodusing ASP.NET Ajax and JSON serialization. I now want to use some kindof data table to display my result, however I also need Paging +Sorting.

Using asp:GridView is not a solution here since it is a server-side control with server-side sorting functionality.

Any suggestions? I don't want some heavy JS file that can do this.

You can add two more parameters to your "webmethod" - something like pageNumber and sortString. If I understood you correctly.


Yep. I am just wondering how to construct this whole thing. So far I am thinking of passing the sortDirection, and perform the sorting on the server side directly since I am dealing with a List. The paging is a little trickier though.


hello.

for paging, you just need to pass the current page and the number of elements per page. you should perform paging on the server side and only return the neecessary elements.


Thank youGeeked


What did you end up using for your solution? You mentioned a GridView was not an option... are you constructing the table by hand?

Wednesday, March 21, 2012

ASCX Custom Events and AsyncPostBackTrigger

I have written a user control that raises an event based on certain criteria. I have placed an UpdatePanel around a grid that needs to be updated when that event fires. So I placed a asp:AsyncPostBackTrigger in the Triggers section. I have set the EventName equal to the event from the user control. In my user control, I throw an exception if something is wrong with some of the data. If the exception is thrown, the event does not get called. I would expect a full postback to occur if the event is not triggered (not a partial render from AJAX); however, even if the event is not thrown and the button is clicked, a partial postback occurs anyways. I need to show that the exception happened in the user control, but I cannot wrap the user control in an UpdatePanel since the data is huge and would take awhile to partial postback.

Any suggestions?

hello.

i think this is an old know issue:

http://msmvps.com/blogs/luisabreu/archive/2006/09/26/Quick-tip_3A00_-using-UserControl-events-as-triggers.aspx


Hmmm.. I have tried implementing your solution, but I cannot seem to get it to work. Here is a code snippet what I am doing.

public delegate void PassengerEmployeeSubmittedEventHandler(object sender, PassengerEmployeeSubmittedEventArgs e);

public class PassengerEmployeeSubmittedEventArgs : EventArgs
{

// properties go here
}

UserControlCode
{

public event PassengerEmployeeSubmittedEventHandler PassengerEmployeeSubmitted;

protected virtual void OnPassengerEmployeeSubmitted(PassengerEmployeeSubmittedEventArgs e)
{
if (this.PassengerEmployeeSubmitted != null)
PassengerEmployeeSubmitted(this, e);
}
}

protected void ibtnSubmitEmployee_Click(object sender, ImageClickEventArgs e)
{

If(verified)
OnPassengerEmployeeSubmitted(new PassengerEmployeeSubmittedEventArgs());
else

this.litError.Text = "Error";

}

} // end user control

Web Page Containing Control Code {

<asp:ScriptManager ID="ScriptManager1" runat="server" EnablePartialRendering="true">
</asp:ScriptManager>

<asp:UpdatePanel ID="UpdatePanelPassengers" runat="server" UpdateMode="Conditional">
<Triggers>
<asp:AsyncPostBackTrigger ControlID="ucAddPassengerEmployee" EventName="PassengerEmployeeSubmitted" />
</Triggers>
<ContentTemplate>

// gridview code only

</ContentTemplate>
</UpdatePanel>
<uc1:AddPassengerEmployee ID="ucAddPassengerEmployee" runat="server" />

}

I have tried registering the ImageButton with the RegisterAsyncPostBackControl, but here's what's happening. The UpdatePanel only refreshes when that event is fired, that works, but it still does a Partial Page Update; therefore, if I catch that exception, the literal is never refreshed since it's only doing a partial postback. I would expect it to do a regular postback all the time unless that event is triggered. Any suggestions?


hello again.

it was an old sample, so i've just updated it for the current release:

A.ASCX

<%@. Control Language="C#" ClassName="A" %>

<script runat="server">
private object aux = new object();
public event EventHandler BtClicked
{
add
{
this.Events.AddHandler(aux, value);
}
remove
{
this.Events.RemoveHandler(aux, value);
}
}

void h(object s, EventArgs e)
{
OnBtClicked(e);
}

protected void OnBtClicked(EventArgs a)
{
if (this.Events[aux] != null)
{
((EventHandler)(this.Events[aux]))(this, a);
}
}

protected override void OnLoad(EventArgs e)
{
base.OnLoad(e);
ScriptManager manager = ScriptManager.GetCurrent(this.Page);
if (manager != null)
{
manager.RegisterAsyncPostBackControl(bt);
}
}
</script>

<asp:Button runat="server" ID="bt" Text="Submit" OnClick="h" UseSubmitBehavior="false" />

PAGE.ASPX

<%@. Page Language="C#" %>

<%@. Register src="http://pics.10026.com/?src=A.ascx" tagname="A" tagprefix="uc1" %>

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

<script runat="server">

</script>

<html xmlns="http://www.w3.org/1999/xhtml">
<head runat="server">
<title>Untitled Page</title>
</head>
<body>
<form id="form1" runat="server">
<div>

</div>
<asp:ScriptManager runat="server" ID="manager"></asp:ScriptManager>
<asp:UpdatePanel runat="server" id="panel">
<ContentTemplate>
<%=DateTime.Now %>
</ContentTemplate>
<Triggers>
<asp:AsyncPostBackTrigger ControlID="A1" EventName="BtClicked" />
</Triggers>
</asp:UpdatePanel>
<uc1:A ID="A1" runat="server" />
</form>
</body>
</html>

the important thing is the call to the RegisterAsyncPostbackControl method


Hello Luis,

I tried using that code and it still doesn't seem to work. I even took your code and made one modification to it. As it is, it works as expected, but if I comment out the call to raise the event in the protected void OnBtClicked(EventArgs a), a partial post back still occurs, and that is the problem I am experiencing. I would expect that if this event is not raised, then a partial postback should NOT occur regardless if the button was clicked; however, please correct me if I am wrong. Thank you very much for your help. What do you think?


hello.

the registerXXX method is responsible for configuring the client page so that it always starts a partial postback operation. the trigger thing is only used on the server side and if you call the method, you'll always get a partial postback.

i'm still not sure on what you're looking for...if you get an exception during a partial postback the only thing you need is to handle the client endRequest event (raised by the pagerequestmanager) and use some js to show the exception on that label...


Guys while were are at this User control juncture, I would need help with a silly question that I havent been able to find an answer to yet. User Control inheritance. How would you go about changing the property of something from an inherited user control or override a base control from a inherited user control.

I have all the code, if you need it to help me but I am unable to get it so far. Rest all works fine except this bit. Any help appreciated


Thread hijacker ;) Kidding. I guess what I was hoping for was a partial postback to only occur when the specified event happens. Here's an example I have posted that does not use a usercontrol.

<%@. Page Language="C#" AutoEventWireup="true" CodeFile="Default.aspx.cs" Inherits="_Default" %
<%@. Register Assembly="System.Web.Extensions, Version=1.0.61025.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35"
Namespace="System.Web.UI" TagPrefix="asp" %
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<script runat="server">
protected void h(object sender, EventArgs e)
{
this.TextBox1.Text = this.ListBox1.SelectedValue;
}

protected void btn(object sender, EventArgs e)
{
this.ListBox1.DataSource = new System.Data.DataTable();
this.ListBox1.DataBind();
}

protected void Page_Load(object sender, EventArgs e)
{
this.ListBox1.Items.Add(new ListItem("TEST", "TEST"));
this.ListBox1.Items.Add(new ListItem("TEST2", "TEST2"));
}
</script>
<html xmlns="http://www.w3.org/1999/xhtml" >
<head runat="server">
<title>Untitled Page</title>
</head>
<body>
<form id="form1" runat="server">
<div>
<asp:ScriptManager ID="ScriptManager1" runat="server" EnablePartialRendering="true">
</asp:ScriptManager>
<asp:UpdatePanel ID="UpdatePanel1" runat="server" UpdateMode="Conditional">
<Triggers>
<asp:AsyncPostBackTrigger ControlID="ListBox1" EventName="SelectedIndexChanged" />
</Triggers>
<ContentTemplate>
<asp:TextBox ID="TextBox1" runat="server"></asp:TextBox>
</ContentTemplate>
</asp:UpdatePanel>
<asp:Button ID="Button1" runat="server" Text="Button" OnClick="btn" />
<asp:ListBox ID="ListBox1" runat="server" OnSelectedIndexChanged="h" AutoPostBack="true" EnableViewState="true" ></asp:ListBox>
</div>
</form>
</body>
</html
What you see is that the SelectdIndexChanged causes the partial postback, while the button click causes a full postback. I guess the big problem I have in my usercontrol is that I have a button that causes a postback, but I do not want it to cause the partial postback. I run some validation AFTER the button has been clicked, and then it will send an Event to the calling page which contains the AJAX. If this event is fired, then it should initialize the partial postback; however, it is causing a partial postback for ANY postback event raised by the usercontrol. This behavior seems really out of place to me since it is not in the updatepanel. Otherwise, there's no point at all in using the EventName with any usercontrol since it will cause the partial postback regardless of what happenes inside of it.

The solution you have posted will work, but perhaps my view on how a usercontrol behaves is miscued. In order for your solution to work, I will need to take into consideration other pages that consume this control that do not use it in AJAX. I would have to let the exception bubble up to the calling page in AJAX, otherwise, I would need to catch it via server side and display it in the literal. What do you think?


As another example, I added a second button in the usercontrol "A" in your example. What I would expect, is that since it is not part of the Trigger, it should not fire a partial postback, but it does. I have tried adding it to the RegisterAsyncPostBackControl... taking it away, etc... but I can't get it to work. Perhaps my thinking is off?


hello again.

due to the way the algorythm is built on the client side, you need to call the registerpostbackcontrol for that 2nd button (just add the line below the registerasyncpostnack cotnrol method on the user control)


That did the trick. Thanks a lot. I guess since I have a button that triggers an event in a user control, it's impossible to do a full postback when the button is pressed, but a partial postback when button is pressed and the event is raised. I ended up using client side validation in the user control (and keeping the server validation) for AJAX. THanks.


hello.

well, the important thing to keep in mind is that on the client side, there really isn't any user control. what you have are several html controls! I've been away for a long time (ie, haven't really been using asp.net ajax since it was onut some moths ago), so i can't really be specific about it. However, i recall that hte pagerequestmanager object will try to make some "smart" tests until it is able to get an element responsible for the postback. if it gets anything different from null, it'll perform a partial postback. that's why your second button still kept giving you a partial postback. btw, i think i've talked about those things in my blog (though I'm not sure)...


Thanks a lot for the clarification. That definitely makes more sense to me. Thank you. I'll check out your blog next time just to make sure I'm not asking redundant questions.

Array as ScriptControlDescriptor property for custom web control

Hi all,

I'm wondering if it's possible to add an Array as property of a ScriptControlDescriptor.

Adding line number 55 in the following code results in the following error.

Error:

Cannot get inner content of MasterHead because the contents are not literal.

Code:

1 using System;
2 using System.Data;
3 using System.Configuration;
4 using System.Web;
5 using System.Web.Security;
6 using System.Web.UI;
7 using System.Web.UI.WebControls;
8 using System.Web.UI.WebControls.WebParts;
9 using System.Web.UI.HtmlControls;
10 using System.Collections.Generic;
11
12 using AjaxControlToolkit;
13
14 namespace OrganizerControls {
15 public class Organizer : Control, IScriptControl {
16 private ScriptManager sm;
17 private List _arrLiterals;
18
19 public Organizer(){
20 _arrLiterals = new List();
21 }
22 protected override void OnInit(EventArgs e) {
23 base.OnInit(e);
24 }
25 protected override void OnPreRender(EventArgs e) {
26 if (!this.DesignMode) {
27 sm = ScriptManager.GetCurrent(Page);
28
29 if (sm == null)
30 throw new HttpException("A ScriptManager control must exist on the current page.");
31
32 sm.RegisterScriptControl(this);
33 }
34
35 foreach (Control c in this.Controls) {
36 if (c.GetType() == typeof(LiteralControl))
37 this._arrLiterals.Add((LiteralControl)c);
38 }
39 base.OnPreRender(e);
40 }
41 protected override void Render(HtmlTextWriter writer) {
42 if (!this.DesignMode)
43 sm.RegisterScriptDescriptors(this);
44
45 base.Render(writer);
46 }
47 protected virtual IEnumerable GetScriptReferences() {
48 ScriptReference reference = new ScriptReference();
49 reference.Path = ResolveClientUrl("~/_js/OrganizerControls.Organizer.js");
50
51 return new ScriptReference[] { reference };
52 }
53 protected virtual IEnumerable GetScriptDescriptors() {
54 ScriptControlDescriptor descriptor = new ScriptControlDescriptor("OrganizerControls.Organizer", this.ClientID);
55 descriptor.AddProperty("CollectionLiterals", this._arrLiterals.ToArray());
56
57 return new ScriptDescriptor[] { descriptor };
58 }
59 IEnumerable IScriptControl.GetScriptReferences() {
60 return GetScriptReferences();
61 }
62 IEnumerable IScriptControl.GetScriptDescriptors() {
63 return GetScriptDescriptors();
64 }
65 }
66 }

Hopefully someone can help me out.

Thanks!

Martijn van Mechelen

Solved the above with a different approach.

Added a string of ID's as a property, which is split to an Array in the .js file:

descriptor.AddProperty("LiterallIds", strLiteralIds);

Or does someone have a better suggestion?