Im having the following problem with vb.net asp.net webparts. Im trying to create a static connection between webparts but im running into a problem, namely:
Could not find the connection provider Web Part with ID 'Ucl_Diary_Summary1'
I have the following defined as my iterface:
Public Interface IDiaryPartsProvider
function Test as String
End Interface
I have the following as my Consumer (UserControl):
Partial Class UsrCtrls_Diary_ucl_DiaryAwaitingReview
Inherits System.Web.UI.UserControl
<ConnectionConsumer("Test", "myID")> _
Public Sub GetTextTransferInterface(ByVal provider As IDiaryPartsProvider)
Dim a As String = provider.Test()
UserMsgBox(a.ToString, Me.Page)
End Sub
End Class
I have the following defined as my Provider (UserControl):
Partial Class UsrCtrls_Diary_Diary_Summary
Inherits System.Web.UI.UserControl
Implements IWebPart, IDiaryPartsProvider
<ConnectionProvider("myID")> _
Public Function Test() As String Implements IDiaryPartsProvider.Test
Return "this is a test"
End Function
End Class
I have my default.aspx as follows:
<%# Register Src="UsrCtrls/Diary/ucl_Diary_Summary.ascx" TagName="ucl_Diary_Summary"
TagPrefix="uc4" %>
<%# Register Src="UsrCtrls/Diary/ucl_DiaryAwaitingReview.ascx" TagName="ucl_DiaryAwaitingReview"
TagPrefix="uc5" %>
<asp:WebPartManager ID="WebPartManager1" runat="server">
<StaticConnections>
<asp:WebPartConnection ID="cnn"
ConsumerID="Ucl_DiaryAwaitingReview1"
ProviderID="Ucl_Diary_Summary1"
/>
</StaticConnections>
</asp:WebPartManager>
<asp:WebPartZone ID="zoneDiaryTopLeft" runat="server" EmptyZoneText="Add WebPart Here" DragHighlightColor="#454777" HeaderText=" ">
<ZoneTemplate>
<asp:Panel ID="pnl1" runat="server" title="Claims Awaiting Review">
<asp:UpdatePanel ID="udp_TopLeft" runat="server" ChildrenAsTriggers="False" UpdateMode="Conditional">
<ContentTemplate>
<uc5:ucl_DiaryAwaitingReview ID="Ucl_DiaryAwaitingReview1" runat="server" title="Claims Awaiting Review" />
</ContentTemplate>
</asp:UpdatePanel>
</asp:Panel>
</ZoneTemplate>
</asp:WebPartZone>
<asp:WebPartZone ID="zoneDiaryTopRight" runat="server" EmptyZoneText="Add WebPart Here" DragHighlightColor="#454777" HeaderText=" ">
<ZoneTemplate>
<asp:Panel ID="PNL2" runat="server" title="Diary Summary">
<asp:UpdatePanel ID="udp_TopRight" runat="server" ChildrenAsTriggers="False" UpdateMode="Conditional">
<ContentTemplate>
<uc4:ucl_Diary_Summary ID="Ucl_Diary_Summary1" runat="server" Title="Diary Summary" />
</ContentTemplate>
</asp:UpdatePanel>
</asp:Panel>
</ZoneTemplate>
</asp:WebPartZone>
I can only assume its because I have my webparts - usercontrol wrapped in a panel (used for scrolling) and also an updatepanel which I use to refresh, so how do I get it to see the usercontrol?
Thanks in advance.
James.
I didn't have a chance to look at your message in detail but the issue appears to be with your provider. It should be returning an object that implements the interface used for communication to the consumer (usually a reference to itself).
Check out the following resource for more info:
Introducing ASP.NET Web Part Connections
I found out my problem/solution in the end.
Rob you are correct I needed to pass back an instance of the object implementing the interface but also, you cant reference a User Control for a static connection which is a child of two other controls, namely the panel and update panel. I was doing this all wrong. I changed it so that the update panel is inside the user control rather than on the default page. That way all the specific (web part) components are self contained.
Also, referring back to the original item of returning the instance, I replaced the following:
Public Function Test() As String Implements IDiaryPartsProvider.Test
Return "this is a test"
End Function
with:
<ConnectionProvider("myID")> _
Public Function Test() As IDiaryPartsProvider
Return me
End Function
Public ReadOnly Property Test() As String Implements IDiaryPartsProvider.Test
Get
Return "This is a test"
End Get
End Property
Hope this can help someone!
James.
Related
I have to create an asp.net form using label. I found an example for this task and tried to run it but nothing from the expected result appeared. Do you have any idea what else should be done to run it? (I'm still at the very beginnig of asp.net.)
Here is the code:
<%# Page Language="vb" %>
<script runat="server">
Sub submit(Sender As Object, e As EventArgs)
label1.Text=txt1.Text
End Sub
</script>
<html>
<body>
<form runat="server">
Write some text:
<asp:TextBox id="txt1" Width="200" runat="server"/>
<asp:Button id="b1" Text="Copy to Label" OnClick="submit" runat="server"/>
<p><asp:Label id="label1" runat="server"/></p>
</form>
</body>
</html>
Please check the default access modifier for your function(SUB).
In c# we use protected and from MSDN
Class members, including nested classes and structs, can be public,
protected internal, protected, internal, or private. The access level
for class members and struct members, including nested classes and
structs, is private by default. Private nested types are not
accessible from outside the containing type.
So try with Friend access modifier for VB.Net.
First off, I know that what I am doing here seems entirely impractical and not good design, but I am trying to increase performance in this ASPX that contains 8,000+ lines of markup. Because of the complexity of this page (not to mention messiness) and short deadline, rewriting it to use clientside binding with AJAX/JSON is just not an option, so I have to continue to use serverside binding.
The page I am working on contains around 13 individual sections, each one loading its own entity from the database. Right now, the page initially loads ALL entities synchronously, so you can imagine that this page can sometimes take 5 seconds or longer to load. My goal here is to employ a quick fix that will load these sections only when the section is expanded so that we load only the sections that are requested by the user, thus increasing performance and conserving database resources.
The sample code below should be easy to paste right into a VB.NET WebForm if you're interested in trying this out for yourself. Just name the page asyncupdatepanels.aspx.
The problem:
Overall, my solution is working fairly well. In cmUpdate_Click, I use Threading.Thread.Sleep(2000) to simulate a call to the database to retrieve data. When you click one of the buttons, it pauses for 2 seconds and then sets the appropriate Panel's .Visible property to True.
The issue occurs when you click one button and then click the the other before the first one is finished updating. For example, if you click Show Panel 1 then quickly click Show Panel 2, only Panel 2 shows even though both button clicks are triggered in the codebehind.
Maybe asynchronous UpdatePanel is the wrong term to use here. Regardless, I need to find a way to show the panels as if they were executed in separate asyncronous threads. I want to be able to click these buttons pretty much near the same time and have both panels show.
If anyone has any other solutions to my problem that will not require major changes to the way I bind controls in each section, I'd love to hear it. The method I am using now is pretty much a hack, but it will work for now until we eventually rewrite this whole thing in MVC/c#.
Edit: The production code doesn't actually call a Javascript function by use of a button's OnClientClick. Instead, it uses a jQuery accordion. I just wanted to keep the sample code simple. For now, focus on __doPostBack("<%=cmUpdate.ClientID %>", ButtonId); regardless of how it's ultimately called.
ASPX
<%# Page Language="vb" AutoEventWireup="false" EnableEventValidation="false" CodeBehind="asyncupdatepanels.aspx.vb" Inherits="JsonJqueryDevex.asyncupdatepanels" %>
<!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 runat="server">
<title></title>
<script language="javascript" type="text/javascript">
function UpdateIt(ButtonId) {
__doPostBack("<%=cmUpdate.ClientID %>", ButtonId);
return false;
}
</script>
</head>
<body>
<form id="form1" runat="server">
<asp:ScriptManager ID="ScriptManager1" runat="server">
</asp:ScriptManager>
<div>
<asp:Button ID="cmShow1" Text="Show Panel 1" ClientIDMode="Static" OnClientClick="javascript:return UpdateIt(this.id);" runat="server" />
<asp:UpdatePanel ID="UpdatePanel1" UpdateMode="Conditional" runat="server">
<ContentTemplate>
<asp:Panel ID="pnl1" Visible="false" runat="server">
Panel 1 content
</asp:Panel>
</ContentTemplate>
<Triggers>
<asp:AsyncPostBackTrigger ControlID="cmUpdate" EventName="Click" />
</Triggers>
</asp:UpdatePanel>
<asp:Button ID="cmShow2" Text="Show Panel 2" ClientIDMode="Static" OnClientClick="javascript:return UpdateIt(this.id);" runat="server" />
<asp:UpdatePanel ID="UpdatePanel2" UpdateMode="Conditional" runat="server">
<ContentTemplate>
<asp:Panel ID="pnl2" Visible="false" runat="server">
Panel 2 content
</asp:Panel>
</ContentTemplate>
<Triggers>
<asp:AsyncPostBackTrigger ControlID="cmUpdate" EventName="Click" />
</Triggers>
</asp:UpdatePanel>
<div style="display: none">
<asp:UpdatePanel UpdateMode="Conditional" runat="server">
<ContentTemplate>
<asp:Button ID="cmUpdate" runat="server" />
</ContentTemplate>
</asp:UpdatePanel>
</div>
</div>
</form>
</body>
</html>
Codebehind:
Public Class asyncupdatepanels
Inherits System.Web.UI.Page
Protected Sub Page_Load(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.Load
End Sub
Private Sub cmUpdate_Click(sender As Object, e As System.EventArgs) Handles cmUpdate.Click
Dim Param As String = Request("__EVENTARGUMENT")
Threading.Thread.Sleep(2000)
Select Case Param
Case "cmShow1"
pnl1.Visible = True
Case "cmShow2"
pnl2.Visible = True
End Select
End Sub
End Class
How about disabling the appropriate buttons on click?
Say,
function UpdateIt(ButtonId) {
$('#<%=cmShow1.ClientID %>').attr('disabled', true);
$('#<%=cmShow2.ClientID %>').attr('disabled', true);
__doPostBack("<%=cmUpdate.ClientID %>", ButtonId);
return false;
}
Then, in your code behind, after the sleep, enable them again (cmShow1.Enabled = true / cmShow2.Enabled = true) - the UpdatePanel call will handle the rest.
I would do an AJAX call to your server-side in the page_load event of the page where your updated panel is. You would then call the Update method of your update panel when your processing is done.
You won't have to wait for the processing to be done to do whatever you want to do meanwhile.
Javascript(with jQuery):
function ajaxCall() {
$.ajax({
url: "YourPage.aspx"
});
}
You can process your AJAX call in the Page_Load in your .NET.
I know that you said using AJAX wouldn't be a good option, but this is fairly short and simple.
Lets say we have the following in the default.aspx file
<asp:Literal runat="server" Text="<%= TestMethod() %>" />
What needs to be defined in the default.aspx.cs file to make this work?
I tried to add a method called TestMethod to the _Default class which simply returned the string Test, but it didn't seem to work.
Can anyone help?
Thanks,
AJ
Apart from the method being marked public...
i think you could also remove the asp:Literal altogether
example
your code
<p><asp:Literal runat="server" Text="<%= TestMethod() %>" /></p>
could be
<p><%= TestMethod() %></p>
However if you are intent on using the Literal then please rather set it on page load.
http://msdn.microsoft.com/en-us/library/system.web.ui.webcontrols.literal.aspx
Regards.
I think you can get the same result by doing this
In your .aspx file
<asp:Literal runat="server" ID="ltr1" />
And in your aspx.cs file
ltr1.text = TestMethod();
I'm fighting this problem for few hours now and I'm not getting any closer to solution.
The thing is: I'm having few UpdatePanels on my master page. And then, I have RadTreeViewcontrol on the page, that should cause partial postback each time node is clicked. Everything works fine there.
Since I'm using the same tree on some other pages, I moved this functionality to UserControl. Stuff I've done before, so no problem. Moved some code to ascx, created some events. Everything always worked for me well. But not now.
RadTreeView is nested inside UserControl, and this control on master page with update panels, see below:
<asp:Panel ID="pnlContentWrapper" runat="server" CssClass="ContentWrapper">
<div id="HeaderBreadCrumb">
<asp:ContentPlaceHolder ID="HeaderBreadCrumbContent" runat="server" />
</div>
<div id="HeaderMenu">
<asp:UpdatePanel ID="upnlTreeMenu" runat="server">
<ContentTemplate>
<asp:ContentPlaceHolder ID="HeaderMenuContent" runat="server" />
</ContentTemplate>
<Triggers>
<asp:AsyncPostBackTrigger ControlID="treeProductTree" />
</Triggers>
</asp:UpdatePanel>
</div>
<div id="TreeDiv">
<fp:ProductTree ID="treeProductTree" runat="server" />
</div>
<asp:Panel ID="ContentDiv" ClientIDMode="Static" runat="server">
<asp:UpdatePanel ID="upnlTreeContent" runat="server">
<ContentTemplate>
<asp:ContentPlaceHolder ID="TreePageContent" runat="server" />
</ContentTemplate>
<Triggers>
<asp:AsyncPostBackTrigger ControlID="treeProductTree" />
</Triggers>
</asp:UpdatePanel>
</asp:Panel>
</asp:Panel>
And the user control is really simple:
<%# Control Language="vb" AutoEventWireup="false" CodeBehind="ProductTree.ascx.vb"
Inherits="ProductTree" %>
<div>
<telerik:RadTreeView ID="treeProductTree" ClientIDMode="Static" runat="server" EnableDragAndDrop="false"
SkinID="CustomSkin" CssClass="MasterProductTree" DataFieldID="NodeId" DataFieldParentID="NodeParentId"
DataTextField="NodeName" DataValueField="NodeId" />
</div>
And some code behind:
Imports Telerik.Web.UI
Public Class ProductTree
Inherits System.Web.UI.UserControl
Public Event NodeExpand As EventHandler(Of ProductTreeNodeExpandEventArgs)
Public Event SelectedNodeChange As EventHandler
Protected Sub ProductTree_NodeExpand(ByVal sender As Object, ByVal e As RadTreeNodeEventArgs) _
Handles treeProductTree.NodeExpand
Dim nodeId As Integer = CInt(e.Node.Value)
Dim evetArgs = New ProductTreeNodeExpandEventArgs(nodeId)
RaiseEvent NodeExpand(Me, evetArgs)
//'some logic
End Sub
Protected Sub ProductTree_OnNodeClick(ByVal sender As Object, ByVal e As RadTreeNodeEventArgs) _
Handles treeProductTree.NodeClick
RaiseEvent SelectedNodeChange(Me, New System.EventArgs())
End Sub
End Class
What I don't know is: why is this causing full postback instead of partial? I suspect that it may have something to do with raising my for SelectedNodeChange, but I don't know how to deal with it other way. I need to let other components know, that node selection changed. How can I improve this to make it work with UpdatePanels?
Suspect that registering a UserControl as an AsyncPostbackTrigger is not going to get you very far. The UC itself is not a postback control, rather, it contains one. I would expose the tree control as a public property of the usercontrol, and then in code behind in your containing page, register the tree control itself as the trigger, rather than the UserControl.
Check this for a similar situation... it's not a great Q&A thread but it shows the basic gist.
Well, I have the similar situation but it's a little more complicated.
User control causing postback is actually added dynamically depending on the request parameter value.
I was so glad the ClietIDMode paramter was added, I didn't think a problem like tat would be overlooked by Microsoft.
The same problem that I am facing right now... I thing that could be fixed by wrapping up the UC with an iFrame.
How is everyone today?
The Problem
Basically, I'm delving into the world of the AjaxControlToolkit today, with the main aim of fulfilling my AutoComplete requirements. I've set everything up as tutorialised and am a little confused as to why things aren't working (well I have an inkling as to what may be holding me back).
I've added the AjaxControlToolkit dll to my project and in my Markup I have the following :
at the top
<%# Register Assembly="AjaxControlToolkit" Namespace="AjaxControlToolkit" TagPrefix="ajaxControlToolkit" %>
then within my content
<ajaxControlToolkit:ToolkitScriptManager ID="ToolkitScriptManager1" runat="server"></ajaxControlToolkit:ToolkitScriptManager>
<asp:TextBox ID="txtSearch" runat="server" CssClass="search"></asp:TextBox>
<ajaxControlToolkit:AutoCompleteExtender ID="autoCompleteSearchExtender" runat="server" TargetControlID="txtSearch" ServiceMethod="GetCompletionList"></ajaxControlToolkit:AutoCompleteExtender>
Then in the code behind, I have my nice little function (which the breakpoint within is never reached)
<System.Web.Services.WebMethodAttribute(), System.Web.Script.Services.ScriptMethodAttribute()> _
Public Function GetCompletionList(ByVal prefixText As String, ByVal count As Integer, ByVal contextKey As String) As String()
' Get current list
Dim myList As List(Of MyClass) = GetSearchResultList()
Return (From s In myList Select s.Name).ToArray()
End Function
The function is never being called, for a reason I am unsure of.
Potential Issues
There are a couple of potential issues where things may be going wrong:
I've tried adding the AjaxControlToolkit dll to the Toolbar in VS (2010), but all the controls are greyed out...
The GetCompletionList function (WebMethod) I have written is in the code behind the page. Could this not be called because it has to be in a Web Service perhaps?
I've also just realised that my function in the code behind isn't Shared, is this required? Because the list associated with the auto complete is dynamic.
Any help would be appreciated.
Thanks in advance.
Try putting your GetCompletionList function in a web-service (asmx is easiest). Make sure the the web-service class has a [ScriptService] attribute and that your function has a [ScriptMethod] attribute.
You'll also need to supply the path to the web-service in your AutoCompleteExtender's "ServicePath" property (i.e. ServicePath="~/MyService.asmx")
Also, you don't need the "contextKey" parameter in your function unless you are passing a context key from your AutoCompleteExtender control.
hth
Update: Add these attributes and try it. I have implemented and it works with page behind web methods.
ServiceMethod="yourGetfunction"
MinimumPrefixLength="2"
CompletionInterval="100"
EnableCaching="FALSE"
CompletionSetCount="20"
You can check this solution: http://suggester.codeplex.com/
Demo to test: http://show-demos.net/suggester/
Its not from ALAX Toolkit but it uses ASP.NET AJAX and jQuery and has more rich functionality
I kind of made this working:
<WebMethod()> _
Public Shared Function GetCompletionList(ByVal prefixText As String, ByVal count As Integer) As List(Of String)
Dim listData As New List(Of String)
listData.Add("A")
listData.Add("B")
listData.Add("C")
Return listData
End Function
My html:
<form id="maincontent" runat="server">
<asp:ScriptManager ID="ScriptManager1" runat="server" EnablePageMethods = "true">
</asp:ScriptManager>
<div>
<table style="margin-top:40px;color:White">
<tr>
<td>
Type in your search:
</td>
<td>
<asp:TextBox ID="searchBox" runat="server"></asp:TextBox>
<asp:AutoCompleteExtender ServiceMethod="GetCompletionList" MinimumPrefixLength="1"
CompletionInterval="10" EnableCaching="false" CompletionSetCount="1" TargetControlID="searchBox"
ID="AutoCompleteExtenderPersonSearch" runat="server" FirstRowSelected="false">
</asp:AutoCompleteExtender>
</td>
</tr>
</table>
</div>
</form>