I did it like this.
I removed the frame template completely. Removed ControlViewer.aspx page also.
Added one div on my Settings.aspx page and loaded the user controls in the div using ajax call on tab click.
This is HTML
<div ng-app="myApp">
<div ng-controller="MainCtrl">
<div class="tabbable padTop10">
<ul class="nav nav-tabs">
<li ng-repeat="hTab in horzTabs track by $index" ng-class="{'active':hTab.active}"><a ng-click="setActive(hTab, true);">{{hTab.SSHVSettingsTabGroupName}}</a></li>
</ul>
<div class="tab-content">
<div class="tab-pane" ng-class="{'active': hTab.active}" ng-repeat="hTab in horzTabs track by $index">
<div ng-if="hTab.SSHVSettingsTabInfo" class="tabbable tabs-left">
<ul class="nav nav-tabs">
<li ng-repeat="vTab in hTab.SSHVSettingsTabInfo track by $index" ng-class="{'active':vTab.active }">
<a ng-click="setActive(vTab, false);">{{vTab.TabCaption}}</a>
</li>
</ul>
<div id="dvUserControl" class="tab-pane active tab-content col-pad-10 borderAll tabContentCustom"></div>
</div>
</div>
</div>
</div>
</div>
</div>
In .js file
app.controller('MainCtrl', function ($scope, $sce) {
$scope.iMainTabIndex = 0;
$scope.horzTabs = tabCollection;
$scope.currentHTab = $scope.horzTabs[$scope.iMainTabIndex];
$scope.currentHTab.active = true;
$scope.currentVTab = $scope.currentHTab.SSHVSettingsTabInfo[0];
$scope.currentVTab.active = true;
$scope.iTab1Index = 0;
$scope.setActive = function (tab, horz) {
var tabdir;
if (horz) tabdir = 'H';
else tabdir = 'V'
tab.active = true;
if ($scope['current' + tabdir + 'Tab']) {
$scope['current' + tabdir + 'Tab'].active = false;
}
$scope['current' + tabdir + 'Tab'] = tab;
if(horz && tab.URL.length > 0)
$scope.loadTab(tab.Type, tab.URL);
else if(horz && tab.URL.length == 0)
$scope.loadTab($scope.currentVTab.Type, $scope.currentVTab.URL);
else
$scope.loadTab(tab.Type, tab.URL);
}
angular.element(document).ready(function () {
$scope.loadTab($scope.currentVTab.Type, $scope.currentVTab.URL);
});
$scope.loadTab = function (type, url) {
if (url != 'undefined' && url.length > 0)
var controlName = url.substring(2, url.length);
if (type == '0') {
$.ajax({
type: "POST",
url: "../AdminView/Settings.aspx/Result",
data: "{ controlName:'" + controlName + "'}",
contentType: "application/json; charset=utf-8",
dataType: "json",
success: function (response) {
$('#dvUserControl').html(response.d);
},
error: function (msg) {
alert(msg);
$('#dvUserControl').html(msg.d);
}
});
} else {
$('#dvUserControl').load(url);
}
}
});
In Settings.aspx.cs
[WebMethod]
public static string Result(string controlName)
{
return Results(controlName);
}
public static string Results(string controlName)
{
try
{
Page page = new Page();
UserControl userControl = (UserControl)page.LoadControl(@"~\SettingControls\" + controlName);
userControl.EnableViewState = false;
HtmlForm form = new HtmlForm();
form.Controls.Add(userControl);
page.Controls.Add(form);
StringWriter textWriter = new StringWriter();
HttpContext.Current.Server.Execute(page, textWriter, false);
return textWriter.ToString();
}
catch (Exception ex)
{
return ex.ToString();
}
}
It worked. :)