usercontrol template system c# - c#

I want to use string replace to replace the tag {tag:shoppingcart} and in that it would load the user control:
<%# Register TagPrefix="basket" TagName="cart" src="~/controls/basket.ascx" %>
<basket:cart id="test" runat="server"></basket:cart>
I would be defining the controls at the top of the page that needs them.
My question is what is my best way to achieve the following if it is at all possible
string templatehtml;
templatehtml = template[0].Cms;
string newhtml;
newhtml = templatehtml.Replace("{tag_pagecontent}", currentPage[0].Body);
newhtml = templatehtml.Replace("{tag_shoppingcart}", <basket:cart id="test" runat="server"></basket:cart>);
litcontent.Text = newhtml;
It's the <basket:cart code i am having trouble with.

We actually do a very similar thing, except we have placeholder divs on the page.
In the page_init method, we get a reference to the placeholder div, load the user control into the page, and then add the usercontrol to the div's controls.
For example (very rough code):
// Get a reference to the div
Control oUserControlDiv = this.FindControl("divUserControl");
// Load the user control
Control oControl = this.LoadControl("controls/basket.ascx");
oControl.EnableViewState = true;
// Clear the existing control(s) from the div
oUserControlDiv.Controls.Clear();
// And add the new one
oUserControlDiv.Controls.Add(oControl);

Please try this instead:
var basket = new Basket();
StringBuilder sb = new StringBuilder();
StringWriter sw = new StringWriter(sb);
using (HtmlTextWriter writer = new HtmlTextWriter(sw))
{
basket.RenderControl(writer);
}
string basketHtml = sb.ToString();
newhtml = templatehtml.Replace("{tag_shoppingcart}", basketHtml);

Related

How to add both input and validation control from codebehind

I am working within a CMS known as RiSE built in iMIS (I don't recommend)
I am building a plugin type thing which will allow the administrator from the backend of the program to build a contact form. (really simple right!?!?!?)
So, I don't know what, or how many form inputs will be present to process.
the process is for each added input
add its "id" to a list to be used when the form is submitted
build the input and add attributes based on administrator selected options
add the validator
The following code is the piece the adds the inputs to the page. The idea is simple, the administrator "creates" the input and chooses their options (name, label, placeholder, readonly, etc)
The codebehind would then take these options and build the input and corosponding input validation control.
I keep getting this error
Unable to find control id 'text_9d8f153' referenced by the 'ControlToValidate' property of 'val_9d8f153'.
here are the files;
EmailFormTextBoxDisplay.ascx
<%# Control Language="C#" AutoEventWireup="True" CodeBehind="EmailFormTextBoxDisplay.ascx.cs" Inherits="EmailForm.EmailFormTextBoxDisplay" %>
<%# Register TagPrefix="telerik" Namespace="Telerik.Web.UI" Assembly="Telerik.Web.UI" %>
<%# Register TagPrefix="asiweb" Assembly="Asi.Web" Namespace="Asi.Web.UI.WebControls" %>
<div onprerender="buildMe" runat="server"></div>
EmailFormTextBoxDisplay.ascx.cs
using System
...
protected void buildMe(object sender, EventArgs e)
{
HtmlGenericControl div = (HtmlGenericControl)sender;
if (EmailForm.formProcessed)
{
div.Visible = false;
}
else
{
String id = inputEmailLabel.Replace(" ", "-") + "_" + randId;
// add this input to the list
EmailForm.inputs.Add(new String[]
{
id,
inputType,
inputEmailLabel
});
// if label is not empty, add it
if (inputLabel != "")
{
HtmlGenericControl label = new HtmlGenericControl("label");
label.InnerText = inputLabel + " ";
label.TagName = "label";
div.Controls.Add(label);
}
// build and add the input
HtmlInputGenericControl input = new HtmlInputGenericControl("input");
// get each setting and add attributes to the input
input.Attributes.Add("type", inputType);
input.Attributes.Add("id", id);
input.Attributes.Add("placeholder", inputPlaceholder);
if (inputValue != "") input.Attributes.Add("value", inputValue);
if (inputDisabled) input.Attributes.Add("disabled", "disabled");
if (inputReadOnly) input.Attributes.Add("readonly", "readonly");
if (inputRequired)
{
input.Attributes.Add("required", "required");
AsiRequiredFieldValidator required = new AsiRequiredFieldValidator();
required.ControlToValidate = id;
required.ID = "val_" + randId;
required.Text = "This is Required";
div.Controls.Add(required);
}
if (inputRegEx != "" && inputRegEx != null)
{
AsiRegularExpressionValidator regEx = new AsiRegularExpressionValidator();
regEx.ValidationExpression = inputRegEx;
regEx.ControlToValidate = id;
regEx.ID = "regExVal_" + randId;
regEx.Text = inputRegExMsg;
div.Controls.Add(regEx);
}
div.Controls.Add(input);
}
}
I have tried breaking the validation part out into it's own method, and calling the first part (making the input) onLoad and then adding the validators onPreRender but I get the same error.
I also tried using Control.AddAt(2, input) to ensure the <input /> is before the validator, but to no avail.
How can I build an input & validation dynamically?
You need to use reference the ID generated by aspnet, not the one set by an Attribute. THis is because the ID will be renamed by aspnet client side, so the actual ID in html might become something like this ctl00_PlaceHolder1_myID
HtmlInputGenericControl input = new HtmlInputGenericControl("input");
input.ID = id;
and then the Validator
required.ControlToValidate = input.ID;
You could also use "real" aspnet Controls.
TextBox tb = new TextBox();
tb.ID = "myTextBox" + i;
RequiredFieldValidator val = new RequiredFieldValidator();
val.ControlToValidate = tb.ID;
val.ErrorMessage = "Required field";
Literal lit = new Literal();
lit.Text = "<br>";
PlaceHolder1.Controls.Add(tb);
PlaceHolder1.Controls.Add(val);
PlaceHolder1.Controls.Add(lit);
ControlToValidate requires the server side id of the control you want to validate. You will need to set the id of the control like this:
input.ID = "MY_ID";
Then use the inputs id to validate:
required.ControlToValidate = input.ID;

How to use html tag in code behind?

I need to use html tags such as <sup></sup> in code behind without declaring anything in aspx page.
So far I've tried below:
string s = HtmlTextWriterTag.Sup.ToString("1");
Try this one:
var strVariable = "This is a string object";
strVariable = strVariable.sup();
From MSDN
you may use html gerneric contorls
HtmlGenericControl sub= new HtmlGenericControl("sub");
sub.Attributes.Add("class", "your-class");
sub.ID = "subId";
sub.ClientIDMode = ClientIDMode.Static;

Rendering a control to HTML without __VIEWSTATE

I'm using a web service to get and render a GridView to HTML. The idea is to generate it asynchronously (to generate the data in a hidden row for an expandable grid, for example).
[System.Web.Services.WebMethod]
[System.Web.Script.Services.ScriptMethod]
public static string ExpandRowService(string contextKey)
{
try
{
long recId = long.Parse(contextKey);
return RenderControlToHtml("/Controls/SubGrid.ascx", recId);
}
catch (Exception)
{
return "";
}
}
public static string RenderControlToHtml(string controlPath, params object[] constructorParams)
{
var page = new Page
{
EnableEventValidation = false,
EnableViewState = false,
};
var form = new HtmlForm
{
EnableViewState = false
};
page.Controls.Add(form);
var control = page.LoadControl(controlPath, constructorParams);
form.Controls.Add(control);
return page.RenderControl();
}
The problem is that rendering to HTML like that needs a dummy form to render into, and that dummy form has a __VIEWSTATE hidden input:
<form method="post" action="ExpandRowService" id="ctl00">
<div class="aspNetHidden">
<input type="hidden" name="__VIEWSTATE" id="__VIEWSTATE" value="" />
</div>
On postback after any other action, there are more than one __VIEWSTATE variables and that's obviously a no-no.
How can I force rendering of a control to HTML without the accursed __VIEWSTATE hiden input?
EDIT:
I'm using a GridView and not making a table from scratch because I need its data binding capabilities to set various styles (for example: mark negative amounts in red).
You can render the control itself, without the surrounding form. All you need is to setup a HtmlTextWriter instance backed by a reasonable storage, such as a StringBuilder:
// create control and make it part of a form and page
…
// render just the control
var c = new StringBuilder();
using (var sw = new StringWriter(c))
{
using (var writer = new HtmlTextWriter(sw))
{
control.RenderControl(writer);
}
}
return c.ToString();
It appears that it is not possible to generate the control with LoadControl into a form (required) and not have a __VIEWSTATE.
I made my own TableWriter, and did some rowbinding to it. Best I could do.

Print a ListView from my C# Web App

Im building out a c# web app here and I have a Listview. I would like to have a button on the page that when clicked it will print the listview easily. Anyone have any idea how this would be done?
Thanks
Try Adding the following code inside the button click event. Hope fully it will help.
this.ListView1.DataBind();
StringWriter sw = new StringWriter();
HtmlTextWriter hw = new HtmlTextWriter(sw);
ListView1.RenderControl(hw);
string ListViewHTML = sw.ToString().Replace("\"", "'").Replace(System.Environment.NewLine, "");
StringBuilder sb = new StringBuilder();
sb.Append("<script type = 'text/javascript'>");
sb.Append("window.onload = new function(){");
sb.Append("var printList = window.open('', '', 'left=0");
sb.Append(",top=0,width=800,height=700,status=0');");
sb.Append("printList.document.write(\"");
sb.Append(ListViewHTML);
sb.Append("\");");
sb.Append("printList.document.close();");
sb.Append("printList.focus();");
sb.Append("printList.print();");
sb.Append("printList.close();};");
sb.Append("</script>");
ClientScript.RegisterStartupScript(this.GetType(), "ListViewPrint", sb.ToString());
this.ListView1.DataBind();
There are 2 options that I can think of:
Send this to a different page with an ID (perhaps the order number?) in the query string; read the order id from the query string, and output the details in the page. Then call window.print on window.load
Something like:
Order o = DAL.GetOrderByID(int.Parse(Request.QueryString["OrderID"]));
//output the order in this new page...
On this new page, have a line like this:
window.onload=function(){window.print();};
Use this jquery plugin to do it. It creates a frame in the page and calls .print on the frame. Seems very simple to implement.

How to remove ViewState and EventValidation data in ASP.NET Control render to string?

I'm using the following method to render a user control to a string:
Page pageHolder = new Page();
pageHolder.EnableViewState = false;
UserControl viewControl = (UserControl)pageHolder.LoadControl(path);
viewControl.EnableViewState = false;
System.Type viewControlType = viewControl.GetType();
HtmlForm tempForm = new HtmlForm();
tempForm.EnableViewState = false;
tempForm.Controls.Add(viewControl);
pageHolder.Controls.Add(tempForm);
StringWriter output = new StringWriter();
HttpContext.Current.Server.Execute(pageHolder, output, false);
string content = output.ToString();
However, in the output, there are sometimes hidden fields with __EVENTVALIDTION and __VIEWSTATE info as well as JavaScript to enable PostBack.
Is there a way to completely disable all WebForms/ViewState related code from being generated for the control I'm trying to render? Setting EnableViewState to false and setting the EnabledViewState="false" in the .ascx file doesn't seem to work.
Did you try
<pages enableViewState="false" enableEventValidation="false">
...
</pages>
On your web.config?
I am not sure it's a good idea in general, but I assume you know what you are doing.
You can set EnableViewState="false" in the directive of the user control. As for disabling event validation, I believe you can only do that through the web.config or page directive.

Categories