asp.net custom validator with radio buttons - asp.net

using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.UI;
using System.Web.UI.WebControls;
namespace WebApplication3
{
public partial class WebForm1 : System.Web.UI.Page
{
protected void Page_Load(object sender, EventArgs e)
{
if (IsPostBack)
CustomValidator1.Validate();
}
protected void CustomValidator1_ServerValidate(object source, ServerValidateEventArgs args)
{
if (RadioButton1.Checked == false && RadioButton2.Checked == false)
args.IsValid = false;
else
args.IsValid = true;
}
}
}
Here is the code I used to program my server side custom validator. I'm having trouble understanding how this works because if I take it out of the IsPostBack "if", it shows up in the summary when I start up the page but when I click a button it doesn't work. Anyone know what might be wrong?
Also as some side info, what is the major difference between server side and client side validation in terms of this type of validation ?

The biggest difference betwen server side and client side validation (besides the obvious) is that client-side validation can prevent you from even submitting a page. Server-side validation only happens once the page has been submitted.
Mixing them can produce the situation where you, the user, have filled in all your fields, made everything the right length and value, and hit submit - and then when the page returns, there are more validation messages!

Related

How can I bind dynamic xml file to asp tree view?

I am trying to bind information from a web service to a tree view in my asp.net website. Using a drop down list, I choose a stock symbol that retrieves that company's information from the web service. I am currently outputting that information as a string.
What I am trying to do is bind it to a tree view dynamically. This is where I'm at:
My aspx.cs file..
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.UI;
using System.Web.UI.WebControls;
using net.webservicex.www;
using System.Xml;
public partial class _Default : System.Web.UI.Page
{
private net.webservicex.www.StockQuote StockQuote;
private string StockInfo;
private XmlDocument stockDoc = new XmlDocument();
protected void Page_Load(object sender, EventArgs e)
{
}
protected void DropDownList1_SelectedIndexChanged(object sender, EventArgs e)
{
string symbol = DropDownList1.SelectedItem.Text;
StockQuote = new net.webservicex.www.StockQuote();
StockInfo = StockQuote.GetQuote(symbol);
stockDoc.LoadXml(StockInfo);
test.Text = StockInfo;
}
}
I cannot configure the data source in design view because it's dynamic, and I never used a hierarchical scheme. Do I need to do that? Is there another way?
Use an XmlDataSource and set it's DataFile property to the desired Xml file. Now go to your TreeView and set it's DataSourceID to the ID of XmlDataSource object.
Update
I just noticed that you are getting your Xml from a service. In that case use the Data property of XmlDataSource object to set the data xml.
Update
Declare your XmlDataSource in the aspx markup and set it as the DataSourceID of the TreeView (again in the markup). In the code behind (in an appropriate event), do something like below.
xmlDataSource.Data = StockInfo; // StockInfo is your string variable
treeView.DataBind(); // i am not sure whether this is necessary
Hope this helps.

I have a Dropdownlist that have event sets values to the dropdownlist how can I use it in another class file?

I have a dropdownlist in my aspx that have an event that sets values to it:
protected void Page_Load(object sender, EventArgs e)
{
DropDownList1.Items.Add("No Image News");
DropDownList1.Items.Add("Small News");
DropDownList1.Items.Add("Medium News");
DropDownList1.Items.Add("Large News");
DropDownList1.DataBind();
}
I have a class file that have a method and I would like to use the dropdownlist inside of the method.
example: If selected dropdownlist value is "Car" do that..
Is it possible to somehow use the dropdownlist from the aspx file inside a class file?
create a function which take DropDownList as an argument
Call that function from you .aspx.cs file.
It will work.
Function will be like this
public void MyControlData(DropDownList ddl)
{
}
Add reference of System.Web in you .cs file where you want to define this function.
Edit 1
using System;
using System.Data;
using System.Configuration;
using System.Web;
using System.Web.Security;
using System.Web.UI;
using System.Web.UI.WebControls;
using System.Web.UI.WebControls.WebParts;
using System.Web.UI.HtmlControls;
public class MyControlData
{
public void MyControlData(DropDownList ddl)
{
// DO SOMETHING HERE
}
}

ASP. A list and pictures

I put a list box and an image box.
now I want the image to swap every time the user clicks on a different element in the list. It doesnt seem to work
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.UI;
using System.Web.UI.WebControls;
public partial class _Default : System.Web.UI.Page
{
string[] pictures = { "~/createWii.jpg",
"~/DKC4_wii.png",
"~/Donkey-Kong-Country-1.jpg",
"~/DSCallOfDutyBlackOps.jpg",
"~/DSPreviewsCodmw2.jpg",
"~/DSPreviewsAliceInWonderLAnds.jpg",
"~/DSPreviewPicross3d.jpg",
"~/createii.jpg",
};
string[] picturesNames = { "picture1", "picture2", "picture3", "picture4", "picture5", "picture6", "picture7", "picture8" };
protected void Page_Load(object sender, EventArgs e)
{
for (int i = 0; i < pictures.Length; i++)
{
ListBox1.Items.Add(new ListItem(picturesNames[i],pictures[i]));
}
Image1.ImageUrl = "~/Donkey-Kong-Country-1.jpg";
ListBox1.DataSource = picturesNames;
ListBox1.DataBind();
}
protected void ListBox1_SelectedIndexChanged(object sender, EventArgs e)
{
Image1.ImageUrl = pictures[ListBox1.SelectedIndex];// it tells me that there is index out of range each time. why ?
}
}
A couple of things.
1.) you should wrap the code in page_load with
if(!IsPostback)
2.) Make sure on the .aspx that the "AutoPostback" property is set to true on the listbox!
Edit
Per the request in the comments, the reason this is needed is two fold.
ASP.NET ViewState will handle the persistence of the values on postback, therefore, you can use the !IsPostback condition to ensure that the information is only bound once. This prevents any "oddities" from coming up in the future.
By default ListBoxes/DropDownLists/etc do not post back automatically when the user changes a selection. So to actually trigger the event you either need to have a button that does the postback, or update the "AutoPostback" property as I directed to ensure that when the user makes a change that it triggers the server-side code.

Set Server Side OnClick() event Programmatically

I am looking for a way to programmatically set the OnClick event handler for a TableCell object. The ASP equivalent of what I'm trying to do will look like this:
<asp:TableCell OnClick="clickHandler" runat="server">Click Me!</asp:TableCell>
In the above example, "clickHandler" is a server-side function defined in the .cs CodeBehind.
public virtual void clickHandler(object sender, EventArgs args) {...}
However, for my situation, this TableCell object needs to be created dynamically, so setting it in an ASP tag is not an option. I am trying to do something like the following in the CodeBehind:
System.Web.UI.WebControls.TableRow row = new System.Web.UI.WebControls.TableRow();
System.Web.UI.WebControls.TableCell cell = new System.Web.UI.WebControls.TableCell();
cell.Text = "Click Me!";
cell.Attributes.Add("onClick", "clickHandler");
row.Cells.Add(cell);
Unfortunately, in this situation:
cell.Attributes.Add("onClick", "clickHandler");
the "clickHandler" only works as a client-side javascript function. What I'm looking for is a way to link the server-side clickHandler() function, defined in the .cs CodeBehind, to this table cell.
After an afternoon of searching, I have been unable to come up with a working solution. Thanks in advance for any help.
After a lot of work and research, I was able to cobble together a working solution, but it seems like an awful lot of work for something that should already be built-in. What I did was to extend the System.Web.UI.WebControls.TableCell object to include a handle for the OnClick event:
using System;
using System.Web;
using System.Web.UI;
using System.Web.UI.WebControls;
namespace MyWebApp
{
public class ExpandableTableCell : TableCell, IPostBackEventHandler, INamingContainer
{
private static readonly object click_event = new object();
public ExpandableTableCell()
{
}
// public handles for adding and removing functions to be called on the click event
public event EventHandler Click
{
add
{
Events.AddHandler(click_event, value);
}
remove
{
Events.RemoveHandler(click_event, value);
}
}
// define parent function that will be called when the container is clicked
protected void Click(EventArgs e)
{
EventHandler h = Events[click_event] as EventHandler;
if (h != null)
{
h(this, e);
}
}
// specify the "post back event reference" or id of the click event
protected override void AddAttributesToRender(HtmlTextWriter writer)
{
base.AddAttributesToRender(writer);
writer.AddAttribute(HtmlTextWriterAttribute.Onclick,
Page.ClientScript.GetPostBackEventReference(this, "custom_click"));
}
// link the custom click id to the click function
void System.Web.UI.IPostBackEventHandler.RaisePostBackEvent(string eventArgument)
{
if(eventArgument == "custom_click")
{
this.OnClick(EventArgs.Empty);
}
}
}
}
Here is how I use my new class (almost exactly like the stock TableCell):
System.Web.UI.WebControls.TableRow row = new System.Web.UI.WebControls.TableRow();
ExpandableTableCell click_cell = new ExpandableTableCell();
click_cell.Text = "Click Me!";
click_cell.Click += clickHandler;
// extra little touch for mouseover event
click_cell.Attributes.Add("onmouseover", "this.style.cursor='pointer'");
row.Cells.Add(click_cell);
As I have said, it seems like going through the trouble of extending the class to set the OnClick method in the codebehind is excessive. If anyone has any other ideas or any ways to clean up or legitimize the code above, please let me know.
I don't know if this is relevant to your problem, but I was trying to add a server-side function to a LinkButton and found the following (VB) code: AddHandler cell.Click, AddressOf clickHandler, which worked for me.
According to this code conversion service, this translates to cell.Click += clickHandler; in C#.
Hope this helps!

Custom ASP.NET Container Control

I've been trying to create a custom control that works exactly like the Panel control except surrounded by a few divs and such to create a rounded box look. I haven't been able to find a decent example of how to do this.
I need to be able to place text and controls inside the control and access it directly without referencing the panel (exactly the way the Panel control works).
Does anyone have any examples of this?
There are two ways to do this. One is to implement INamingContainer on your control, and it takes a lot of effort.
The other way is to inherit from Panel, and override the RenderBeginTag and RenderEndTag methods to add your custom markup. This is easy.
public class RoundedCornersPanel : System.Web.UI.WebControls.Panel
{
public override RenderBeginTag (HtmlTextWriter writer)
{
writer.Write("Your rounded corner opening markup");
base.RenderBeginTag(writer);
}
public override RenderEndTag (HtmlTextWriter writer)
{
base.RenderEndTag(writer);
writer.Write("Your rounded corner closing markup");
}
}
There are already quite a few answers here, but I just wanted to paste the most basic implementation of this without inheriting from Panel class. So here it goes:
using System.ComponentModel;
using System.Web.UI;
using System.Web.UI.WebControls;
[ToolboxData("<{0}:SimpleContainer runat=server></{0}:SimpleContainer>")]
[ParseChildren(true, "Content")]
public class SimpleContainer : WebControl, INamingContainer
{
[PersistenceMode(PersistenceMode.InnerProperty)]
[TemplateContainer(typeof(SimpleContainer))]
[TemplateInstance(TemplateInstance.Single)]
public virtual ITemplate Content { get; set; }
public override void RenderBeginTag(HtmlTextWriter writer)
{
// Do not render anything.
}
public override void RenderEndTag(HtmlTextWriter writer)
{
// Do not render anything.
}
protected override void RenderContents(HtmlTextWriter output)
{
output.Write("<div class='container'>");
this.RenderChildren(output);
output.Write("</div>");
}
protected override void OnInit(System.EventArgs e)
{
base.OnInit(e);
// Initialize all child controls.
this.CreateChildControls();
this.ChildControlsCreated = true;
}
protected override void CreateChildControls()
{
// Remove any controls
this.Controls.Clear();
// Add all content to a container.
var container = new Control();
this.Content.InstantiateIn(container);
// Add container to the control collection.
this.Controls.Add(container);
}
}
Then you can use it like this:
<MyControls:SimpleContainer
ID="container1"
runat="server">
<Content>
<asp:TextBox
ID="txtName"
runat="server" />
<asp:Button
ID="btnSubmit"
runat="server"
Text="Submit" />
</Content>
</MyControls:SimpleContainer>
And from codebehind you can do things like this:
this.btnSubmit.Text = "Click me!";
this.txtName.Text = "Jack Sparrow";
Create a class that inherits System.Web.UI.Control, and overrride the Render ( HtmlTextWriter ) method.
In this method, render surrounding start tags, then render the children(RenderChildren), then render end tags.
protected override void Render ( HtmlTextWriter output )
{
output.Write ( "<div>" );
RenderChildren ( output );
output.Write ( "</div>" );
}
Rounded corners is typically achieved using CSS and corner images for the top left, top right, bottom left and bottom right corners.
It could be done using 4 nested divs, acting as layers, each of them having one corner image as their background image.
Code project have something that might interest you : Panel Curve Container - An ASP.NET Custom Control Nugget. I am sure you can play with the code and have the behavior and look you want.
If you don't want to inherit directly from WebControl instead of from Panel, the easiest way to do this is to decorate the class with the attribute [ParseChildren(false)]. Although at first glance this might suggest that you don't want to parse children, what the false actually indicates is that you don't want the children to be treated as properties. Instead, you want them to be treated as controls.
By using this attribute, you get virtually all of the functionality out of the box:
[ToolboxData("<{0}:RoundedBox runat=server></{0}:RoundedBox>")]
[ParseChildren(false)]
public class RoundedBox : WebControl, INamingContainer
{
public override void RenderBeginTag(HtmlTextWriter writer)
{
writer.Write("<div class='roundedbox'>");
}
public override void RenderEndTag(HtmlTextWriter writer)
{
writer.Write("</div>");
}
}
This will allow you to add RoundedBox controls to your pages, and add children (either asp.net controls or raw html) that will be rendered inside your div.
Of course, css would be added to correctly style the roundedbox class.
Just another thing you can use, there's a rounded corner extender in the ASP.Net ajax toolkit.
I know it's not exactly what you asked for, but you don't have to write any custom code.
Hope that helps!
I looked at this question because I wanted to produce a 2 column layout panel. (not quite but its a much simpler example of what I needed. I'm sharing the solution that I wound up using:
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Web;
using System.Web.UI;
using System.Web.UI.WebControls;
namespace Syn.Test
{
[DefaultProperty("Text")]
[ToolboxData("<{0}:MultiPanel runat=server></{0}:MultiPanel>")]
[ParseChildren(true)]
[PersistChildren(false)]
public class MultiPanel : WebControl, INamingContainer
{
public ContentContainer LeftContent { get; set; }
public ContentContainer RightContent { get; set; }
protected override void CreateChildControls()
{
base.CreateChildControls();
}
protected override void Render(HtmlTextWriter output)
{
output.AddStyleAttribute("width", "600px");
output.RenderBeginTag(HtmlTextWriterTag.Div);
output.AddStyleAttribute("float", "left");
output.AddStyleAttribute("width", "280px");
output.AddStyleAttribute("padding", "10px");
output.RenderBeginTag(HtmlTextWriterTag.Div);
LeftContent.RenderControl(output);
output.RenderEndTag();
output.AddStyleAttribute("float", "left");
output.AddStyleAttribute("width", "280px");
output.AddStyleAttribute("padding", "10px");
output.RenderBeginTag(HtmlTextWriterTag.Div);
RightContent.RenderControl(output);
output.RenderEndTag();
output.RenderEndTag();
}
}
[ParseChildren(false)]
public class ContentContainer : Control, INamingContainer
{
}
}
The issue I still have is the intellisense does't work for in this scenario, it won't suggest the Left and Right Content tags.
public class myCustomPanel : Panel
{
public override void RenderBeginTag(HtmlTextWriter writer)
{
writer.AddAttribute(HtmlTextWriterAttribute.Class, "top_left_corner");
writer.RenderBeginTag(HtmlTextWriterTag.Div);
base.RenderBeginTag(writer);
}
public override void RenderEndTag(HtmlTextWriter writer)
{
base.RenderEndTag(writer);
writer.RenderEndTag();
}
}

Resources