Creating UserControl Via Webpart. i need css file import but how? - c#

Everything is ok. i van see StyleSheet.css in page source.But css effect can not run my gridview. How can i do that
public class MyGridView : WebPart
{
GridView gvCustomers;
protected override void CreateChildControls()
{
gvCustomers = new GridView();
HtmlHead head = (HtmlHead)Page.Header;
HtmlLink link = new HtmlLink();
link.Attributes.Add("href", Page.ResolveClientUrl("StyleSheet.css"));
link.Attributes.Add("type", "text/css");
link.Attributes.Add("rel", "stylesheet");
head.Controls.Add(link);
gvCustomers.CssClass = "tablestyle";
gvCustomers.HeaderStyle.CssClass = "headerstyle";
gvCustomers.AlternatingRowStyle.CssClass = "altrowstyle";
gvCustomers.RowStyle.CssClass = "rowstyle";
this.Controls.Add(gvCustomers);
}
public object DataSource
{
get {
this.EnsureChildControls();
return gvCustomers.DataSource; }
set {
this.EnsureChildControls();
gvCustomers.DataSource = value; }
}

Have you tried a ScriptManagerProxy control? using this control within your user control can determine if the CSS has already been added to your page, and only add one reference to your css file

Related

Does a child web page inherit the text boxes which were there in the master web page? [duplicate]

I have a master page which contains a label for status messages. I need to set the status text from different .aspx pages. How can this be done from the content page?
public partial class Site : System.Web.UI.MasterPage
{
public string StatusNachricht
{
get
{
return lblStatus.Text;
}
set
{
lblStatus.Text = value;
}
}
protected void Page_Load(object sender, EventArgs e)
{
}
}
I have tried this, but was unsuccessful in making it work:
public partial class DatenAendern : System.Web.UI.Page
{
var master = Master as Site;
protected void Page_Load(object sender, EventArgs e)
{
if (master != null)
{
master.setStatusLabel("");
}
}
protected void grdBenutzer_RowCommand(object sender, GridViewCommandEventArgs e)
{
try
{
//some code
if (master != null)
{
master.setStatusLabel("Passwort erfolgreich geändert.");
}
}
catch (Exception ex)
{
if (master != null)
{
master.setStatusLabel("Passwort konnte nicht geändert werden!");
}
}
}
}
}
In the MasterPage.cs file add the property of Label like this:
public string ErrorMessage
{
get
{
return lblMessage.Text;
}
set
{
lblMessage.Text = value;
}
}
On your aspx page, just below the Page Directive add this:
<%# Page Title="" Language="C#" MasterPageFile="Master Path Name"..... %>
<%# MasterType VirtualPath="Master Path Name" %> // Add this
And in your codebehind(aspx.cs) page you can then easily access the Label Property and set its text as required. Like this:
this.Master.ErrorMessage = "Your Error Message here";
In Content page you can access the label and set the text such as
Here 'lblStatus' is the your master page label ID
Label lblMasterStatus = (Label)Master.FindControl("lblStatus");
lblMasterStatus.Text = "Meaasage from content page";
It Works
To find master page controls on Child page
Label lbl_UserName = this.Master.FindControl("lbl_UserName") as Label;
lbl_UserName.Text = txtUsr.Text;
I have a helper method for this in my System.Web.UI.Page class
protected T FindControlFromMaster<T>(string name) where T : Control
{
MasterPage master = this.Master;
while (master != null)
{
T control = master.FindControl(name) as T;
if (control != null)
return control;
master = master.Master;
}
return null;
}
then you can access using below code.
Label lblStatus = FindControlFromMaster<Label>("lblStatus");
if(lblStatus!=null)
lblStatus.Text = "something";
You cannot use var in a field, only on local variables.
But even this won't work:
Site master = Master as Site;
Because you cannot use this in a field and Master as Site is the same as this.Master as Site. So just initialize the field from Page_Init when the page is fully initialized and you can use this:
Site master = null;
protected void Page_Init(object sender, EventArgs e)
{
master = this.Master as Site;
}
This is more complicated if you have a nested MasterPage. You need to first find the content control that contains the nested MasterPage, and then find the control on your nested MasterPage from that.
Crucial bit: Master.Master.
See here: http://forums.asp.net/t/1059255.aspx?Nested+master+pages+and+Master+FindControl
Example:
'Find the content control
Dim ct As ContentPlaceHolder = Me.Master.Master.FindControl("cphMain")
'now find controls inside that content
Dim lbtnSave As LinkButton = ct.FindControl("lbtnSave")
If you are trying to access an html element: this is an HTML Anchor...
My nav bar has items that are not list items (<li>) but rather html anchors (<a>)
See below: (This is the site master)
<nav class="mdl-navigation">
<a class="mdl-navigation__link" href="" runat="server" id="liHome">Home</a>
<a class="mdl-navigation__link" href="" runat="server" id="liDashboard">Dashboard</a>
</nav>
Now in your code behind for another page, for mine, it's the login page...
On PageLoad() define this:
HtmlAnchor lblMasterStatus = (HtmlAnchor)Master.FindControl("liHome");
lblMasterStatus.Visible =false;
HtmlAnchor lblMasterStatus1 = (HtmlAnchor)Master.FindControl("liDashboard");
lblMasterStatus1.Visible = false;
Now we have accessed the site masters controls, and have made them invisible on the login page.

Unable to modify the control collection

I'm trying to add a Link to a webform page from a user control. The CSS file contains the styling used by the control. When I try, I get the following exception:
The control collection cannot be modified during DataBind, Init, Load,
PreRender or Unload phase
So, when can anything be added to the controls collection? Seems to me the exception message suggests that all options are off the table. Here's the code:
public partial class AddNoteDlg : UserControl
{
protected void Page_Load(object sender, EventArgs e)
{
RegisterFiles();
}
private void RegisterFiles()
{
Page.ClientScript.RegisterClientScriptInclude(GetType(), "addNoteDlgComponent-1.0.0.js", ResolveUrl("~/Shared/scripts/js/addNoteDlgComponent-1.0.0.js"));
var css = new HtmlLink();
css.Href = ResolveUrl("~/Shared/css/addNoteDlg-0.0.1.css");
css.Attributes["rel"] = "stylesheet";
css.Attributes["type"] = "text/css";
css.Attributes["media"] = "all";
Page.Controls.Add(css);
}
}
Instead, stuck the link tag in the user control markup, as there is no difference, practically speaking.
(The original motivation for doing it programmatically was so I could add it to the header, with Page.Header.Controls.Add(css), allowing me to keep all CSS links in the header.)

Adding Custom GridView to Control collection

I have a custom GridView control in my site, basically just a class extending GridView as
ITCSGridView : GridView
This has caused a bug in the export to excel feature which is adding the control to a table cell and then exporting it. The line the error occurs on is:
NewTableCell(ATable).Controls.Add(AControl);
And the exception thrown is:
The Controls collection cannot be modified because the control contains code blocks (i.e. <% ... %>).
Prior to me extending the GridView control, the export function was working. The only way I have found to get it to work is to pass the first child control of the custom GridView (which is of type System.Web.UI.WebControl.ChildTable) but then I lose the styling which is required.
Any help would be greatly appreciated.
Edit: Additional code added below
The custom GridView class
public class ITCSGridView : GridView
{
private const string ControlHeaderBackColor = "#B0E0E6";
private const string ControlHeaderForeColor = "#000000";
private const string ControlSelectedRowStyleForeColor = "#335555";
public ITCSGridView() : base()
{
ControlProperties();
HeaderProperties();
PagerProperties();
RowProperties();
}
private void ControlProperties()
{
EnableTheming = true;
Width = new Unit("100%");
SkinID = "ITCSGridView";
CellPadding = 2;
BorderStyle = BorderStyle.None;
HorizontalAlign = HorizontalAlign.Center;
AllowSorting = true;
}
private void HeaderProperties()
{
HeaderStyle.HorizontalAlign = HorizontalAlign.Left;
HeaderStyle.BackColor = ColorTranslator.FromHtml(ControlHeaderBackColor);
HeaderStyle.ForeColor = ColorTranslator.FromHtml(ControlHeaderForeColor);
HeaderStyle.Font.Bold = false;
}
private void PagerProperties()
{
AllowPaging = true;
PageSize = SASMisc.DDLGridViewPageSize;
PagerSettings.Position = PagerPosition.TopAndBottom;
PagerSettings.Mode = PagerButtons.NumericFirstLast;
PagerSettings.FirstPageText = "First";
PagerSettings.LastPageText = "Last";
}
private void RowProperties()
{
RowStyle.Wrap = false;
SelectedRowStyle.ForeColor = ColorTranslator.FromHtml(ControlSelectedRowStyleForeColor);
SelectedRowStyle.Font.Bold = false;
}
Within the class that handles exporting the control to Excel, a System.Web.UI.WebControls.Table Control is created and the GridView control is added to a TableCell within the Table Control, the call to NewTableCell(ATable) is the method that returns the System.Web.UI.WebControls.TableCell. This is basically just:
// The GridView control is passed directly to this method from the aspx.cs
private void AddControlToTable(System.Web.UI.WebControls.Table ATable, Control AControl){
var Table = new System.Web.UI.WebControls.Table();
// Excpetion thrown on line below (this works when using standard GridView instead of custom extended)
NewTableCell(ATable).Controls.Add(AControl);
}
private TableCell NewTableCell(System.Web.UI.WebControls.Table ATable)
{
TableCell Lcell = new TableCell();
TableRow LRow = new TableRow();
LRow.Cells.Add(Lcell);
ATable.Rows.Add(LRow);
return Lcell;
} // private TableCell AddToTable(Table ATable)
You probably have on the same page/or control included on the page piece of markup in which you're doing this:
<%= DateTime.Now %>
The DateTime.Now is just for illustration - the <%= %> matters. This screws up control tree & makes dynamical adding of controls (as you're doing impossible). Workaround is simple - enclose all <%= %> statements into runat="server" control - best control for this is placeholder.
So <%= DateTime.Now %> becomes
<asp:PlaceHolder runat="server">
<%= DateTime.Now %>
</asp:PlaceHolder>
Control tree is consistent and you can add controls dynamically from codebehind once more.

ConfirmButtonExtender not working when adding to control collection at runtime

I am trying to add a ConfirmButtonExtender to my controls collection within a custom control at runtime but can not figure out why the extender will not wire to the button that is being added to the controls collection in the same CreateChildControls method. I did a simple test and added a button explicitly to an aspx page and then creating the extender dynamically in the PreRender of the the .cs file of that page and it still did not work. It seems that the only way to get this to work is to have the actual tags on the .aspx page.
Am I missing something?
protected virtual void CreateChildControls(System.Resources.ResourceManager rm)
{
valValidationSummary = new ValidationSummary();
valValidationSummary.ID = "valValidationSummary";
valValidationSummary.ShowSummary = true;
valValidationSummary.HeaderText = rm.GetString("ValidationSummary");
valValidationSummary.CssClass = "error";
btnGetRates = new LocalizedButton();
btnGetRates.ID = "btnGetStats";
btnGetRates.TextResource = rm.GetString("SubmitButton");
btnGetRates.Text = rm.GetString("SubmitButton");
btnGetRates.CssClass = "inputfield";
btnGetRates.Click += new System.EventHandler(OnSubmitButton_Click);
btnConfirmation = new ConfirmButtonExtender();
btnConfirmation.ID = "rfBtnSubmit_Confirm";
btnConfirmation.ConfirmText = rm.GetString("BAUConfrimation");
btnConfirmation.TargetControlID = "btnGetStats";
this.Controls.Add(btnConfirmation);
this.Controls.Add(valValidationSummary);
this.Controls.Add(btnGetRates);
}
Dumb mistake, I was not rendering the control.

UserControl's RenderControl is asking for a form tag in (C# .NET)

I asked how to render a UserControl's HTML and got the code working for a dynamically generated UserControl.
Now I'm trying to use LoadControl to load a previously generated Control and spit out its HTML, but it's giving me this:
Control of type 'TextBox' must be placed inside a form tag with runat=server.
I'm not actually adding the control to the page, I'm simply trying to grab its HTML. Any ideas?
Here's some code I'm playing with:
TextWriter myTextWriter = new StringWriter();
HtmlTextWriter myWriter = new HtmlTextWriter(myTextWriter);
UserControl myControl = (UserControl)LoadControl("newUserControl.ascx");
myControl.RenderControl(myWriter);
return myTextWriter.ToString();
Alternatively you could disable the ServerForm/Event-validation on the page that is rendering the control to a string.
The following example illustrates how to do this.
public partial class _Default : System.Web.UI.Page
{
protected void Page_Load(object sender, EventArgs e)
{
string rawHtml = RenderUserControlToString();
}
private string RenderUserControlToString()
{
UserControl myControl = (UserControl)LoadControl("WebUserControl1.ascx");
using (TextWriter myTextWriter = new StringWriter())
using (HtmlTextWriter myWriter = new HtmlTextWriter(myTextWriter))
{
myControl.RenderControl(myWriter);
return myTextWriter.ToString();
}
}
public override void VerifyRenderingInServerForm(Control control)
{ /* Do nothing */ }
public override bool EnableEventValidation
{
get { return false; }
set { /* Do nothing */}
}
}
This is a dirty solution I used for the moment (get it working then get it right, right?).
I had already created a new class that inherits the UserControl class and from which all other "UserControls" I created were derived. I called it formPartial (nod to Rails), and this is going inside the public string renderMyHTML() method:
TextWriter myTextWriter = new StringWriter();
HtmlTextWriter myWriter = new HtmlTextWriter(myTextWriter);
UserControl myDuplicate = new UserControl();
TextBox blankTextBox;
foreach (Control tmpControl in this.Controls)
{
switch (tmpControl.GetType().ToString())
{
case "System.Web.UI.LiteralControl":
blankLiteral = new LiteralControl();
blankLiteral.Text = ((LiteralControl)tmpControl).Text;
myDuplicate.Controls.Add(blankLiteral);
break;
case "System.Web.UI.WebControls.TextBox":
blankTextBox = new TextBox();
blankTextBox.ID = ((TextBox)tmpControl).ID;
blankTextBox.Text = ((TextBox)tmpControl).Text;
myDuplicate.Controls.Add(blankTextBox);
break;
// ...other types of controls (ddls, checkboxes, etc.)
}
}
myDuplicate.RenderControl(myWriter);
return myTextWriter.ToString();
Drawbacks off the top of my head:
You need a case statement with every
possible control (or controls you
expect).
You need to transfer all
the important attributes from the
existing control (textbox, etc) to
the new blank control.
Doesn't take full advantage of
Controls' RenderControl method.
It'd be easy to mess up 1 or 2. Hopefully, though, this helps someone else come up with a more elegant solution.
You can add the control into page, render html and then remove the control from page.
Or try this:
Page tmpPage = new TempPage(); // temporary page
Control tmpCtl = tmpPage.LoadControl( "~/UDynamicLogin.ascx" );
//the Form is null that's throws an exception
tmpPage.Form.Controls.Add( tmpCtl );
StringBuilder html = new StringBuilder();
using ( System.IO.StringWriter swr = new System.IO.StringWriter( html ) ) {
using ( HtmlTextWriter writer = new HtmlTextWriter( swr ) ) {
tmpPage.RenderControl( writer );
}
}
You can either add a form to your user control, or use a regular html input box
<input type="text" />
Edit: If you are trying to do something AJAXy, maybe you want something like this
http://aspadvice.com/blogs/ssmith/archive/2007/10/19/Render-User-Control-as-String-Template.aspx
public static string RenderView<D>(string path, D dataToBind)
{
Page pageHolder = new Page();
UserControl viewControl = (UserControl) pageHolder.LoadControl(path);
if(viewControl is IRenderable<D>)
{
if (dataToBind != null)
{
((IRenderable<D>) viewControl).PopulateData(dataToBind);
}
}
pageHolder.Controls.Add(viewControl);
StringWriter output = new StringWriter();
HttpContext.Current.Server.Execute(pageHolder, output, false);
return output.ToString();
}
You can remove the data binding part if not needed.
I was having the same problem using similar code to #TcKs and haven't been able to make any of these examples work for me. I got it working by using the LoadControl method of a UserControl as such:
UserControl uc = new UserControl();
Control c = uc.LoadControl("newUserControl.ascx");
c.RenderControl(myWriter);

Categories