Access ASPX elements inside classes - c#

I have a bunch of methods which manipulate the ASPX page elements and at this point it makes sense to encapsulate them into their own static object. However, it seems like I do not have access into the form elements outside of the ASPX page. Any ideas on how to go about this?

You need to pass the Page itself into the class, see the example below:
ASPX page
<form id="form1" runat="server">
<div>
<asp:TextBox ID="txtTest" runat="server" Text="Test" />
</div>
</form>
Code-Behind
protected void Page_Load(object sender, EventArgs e)
{
Process p = new Process(this);
string s = p.GetTextBoxValue();
}
Class
public class Process
{
public Page thePage { get; set; }
public Process(Page page)
{
thePage = page;
}
public string GetTextBoxValue()
{
TextBox tb = (TextBox)thePage.FindControl("txtTest");
return tb.Text;
}
}
Process is probably not the best name for the class, but this is purely a demo.
Also, passing the Page object into another class tight couples that class to the Page object. I would recommend reconsidering your design of the class you're trying to make to not rely on the Page object entirely.

If you really want to encapsulate functionality, I guess you best create a class in which you pass the relevant elements to the constructor.
If you are aiming on reuse in other pages, you could create a base page from which you inherit. Another option is to do stuff in a master page that you refer from your pages.
I think a more detailed question is required to give a more detailed answer.

You need to pass Page object as one of the parameters to your class methods, this way its elements will be accessible inside the class.
For example if you have a class like:
public class CMyDataClass {
public bool CompareText(System.Web.UI.Page i_oPage) {
TextBox oTextBox = i_oPage.FindControl("TextBox1");
return (oTextBox.Text == "My Data");
}
}
You can use it like this from the page:
CMyDataClass oMyDataClass = new CMyDataClass();
if (oMyDataClass.CompareText(this)) {
Response.Write("Ok!");
}

Related

How to access MasterPage1 method in another ContentPage with MasterPage2 in asp.net?

I have Page1.aspx which has MasterPage1.master as its MasterPage and Page2.aspx which has MasterPage2.master as its MasterPage. I am showing Page2.aspx page in iframe (which is in Page1.aspx) Page2.aspx displays some items in ListView. After adding item to Cart(MyCartUserControl in MasterPage1.master) i want to call the Method say 'MyMethod()' which is in MasterPage1.master. in Page2.aspx
In Page2.aspx:
<%# MasterType VirtualPath="~/Sales/MasterPage1.master" %>
In Page2.aspx.cs
protected void UpdateShoppingCart()
{
Sales_MasterPage1 master = (Sales_MasterPage1)this.Master;
master.BindCart();
}
I know the above code will not work using 'this'. What is replaceable to 'this' keyword?
Help Appreciated!
Try below Code :
protected void UpdateShoppingCart()
{
Sales_MasterPage1 master = new Sales_MasterPage1();
master.BindCart();
}
Problem is the access modifier.
You might need to make it a public method because protected wont let you access it outside of that master class
public static void UpdateShoppingCart()
{
Sales_MasterPage1 master = new Sales_MasterPage1();
master.BindCart();
}
to call it from anywhere you can do:
Sales_MasterPage1.UpdateShoppingCart()

How can I access my ViewModel from the View and associated code behind file?

I am a real beginner at ASP.NET and working with MVC2 + EF4 in Visual Studio 2010.
I am trying to use the MVVM pattern and strongly typing my View to a ViewModel.
<%# Page Title="" Language="C#" MasterPageFile="~/Views/Shared/Site.Master" AutoEventWireup="True" CodeBehind="~/Views/Options/Index.aspx.cs" Inherits="System.Web.Mvc.ViewPage<OptionsViewModel>" %>
My OptionsViewModel looks like this:
public class OptionsViewModel
{
public List<DeskPreference> DeskPreferences { get; set; }
public List<DayPreference> DayPreferences { get; set; }
}
In the controller I create a new OptionsViewModel and do return View(myOptionsViewModel);
Then, for example, I want to check/uncheck some boxes based on what is in DayPreference. I don't get how to access the model from my code behind file, which looks like this:
using System.Web.Mvc;
using DeskRota_v1.ViewModels;
public class OptionsPage : System.Web.Mvc.ViewPage<OptionsViewModel>
{
protected void Page_Load(object sender, EventArgs e)
{
setCheckBoxes();
}
private void setCheckBoxes()
{
foreach (DayPreference dayPreference in Model.DayPreferences)
{
\\ check boxes here
}
}
It comes up with "The name 'Model' does not exist in the current context". Also if I try to do <% Model. %> in the view there is no intellisense, which I thought there should be. Could somebody please explain what I am doing wrong? How am I supposed to access the ViewModel and its properties?
Your controller will have two overloads of each action method for each view that you need to post back: one with an HttpGet signature and one with an HttpPost signature. The GET version will be called on the first load of the page and will set the initial page values.
The POST version will be called on form submit and accept your viewmodel as an arg. MVC will automagically reconstruct it with the values that were posted in your form (assuming you're using relatively simple types. More complex types is doable but more complicated).
My own convention is to have a work unit in the ViewModel that is responsible for persisting or otherwise processing the values that were submitted. Do NOT put this sort of thing in the controller.
Your viewmodel will need a parameterless constructor, which is the version MVC will use when reconstituting it on page submit. In general I also have a second constructor I use on the GET version so that the VM can instantiate it's initial values.
[HttpGet]
public ActionResult Index(int somethingICareAbout)
{
return View(new IndexViewModel(somethingICareAbout));
}
[HttpPost]
public ActionResult Index(IndexViewModel viewModel)
{
viewModel.SaveChanges()/DoWork()/Whatever();
return View(new viewModel());
}

Accessing public methods from a user control

I have a user control with this simple public method:
public void appendHtml(string html)
{
txtTinyMce.InnerText += html;
}
In the page where this control is contained, I have specified it in the page's markup like so:
<QuickBuck:TinyMCE runat="server" ID="tinyMCE" />
When I call tinyMCE.appendHtml, it doesn't find it. What am I doing wrong?

Dynamic user control controls are null on load

I have a base usercontrol in my ASP.Net app, There are HTML markup within this usercontrol that are set to runat="server" and id's. The problem I am having is when the usercontrol is loaded, the HTML markup is being returned as null
ASP.Net C# code:
public partial class webonlinecustombase : System.Web.UI.UserControl
{
public Event Event { get; set; }
public OnlineSystemPageCustom custompage { get; set; }
public OnlineSystemPageCustom.OnlineSystemPageHdr.OnlineSystemPageModule custommodule { get; set; }
public void Page_Load(object sender, EventArgs e)
{
string typeName = custommodule.ModuleInternetFile;
inpagelink.HRef = "#" + custommodule.ModuleName.Replace(" ", "").Replace("/", "");
modtitle.InnerText = custommodule.ModuleName;
Type child = Type.GetType(typeName);
UserControl ctl = Activator.CreateInstance(child) as UserControl;
if (ctl != null)
{
this.modsection.Controls.Add(ctl);
}
}
}
Here is the HTML Markup:
<%# Control Language="C#" AutoEventWireup="true" CodeBehind="webonlinecustombase.ascx.cs" Inherits="IPAMIntranet.IPAM_Controls.webtemplatecontrols.webonlinecustombase" %>
<a id="inpagelink" runat="server"></a>
<span id="modtitle" runat="server" style="width:100%;text-align:left">Scientific Overview</span>
<div id="modsection" runat="server" style="width:100%;">
</div>
<p>Back to Top</p>
Why is the inpagelink and modtitle being returned as null?
I have seen this happen in web applications (not web sites) when changes are made to the source (especially setting runat=server on items that were not previously runat=server), but you don't switch to the designer view.
The way that I resolve this issue is to switch to design view and dirty a property in one of the fields. This usually causes VS to update the designer code-behind file.
You can double-check this file to ensure the controls have been added. If you check it prior to doing this, you should see that they are missing.
asp.net does'n have span class, so you cant do anything in code behind with it.
use LinkButton or HyperLink instead of
the other solution is to create span or a in code, something like this
var span = new HtmlGenericControl("span");
span.InnerHtml = "From<br/>Date";
span.Attributes["class"] = "blue";
placeholder.Controls.Add(span);
hope I helped :))

Using ASP.NET MVC, how to best avoid writing both the Add View and Edit View?

The Add view and the Edit view are often incredibly similar that it is unwarranted to write 2 views. As the app evolves you would be making the same changes to both.
However, there are usually subtle differences. For instance, a field might be read-only once it's been added, and if that field is a DropDownList you no longer need that List in the ViewData.
So, should I create a view data class which contains all the information for both views, where, depending on the operation you're performing, certain properties will be null?
Should I include the operation in the view data as an enum?
Should I surround all the subtle differences with <% if( ViewData.Model.Op == Ops.Editing ) { %> ?
Or is there a better way?
It's pretty easy really. Let's assume you're editing a blog post.
Here's your 2 actions for new/edit:
public class BlogController : Controller
{
public ActionResult New()
{
var post = new Post();
return View("Edit", post);
}
public ActionResult Edit(int id)
{
var post = _repository.Get(id);
return View(post);
}
....
}
And here's the view:
<% using(Html.Form("save")) { %>
<%= Html.Hidden("Id") %>
<label for="Title">Title</label>
<%= Html.TextBox("Title") %>
<label for="Body">Body</label>
<%= Html.TextArea("Body") %>
<%= Html.Submit("Submit") %>
<% } %>
And here's the Save action that the view submits to:
public ActionResult Save(int id, string title, string body)
{
var post = id == 0 ? new Post() : _repository.Get(id);
post.Title = title;
post.Body = body;
_repository.Save(post);
return RedirectToAction("list");
}
I don't like the Views to become too complex, and so far I have tended to have separate views for Edit and Add. I use a user control to store the common elements to avoid repetition. Both of the views will be centered around the same ViewData, and I have a marker on my data to say whether the object is new or an existing object.
This isn't any more elegant than what you have stipulated, so I wonder if any of the Django or Rails guys can provide any input.
I love asp.net mvc but it is still maturing, and still needs more sugar adding to take away some of the friction of creating websites.
I personally just prefer to use the if/else right there in the view. It helps me see everything going on in view at once.
If you want to avoid the tag soup though, I would suggest creating a helper method.
<%= Helper.ProfessionField() %>
string ProfessionField()
{
if(IsNewItem) { return /* some drop down code */ }
else { return "<p>" + _profession+ "</p>"; }
}
You can specify a CustomViewData class and pass the parameters here.
public class MyViewData {
public bool IsReadOnly { get; set; }
public ModelObject MyObject { get; set; }
}
And both views should implement this ViewData.
As a result you can use provided IsReadOnly property to manage the UserControl result.
As the controller uses this, you can unit test it and your views doesn't have implementation, so you can respect the MVC principles.

Categories

Resources