PDA

View Full Version : [CLOSED] Migration of UserControls



rmelancon
Jul 01, 2013, 3:34 PM
I am in the process of migrating our app from 1.x and we have pages that are based on master pages that contain users control that themselves contain user controls, that may contain user controls... In addition there are <asp:ContentPlaceHolder in use.

Initially I got the error "Control with type 'Ext.Net.XScript' cannot be handled by layout". So I changed all the places that had:



<Content>
<uc:HouseholdAllocationChart ID="HouseholdAllocationChart" runat="server" />
</Content>


to instead use:


<Items>
<ext:Container ID="Container2" runat="server">
<HtmlBin>
<uc:HouseholdAllocationChart ID="HouseholdAllocationChart" runat="server" />
</HtmlBin>
</ext:Container>
</Items>



and in the case where the usercontrol was within an <asp:Content block:



<asp:Content ID="Content2" ContentPlaceHolderID="ResultGridPlaceHolder" runat="server">
<ext:Viewport ID="Viewport" runat="server" Layout="FitLayout">
<Items>
<ext:Container ID="Container3" runat="server">
<HtmlBin>
<uc:ResultGridClient ID="ResultGridClient" runat="server" />
</HtmlBin>
</ext:Container>
</Items>
</ext:Viewport>
</asp:Content>


After the change, I now get the error "Only Content controls are allowed directly in a content page that contains Content controls."

So I'm trying to get a better understanding of how this should be laid out in 2.x. The page, like I said is very complex with lots of reuseable user controls, so I'll do my best to layout the current structure so hopefully you can provide me with a baseline of how it should be laid out in 2.x

In the Master page:



<asp:Content ContentPlaceHolderID="MainContent" runat="server">

... several <ext:Window

<ext:FitLayout runat="server">
<Items>
<ext:Panel ID="DataMiningPanel" runat="server" Border="false" Layout="BorderLayout">
...

<ext:Panel ID="ResultSummaryPanel" runat="server" Title="Summary" Icon="Information" Hidden="true" Region="East" Split="true" Width="600" AutoScroll="true" Padding="5" Layout="FitLayout">
<Tools>
<ext:Tool Type="Close" Handler="#{ResultSummaryPanel}.hide(); #{DataMiningPanel}.doLayout();" />
</Tools>
<Items>
<ext:Panel runat="server" Border="false" AutoHeight="true" AutoWidth="true">
<Content>
<asp:ContentPlaceHolder ID="ResultSummaryPlaceHolder" runat="server" />
</Content>
</ext:Panel>
</Items>
</ext:Panel>

<ext:Panel ID="ResultDetailsPanel" runat="server" Title="Details" Icon="Information" Hidden="true" Region="South" Split="true" Height="400">
<Tools>
<ext:Tool Type="Close" Handler="#{ResultDetailsPanel}.hide(); #{DataMiningPanel}.doLayout();" />
</Tools>
<Content>
<asp:ContentPlaceHolder ID="ResultDetailsPlaceHolder" runat="server" />
</Content>
</ext:Panel>

</Items>
</ext:Panel>
</Items>
</ext:FitLayout>


</asp:Content>


Here is a page that uses the above master:


<%@ Page Title="" Language="vb" AutoEventWireup="false" MasterPageFile="~/DataMining.master" CodeBehind="DataMiningClient.aspx.vb" Inherits="Adhesion.Web.DataMiningClientPage" %>

<%@ MasterType VirtualPath="~/DataMining.master" %>

<%@ Register TagPrefix="uc" TagName="ResultGridClient" Src="~/ResultGridClient.ascx" %>
<%@ Register TagPrefix="uc" TagName="ResultSummaryClient" Src="~/ResultSummaryClient.ascx" %>

<asp:Content ContentPlaceHolderID="ResultGridPlaceHolder" runat="server">
<uc:ResultGridClient ID="ResultGridClient" runat="server" />
</asp:Content>

<asp:Content ContentPlaceHolderID="ResultSummaryPlaceHolder" runat="server">
<uc:ResultSummaryClient ID="ResultSummaryClient" runat="server" />
</asp:Content>


and finally here is one of the "sub" controls



<%@ Control Language="vb" AutoEventWireup="false" CodeBehind="ResultSummaryClient.ascx.vb" Inherits="Adhesion.Web.ResultSummaryClientControl" %>

<%@ Register TagPrefix="uc" TagName="HouseholdAllocationChart" Src="~/HouseholdAllocationChart.ascx" %>
<%@ Register TagPrefix="uc" TagName="AccountAllocationChart" Src="~/AccountAllocationChart.ascx" %>
<%@ Register TagPrefix="uc" TagName="HouseholdPerformanceChart" Src="~/HouseholdPerformanceChart.ascx" %>
<%@ Register TagPrefix="uc" TagName="AccountPerformanceChart" Src="~/AccountPerformanceChart.ascx" %>
<%@ Register TagPrefix="uc" TagName="HouseholdDetails" Src="~/HouseholdDetails.ascx" %>
<%@ Register TagPrefix="uc" TagName="AccountDetails" Src="~/AccountDetails.ascx" %>
<%@ Register TagPrefix="uc" TagName="ProposalAccountDetails" Src="~/ProposalAccountDetails.ascx" %>
<%@ Register TagPrefix="uc" TagName="Reports" Src="~/ResultSummaryReports.ascx" %>
<%@ Register TagPrefix="uc" TagName="Notes" Src="~/ResultSummaryNotes.ascx" %>
<%@ Register TagPrefix="uc" TagName="Tags" Src="~/ResultSummaryTags.ascx" %>

<ext:FitLayout runat="server">
<Items>
<ext:Panel ID="MainPanel" runat="server" Border="false" Width="600" AutoHeight="true">
<Defaults>
<ext:Parameter Name="cls" Value="result-summary-margin" Mode="Value" />
</Defaults>
<Items>
<ext:Panel ID="MarketValueCardPanel" runat="server" Title="Market Value" Height="200" Collapsible="true" Padding="5" Layout="CardLayout">
<Tools>
<ext:Tool Type="Restore" Handler="#{DirectMethods}.OpenMarketValue();" Qtip="Market&nbsp;Value<br/>Transactions<br/>Relationships<br/>Custom&nbsp;URL" />
</Tools>
<Items>
<ext:Container runat="server">
<Content>
<uc:HouseholdAllocationChart ID="HouseholdAllocationChart" runat="server" />
</Content>
</ext:Container>
<ext:Container runat="server">
<Content>
<uc:AccountAllocationChart ID="AccountAllocationChart" runat="server" />
</Content>
</ext:Container>
</Items>
</ext:Panel>
<ext:Panel ID="AnalyticsCardPanel" runat="server" Title="Analytics" Height="200" Collapsible="true" Padding="5" Layout="CardLayout">
<Tools>
<ext:Tool Type="Restore" Handler="#{DirectMethods}.OpenPerformance();" Qtip="Performance<br/>Performance&nbsp;Refresh<br/>Performance&nbsp;Filters" />
</Tools>
<Items>
<ext:Container runat="server">
<Content>
<uc:HouseholdPerformanceChart ID="HouseholdPerformanceChart" runat="server" />
</Content>
</ext:Container>
<ext:Container runat="server">
<Content>
<uc:AccountPerformanceChart ID="AccountPerformanceChart" runat="server" />
</Content>
</ext:Container>
</Items>
</ext:Panel>
<ext:Panel ID="ReportsPanel" runat="server" Title="Reporting" Collapsible="true" Layout="FitLayout">
<Tools>
<ext:Tool Type="Restore" Handler="#{DirectMethods}.OpenReporting();" Qtip="Quick&nbsp;Reports<br/>Reporting<br/>Performance&nbsp;Refresh" />
</Tools>
<Content>
<uc:Reports ID="Reports" runat="server" />
</Content>
</ext:Panel>
<ext:Panel ID="DetailsCardPanel" runat="server" Title="Details" Collapsible="true" Padding="5" Layout="CardLayout" AutoHeight="true">
<Tools>
<ext:Tool Type="Restore" Handler="#{DirectMethods}.OpenAdmin();" Qtip="Household/Account&nbsp;Admin<br />Custom&nbsp;URL" />
</Tools>
<Items>
<ext:Container runat="server" AutoHeight="true">
<Content>
<uc:HouseholdDetails ID="HouseholdDetails" runat="server" />
</Content>
</ext:Container>
<ext:Container runat="server" AutoHeight="true">
<Content>
<uc:AccountDetails ID="AccountDetails" runat="server" />
</Content>
</ext:Container>
</Items>
</ext:Panel>
<ext:Panel ID="ProposalAccountPanel" runat="server" Title="UMA" Collapsible="true" Padding="5" AutoHeight="true">
<Tools>
<ext:Tool Type="Restore" Handler="#{DirectMethods}.OpenProposal();" Qtip="UMA&nbsp;Admin" />
</Tools>
<Content>
<uc:ProposalAccountDetails ID="ProposalAccountDetails" runat="server" />
</Content>
</ext:Panel>
<ext:Panel ID="NotesPanel" runat="server" Title="Notes" Collapsible="true" AutoHeight="true">
<Content>
<uc:Notes ID="Notes" runat="server" />
</Content>
</ext:Panel>
<ext:Panel ID="TagsPanel" runat="server" Title="Tags" Collapsible="true" AutoHeight="true">
<Content>
<uc:Tags ID="Tags" runat="server" />
</Content>
</ext:Panel>
</Items>
</ext:Panel>
</Items>
</ext:FitLayout>



So basically I'm looking for a "best practice" in converting all of the containers/panels holding the user controls. If it helps I can post my attempted conversion of the above markup.

Thanks,
Robb

Daniil
Jul 01, 2013, 5:37 PM
Hi Robb,

This exception

Initially I got the error "Control with type 'Ext.Net.XScript' cannot be handled by layout"
can be reproduced with the following example.

Page

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

<%@ Register Assembly="Ext.Net" Namespace="Ext.Net" TagPrefix="ext" %>
<%@ Register Src="~/TestUC.ascx" TagPrefix="uc" TagName="TestUC" %>

<!DOCTYPE html>
<html>
<head runat="server">
<title>Ext.NET v2 Example</title>
</head>
<body>
<form runat="server">
<ext:ResourceManager runat="server" />

<ext:Panel runat="server" Title="Page Panel" Layout="FitLayout">
<Content>
<uc:TestUC runat="server" />
</Content>
</ext:Panel>
</form>
</body>
</html>


User Control

<%@ Control Language="C#" %>

<ext:XScript runat="server">
<script>
var testFunction = function () { }
</script>
</ext:XScript>

<ext:Panel runat="server" Title="User Control Panel" />

The exception means that the XScript control of the User Control cannot be handled by Layout="FitLayout" of the Panel in the Page.

I can say that it also doesn't work in Ext.NET v1, just an Exception is not thrown, but Layout="FitLayout" is just ignored.

There are two approaches to avoid the exception.

1. Remove Layout="FitLayout". Then the User Control will be rendered as a Panel's Content (raw HTML) without any layout logic.

2. Move the XScript control into the Panel's HtmlBin.

Corrected User Control

<%@ Control Language="C#" %>

<ext:Panel runat="server" Title="User Control Panel">
<HtmlBin>
<ext:XScript runat="server">
<script>
var testFunction = function () { }
</script>
</ext:XScript>
</HtmlBin>
</ext:Panel>



So basically I'm looking for a "best practice" in converting all of the containers/panels holding the user controls.

I don't think there is an entire policy and there should not be many changes. The mayor change is to replace layout type controls with Layout property of containers, see #34 here.
http://examples2.ext.net/#/Getting_Started/Release_Documents/BREAKING_CHANGES/

If this change throws an Exception we discussed above, it should mean that the Layout control has been just ignored in v1 and, supposedly, might be considered fro removal if we are talking about migration. If you do want layouts to be applied, then you could try with the HtmlBin feature. But it is rather improving than just migrating.

Hope this helps.

rmelancon
Jul 01, 2013, 6:00 PM
So in the case of a UserControl with <ext:XScript> code that is used by multiple windows such as below, where would you put the <ext:XScript>?
Would you have multiple copies of the XScript code in each of the separate windows and panels that needed the functions?




<ext:XScript runat="server">

<script type="text/javascript">

var getNodeParameter = function (tree) {
var selNode = tree.getSelectionModel().getSelectedNode();
return selNode ? tree.convertToSubmitNode(selNode) : -1;
};


var dropfile = null;

Ext.onReady(function () {
var dropbox = document.getElementById("dropbox");
// init event handlers
dropbox.addEventListener("dragenter", noopHandler, false);
dropbox.addEventListener("dragexit", noopHandler, false);
dropbox.addEventListener("dragover", noopHandler, false);
dropbox.addEventListener("drop", drop, false);
});

var noopHandler = function (e) {
e.stopPropagation();
e.preventDefault();
};

</script>

<ext:Window ID="ImportWindow" runat="server" Icon="PackageIn" Title="Import Filter" Hidden="true" Layout="CardLayout" ActiveIndex="0" Width="400" Height="300" Modal="true">
<Items>
<ext:Panel ID="ImportPanel" runat="server" Border="false" Layout="FitLayout">
<Content>
<div id="dropbox">Drop filter file here...</div>
</Content>
</ext:Panel>
<ext:Panel ID="PreviewPanel" runat="server" Border="false" Padding="15" Layout="FormLayout">
<Content>
Now click the button below to begin importing <strong><span id="dropfile"/></strong>
</Content>
</ext:Panel>
...
<Buttons>
<ext:Button ID="ImportButton" runat="server" Text="Import" Icon="Accept" Disabled="true">
<Listeners>
<Click Handler="importFilter();" />
</Listeners>
</ext:Button>
</Buttons>
</ext:Window>

<ext:Panel ID="FiltersPanel" runat="server" Border="false" Layout="VBoxLayout">
<LayoutConfig>
<ext:VBoxLayoutConfig Align="Stretch" />
</LayoutConfig>
...
<ext:TreePanel ID="AvailableCriteriaTree" runat="server" Title="Available Criteria" RootVisible="false" AutoScroll="true" Border="false" Flex="1">
<DirectEvents>
<ItemClick OnEvent="AvailableCriteriaTree_Click" Before="return !node.hasChildNodes();">
<EventMask ShowMask="true" Msg="Loading Criteria" Target="Page" />
<ExtraParams>
<ext:Parameter Name="node" Value="getNodeParameter(#{AvailableCriteriaTree})" Mode="Raw" Encode="true" />
</ExtraParams>
</ItemClick>
</DirectEvents>
<Root>
<ext:Node />
</Root>
</ext:TreePanel>
</Items>
</ext:Panel>


</ext:XScript>

Daniil
Jul 02, 2013, 5:15 AM
You should not copy it into all the Windows. Yes, you could put it to HtmlBin of some Window.

Also I would recommend not to add Windows to a container's Items, but put it into its Bin collection instead.