ASP .NET Dynamically Create User Controls - asp.net

I am working on a web application (IIS) targeting .NET 4.0 using Visual Studio 2015. I need to have a page with multiple user controls but the number of controls will not be known until runtime.
There will always be at least six controls. They should appear on screen like tiles in two rows of three - each tile approximately 30% of the screen width and 45% of the screen height.
That's not a problem. The issue is when there are more than 6 tiles due to user settings. The number of tiles needed will be retrieved from the database (SQL). Additional tiles should be added in a new row in the same layout as the original six but the screen should not expand - there should be a scrollbar to scroll down and see the next row of tiles.
I have a main page with the six initial controls, a placeholder, and a generic user control to put in that placeholder. I don't know how to get the placeholder to keep the same layout. Or even if this is the best way to accomplish the task.
Main .ASPX:
<%# Page Language="vb" AutoEventWireup="false" Inherits="Reporting" CodeBehind="Reporting.aspx.vb"%>
<%# Register TagPrefix="uc1" TagName="ReportingTile" Src="ReportingTile.ascx" %>
<!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/xhtml">
<head runat="server">
<title></title>
</head>
<body style="overflow:hidden; width:100%; height:100%">
<form id="form1" runat="server">
<asp:Panel ID="pnlTile1" runat="server" BackColor="White" style="position:absolute; width:31%; height:44%; left:1%; top:2%; font-family: Arial; font-size: 12px;">
<uc1:ReportingTile id="ReportingTile1" runat="server"></uc1:ReportingTile>
</asp:Panel>
<asp:Panel ID="pnlTile2" runat="server" BackColor="White" style="position:absolute; width:31%; height:44%; left:34%; top:2%; font-family: Arial; font-size: 12px;">
<uc1:ReportingTile id="ReportingTile2" runat="server"></uc1:ReportingTile>
</asp:Panel>
<asp:Panel ID="pnlTile3" runat="server" BackColor="White" style="position:absolute; width:31%; height:44%; left:67%; top:2%; right:2%; font-family: Arial; font-size: 12px;">
<uc1:ReportingTile id="ReportingTile3" runat="server"></uc1:ReportingTile>
</asp:Panel>
<asp:Panel ID="pnlTile4" runat="server" BackColor="White" style="position:absolute; width:31%; height:44%; left:1%; top:49%; font-family: Arial; font-size: 12px;">
<uc1:ReportingTile id="ReportingTile4" runat="server"></uc1:ReportingTile>
</asp:Panel>
<asp:Panel ID="pnlTile5" runat="server" BackColor="White" style="position:absolute; width:31%; height:44%; left:34%; top:49%; font-family: Arial; font-size: 12px;">
<uc1:ReportingTile id="ReportingTile5" runat="server"></uc1:ReportingTile>
</asp:Panel>
<asp:Panel ID="pnlTile6" runat="server" BackColor="White" style="position:absolute; width:31%; height:44%; left:67%; top:49%; right:2%; font-family: Arial; font-size: 12px;">
<uc1:ReportingTile id="ReportingTile6" runat="server"></uc1:ReportingTile>
</asp:Panel>
<div style="height:44%;width:31%;background-color:whitesmoke;">
<asp:PlaceHolder ID="placeHolder1" runat="server"></asp:PlaceHolder>
</div>
<div runat="server" style="position:absolute;bottom:0px;left:0px;right:0px;margin:0;height:40px;">
<asp:Table runat="server" Height="100%" Width="100%" BackColor="White" HorizontalAlign="Center">
<asp:TableRow HorizontalAlign="Center" VerticalAlign="Bottom" Width="100%">
<asp:TableCell HorizontalAlign="Center" VerticalAlign="Bottom" style="background-color:white;">
<asp:ImageButton ID="btnCloseWindow" runat="server" CausesValidation="False" ImageUrl="../images/btn-CloseWindow.png" />
</asp:TableCell>
</asp:TableRow>
</asp:Table>
</div>
</form>
</body>
</html>
.ASPX.vb (I've hardcoded 3 additional controls just for testing):
Imports System.Linq
Partial Public Class Reporting
Inherits System.Web.UI.Page
Private Property NumberOfControls As Integer
Get
Return CInt(ViewState("NumControls"))
End Get
Set(ByVal Value As Integer)
ViewState("NumControls") = Value
End Set
End Property
Protected Overrides Sub Page_Load(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.Load
Dim myControl As ReportingTile = CType(Page.LoadControl("~/ReportingTile.ascx"), ReportingTile)
Me.NumberOfControls = 3
Me.createControls()
End Sub
Private Sub createControls()
Dim count As Integer = Me.NumberOfControls
For i As Integer = 2 To count - 1
Dim myControl As ReportingTile = CType(Page.LoadControl("~/ReportingTile.ascx"), ReportingTile)
Dim ph As PlaceHolder = New PlaceHolder()
ph.ID = "ControlID_" & i.ToString()
ph.Controls.Add(myControl)
Dim lt As Literal = New Literal()
lt.Text = "<br />"
Page.Form.Controls.Add(ph)
Page.Form.Controls.Add(lt)
Next
End Sub
End Class
End Namespace
Generic User Control:
<%# Control Language="vb" AutoEventWireup="false" CodeBehind="ReportingTile.ascx.vb" Inherits="ReportingTile" %>
<asp:Table ID="tblHPSettingsOptions" runat="server">
<asp:TableRow>
<asp:TableCell>
<asp:Label runat="server" Font-Bold="true">Reporting Tile</asp:Label>
</asp:TableCell>
</asp:TableRow>
</asp:Table>

It is much better to use Bootstrap Grid System, Masonry, Flexbox or some other front end plugin insead of messing around yourself with styles in the controls itself. This is bound to cause problems (as you have noticted)
https://getbootstrap.com/
https://css-tricks.com/snippets/css/a-guide-to-flexbox/
https://masonry.desandro.com/

Related

Change label text based on file upload control inside repeater

I have file upload and label control in a repeater. The problem is whenever a file is uploaded, I want to assign name of the uploaded file to a label inside repeater.
<asp:Repeater ID="Repeater1" runat="server" ClientIDMode="AutoID">
<HeaderTemplate>
</HeaderTemplate>
<ItemTemplate>
<asp:Label ID="Label1" runat="server" Text=""><img src="../images/upload.png" alt="" style="position:absolute;cursor:pointer;"/></asp:Label>
<asp:FileUpload ID="PhotoUpload" runat="server" CssClass="uplodfile" Style="padding: 0px; position: relative; left: 0px; top: 0px; width: 20px;" />
<asp:Label ID="lblFilePath" Text="" runat="server" Style="vertical-align: inherit; padding: 0px 5px;"></asp:Label>
</ItemTemplate>
</asp:Repeater>
Can anybody assist me how to achieve this?
You can use FindControl.
protected void PhotoUpload_Click(object sender, EventArgs e)
{
Label lbl = Repeater1.Items[0].FindControl("Label1") as Label;
lbl.Text = "Label found!";
}

Ajax modalpopupextender not popping up

.modalBackground
{
background-color: Gray;
filter: alpha(opacity=70);
opacity: 0.7;
}
.modalPopup
{
background-color: #ddffdd;
border-width: 3px;
border-style: solid;
border-color: Gray;
margin-top: 60px;
padding: 2px;
width: 400px;
font-size: 10pt;
}
<cc1:ModalPopupExtender ID="ModalPopupExtender1" runat="server" CancelControlID="Button3"
OkControlID="btnOk" TargetControlID="LinkButtonDummy" PopupControlID="PanelPopUp"
BackgroundCssClass="modalBackground" />
<asp:Panel ID="PanelPopUp" runat="server" CssClass="modalPopup" Style="display: none">
<div>
<asp:Label ID="lblMsg" runat="server" />
<asp:Button ID="Button2" runat="server" Text="Add New Organisation" OnClick="Button2_Click" />
<asp:Button ID="Button3" runat="server" Text="Cancel" />
</div>
</asp:Panel>
I have also included the AJAX reference and a ScriptManager on the master page.
I have to add an enhancement to an existing page and I'm quite new with ASP.NET, the page in question is a 'content page' and is linked to a master page (containing the scriptmanager).
This code all looks completely fine and I have been reading on this for over three hours now but to no avail - my modal doesn't 'pop-up' and grey the background out, it simply appears where I have placed it on the page (right at the top, or right at the bottom e.t.c.) as if I was just showing/hiding a div.
Can anyone help, I'm going crazy?
What other routes can I go down for adding a confirmation box on a page that takes a string built in the code-behind and also runs code-behind functions on OK/Cancel?
Keep your css as it it and try this code :
<asp:HiddenField ID="HiddenField1" runat="server" />
<asp:ModalPopupExtender ID="MyPopup" runat="server" CancelControlID="Button3" OkControlID="btnOk" PopupControlID="PanelPopUp" BackgroundCssClass="modalBackground" DynamicServicePath="" Enabled="True"
TargetControlID="HiddenField1"></asp:ModalPopupExtender>
and on Button2_Click event add
MyPopup.Show();

Setting Checkbox ItemStyle ForeColor on ASP.Net DetailsView and GridView

On an ASP.Net DetailsView and also on a GridView I noticed that the tick mark in CheckBoxes are a light gray (disabled) colour even though I set it as blue.
<asp:CheckBoxField DataField="DayOfWeekMonday" HeaderText="Monday:" SortExpression="DayOfWeekMonday">
<ItemStyle ForeColor="Blue" />
</asp:CheckBoxField>
The same thing happens when the CheckBox is a TemplateField.
<asp:TemplateField HeaderText="Monday:" SortExpression="DayOfWeekMonday">
<EditItemTemplate>
<asp:CheckBox ID="CheckBoxEditDayOfWeekMonday" runat="server" Checked='<%# Bind("DayOfWeekMonday") %>' />
</EditItemTemplate>
<InsertItemTemplate>
<asp:CheckBox ID="CheckBoxInsertDayOfWeekMonday" runat="server" Checked='<%# Bind("DayOfWeekMonday") %>' />
</InsertItemTemplate>
<ItemTemplate>
<asp:CheckBox ID="CheckBoxItemDayOfWeekMonday" runat="server" Checked='<%# Bind("DayOfWeekMonday") %>' Enabled="false" />
</ItemTemplate>
<ItemStyle ForeColor="Blue" />
</asp:TemplateField>
I also tried this in the code-behind file.
Protected Sub CheckBoxItemDayOfWeekMonday_DataBinding(sender As Object, e As EventArgs)
Dim theControl As CheckBox
theControl = DetailsView.FindControl("CheckBoxItemDayOfWeekMonday")
theControl.ForeColor = Drawing.Color.Blue
End Sub
Is there a way to change it to blue like the rest of our fields and columns?
I noticed you meant the tick mark INSIDE the checkboxes, not the forecolor. I don't think you can change this as this is very OS dependant. I have implemented this with images in the past. You can try these CSS3 CheckBoxes which uses images: http://webdesign.tutsplus.com/tutorials/htmlcss-tutorials/quick-tip-easy-css3-checkboxes-and-radio-buttons/
Sample:
HTML:
<span><input type="checkbox" id="c1" name="cc" />
<label for="c1"><span></span>Check Box 1</label>
</span>
CSS:
input[type="checkbox"] {
display:none;
}
input[type="checkbox"] + label {
color:#000000;
font-family:Arial, sans-serif;
font-size:14px;
}
input[type="checkbox"] + label span {
display:inline-block;
width:19px;
height:19px;
margin:-1px 4px 0 0;
vertical-align:middle;
background:url(http://webdesigntutsplus.s3.amazonaws.com/tuts/391_checkboxes/check_radio_sheet.png) left top no-repeat;
cursor:pointer;
}
input[type="checkbox"]:checked + label span {
background:url(http://webdesigntutsplus.s3.amazonaws.com/tuts/391_checkboxes/check_radio_sheet.png) -19px top no-repeat;
}
JSFiddle: http://jsfiddle.net/4FraV/2/

ASP:Object reference not set to an instance of an object

i am trying to pass a value to a label from a data source, but it keeps on giving me this error.
form1.aspx:
<asp:FormView ID="ProductsView" DataSourceID="ProductDataSource" DataKeyNames="Parking_ID"
runat="server" >
<ItemTemplate>
<div style="width: 200px; height: 200px; border: solid 10px white; background-position: center;
background-repeat: no-repeat; background-image: url('<%# Eval("Parking_ID", "images/{0}.bmp") %>');">
</div>
<asp:HiddenField Value='<%# Eval("Parking_Cost") %>' ID="hiddenPrice" runat="server" />
<asp:HiddenField Value='<%# Eval("Parking_Name") %>' ID="hiddenName" runat="server" />
<asp:HiddenField Value='<%# Eval("Parking_ID") %>' ID="HiddenField1" runat="server" />
</ItemTemplate>
</asp:FormView>
<asp:Label ID="lblName" runat="server" Text="TEST" CssClass="title" Style="font-size: 17px;
display: block;"></asp:Label>
<asp:Label ID="lblPrice" runat="server" Text="TEST" CssClass="title" Style="color: Red;
font-size: 12px;"></asp:Label>
<asp:Label ID="lbl_ID" runat="server" Text="" CssClass="title" Style="color: Red;
font-size: 12px;"></asp:Label>
<asp:SqlDataSource ID="ProductDataSource" runat="server" ConnectionString="<%$ ConnectionStrings:mydatabaseConnectionString2 %>"
ProviderName="System.Data.SqlClient" SelectCommand="SELECT * FROM [Parking] WHERE ([Parking_ID] = #Parking_ID)">
<SelectParameters>
<asp:Parameter Name="Parking_ID" Type="Int32" />
</SelectParameters>
</asp:SqlDataSource>
form1.aspx.vb:
lblName.Text = DirectCast(Me.ProductsView.FindControl("hiddenName"), HiddenField).Value
I am using vb.net script
Any ideas ?
Regards.
The Controls are usually in the data row of the FormView.
Try
lblName.Text = DirectCast(Me.ProductsView.Row.FindControl("hiddenName"), HiddenField).Value
But in general, when you use Control.FindControl(), there is a chance it will return Nothing if it cannot find it. So the best thing to do is do a TryCast instead of DirectCast and check to see if it's Nothing.
I guess the error source is the following statement:
Me.ProductsView.FindControl("hiddenName")
And the reason is that you dont have a Control with the ID of "hiddenName" directly in the ProductsView control.
You may need to use a recursive function to get the control ..
Is this code in the bind event?
lblName.Text = DirectCast(Me.ProductsView.FindControl("hiddenName"), HiddenField).Value
If so, it might be that you have to check which template it is running:
if (e.Item.ItemType == ItemType || e.Item.ItemType == AlternateItemType)
(I'm not sure of the types for FormView, but in a GridView it would be like this.
The control hiddenName doesn't existing on other templates.
Also you have to find the control from e.Item which is the current template.

How to get the id of Updatepanel which initiated a postback

Hi I need to intercept server callback after udate panel async post back and determine which panel initiated the request. The code is pretty simple:
Sys.WebForms.PageRequestManager.getInstance().add_pageLoaded(InterceptUpdateCallback);
function InterceptUpdateCallback(sender, args)
{
var updatedPanels = args.get_panelsUpdated();
for (idx = 0; idx < updatedPanels.length; idx++) {
if (updatedPanels[idx].id == "myUpdatePanel") {
StartSmth();
break;
}
}
}
And it works when UpdatePanel is not inside another UpdatePanel. But when it is inside another UpdatePanel updatedPanels[idx].id has parent Updatepanel id. So how can I get the id of UpdatePanel which initiated the request (the inner UpdatePanel)? Thanx
Here you go:
function InterceptUpdateCallback(sender, args) {
if (sender._postBackSettings)
alert(sender._postBackSettings.panelID);
else
alert('first load');
}
Update:
<%# Page Language="C#" %>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<script runat="server">
protected void LinkButtons_Click(object sender, EventArgs e)
{
LabelMain.Text = LabelSub1.Text = LabelSub2.Text = LabelSub3.Text = string.Format("{0} Updated By {1}", DateTime.Now, ((Control)sender).ID);
}
</script>
<html xmlns="http://www.w3.org/1999/xhtml">
<head runat="server">
<style type="text/css">
body { font-family: Tahoma;}
fieldset { padding: 15px; }
fieldset a
{
float: right;
clear: none;
display: block;
margin: 10px;
}
fieldset span
{
display: block;
margin-top: 20px;
margin-bottom: 20px;
}
</style>
</head>
<body>
<form id="form1" runat="server">
<asp:ScriptManager ID="ScriptManager1" runat="server" />
<script type="text/javascript">
function pageLoaded(sender, args) {
if (sender._postBackSettings) {
var panelId = sender._postBackSettings.panelID.split('|')[0];
if (panelId == sender._scriptManagerID) {
var updatedPanels = args.get_panelsUpdated();
var affectedPanels = "Affected Panels:\n";
for(var x=0;x<updatedPanels.length;x++)
affectedPanels+= updatedPanels[x].id + "\n";
alert("Request initiated by ScriptManager\n\nMight be an async trigger, or child of an update panel with children as triggers set to false.\n\n"+affectedPanels);
}
else
alert("Request initiated by: " + panelId);
}
}
Sys.WebForms.PageRequestManager.getInstance().add_pageLoaded(pageLoaded);
</script>
<asp:LinkButton ID="UpdateMain" runat="server" Text="UpdateMain" OnClick="LinkButtons_Click"></asp:LinkButton>,
<asp:LinkButton ID="UpdateSub1" runat="server" Text="UpdateSub1" OnClick="LinkButtons_Click"></asp:LinkButton>,
<asp:LinkButton ID="UpdateSub2" runat="server" Text="UpdateSub2" OnClick="LinkButtons_Click"></asp:LinkButton>,
<asp:LinkButton ID="UpdateSub3" runat="server" Text="UpdateSub3" OnClick="LinkButtons_Click"></asp:LinkButton>
<br />
<br />
<asp:UpdatePanel ID="Main" runat="server" ChildrenAsTriggers="false" UpdateMode="Conditional">
<ContentTemplate>
<fieldset>
<asp:LinkButton ID="LinkButton1" runat="server" Text="LinkButton1" OnClick="LinkButtons_Click"></asp:LinkButton>
<legend>Main - Update Mode:Conditional, Children As Triggers:False</legend>
<asp:Label ID="LabelMain" runat="server" Text="LabelMain"></asp:Label>
<asp:UpdatePanel ID="Sub1" runat="server" UpdateMode="Always" ChildrenAsTriggers="true">
<ContentTemplate>
<fieldset>
<asp:LinkButton ID="LinkButton2" runat="server" Text="LinkButton2" OnClick="LinkButtons_Click"></asp:LinkButton>
<legend>Sub1 - Update Mode:Always, Children As Triggers:True</legend>
<asp:Label ID="LabelSub1" runat="server" Text="LabelSub1"></asp:Label>
<asp:UpdatePanel ID="Sub2" runat="server" UpdateMode="Always" ChildrenAsTriggers="true">
<ContentTemplate>
<fieldset>
<asp:LinkButton ID="LinkButton3" runat="server" Text="LinkButton3" OnClick="LinkButtons_Click"></asp:LinkButton>
<legend>Sub2 - Update Mode:Always, Children As Triggers:True</legend>
<asp:Label ID="LabelSub2" runat="server" Text="LabelSub2"></asp:Label>
</fieldset>
</ContentTemplate>
<Triggers>
<asp:AsyncPostBackTrigger ControlID="UpdateSub2" />
</Triggers>
</asp:UpdatePanel>
</fieldset>
</ContentTemplate>
<Triggers>
<asp:AsyncPostBackTrigger ControlID="UpdateSub1" />
</Triggers>
</asp:UpdatePanel>
<asp:UpdatePanel ID="Sub3" runat="server" ChildrenAsTriggers="false" UpdateMode="Conditional">
<ContentTemplate>
<fieldset>
<asp:LinkButton ID="LinkButton4" runat="server" Text="LinkButton4" OnClick="LinkButtons_Click"></asp:LinkButton>
<legend>Sub3 - Update Mode:Conditional, Children As Triggers:False</legend>
<asp:Label ID="LabelSub3" runat="server" Text="LabelSub3"></asp:Label>
</fieldset>
</ContentTemplate>
<Triggers>
<asp:AsyncPostBackTrigger ControlID="UpdateSub3" />
</Triggers>
</asp:UpdatePanel>
</fieldset>
</ContentTemplate>
<Triggers>
<asp:AsyncPostBackTrigger ControlID="UpdateMain" />
</Triggers>
</asp:UpdatePanel>
</form>
</body>
</html>
I will have a guess at this one.
Does setting UpdateMode = Conditional on the outer (or both) UpdatePanels help? I think the problem is that you only get the "outermost" updated panel and if you do not set UpdateMode to Conditional the outer Panel is updated as well (even if you click something in the inner panel; see second reference).
For reference see
Note that, if I remove the property
UpdateMode=Conditional for the
UpdatePanel1 (parent), both the labels
will get refreshed.
from ASP.NET 2.0 AJAX Extensions Update Panel - Nested Update Panel
and
When set to Always, the UpdatePanel is
updated on every postback raised from
anywhere in the page, so from controls
inside the panel, inside other panels
or just on the page.
from Remember to set UpdatePanel's UpdateMode to Conditional
Finally I came to solution: the problem was that I had trigger control (Button) for child UpdatePanel which actually was outside this Update panel and inside parent UpdatePanel (sorry I hadn't noticed that). If you put Button inside child UpdatePanel - everything works fine.

Resources