why can't i access a function of a web control? - c#

i have the next question:
I've got an .aspx which contains a lot of web controls, this is the one i care:
//line 5
<%# Register src="Controls/UCAttachments.ascx" tagname="UCAttachments" tagprefix="uc1" %>
//line 430
<uc1:UCAttachments ID="UCAttachments" runat="server" Visible="false" />
On the selected index changed event of a combo box, i need to call a function of the web control, this is the code of the .aspx.cs.
private void cbo_SelectedIndexChanged( object sender, EventArgs e )
{
if(this.op == 1){
UCAttachments.visible=true;
UCAttachments.loadById(this.id); <-this doesnt work.
//Even tho, i can access all the other functions of UCAttachments.
//More infor abkout the error:
//'CONTROL' does not contain a definition for 'loadById'and no accessible //method accepting first argument...
}
}
public partial class Controls_UCAttachments: System.Web.UI.UserControl
{
//lots of functions
public void loadById( string id )
{
string query = "SELECT * FROM table WHERE ID = " +id;
//more code
return ;
}
}

you have to make this method static
public partial class Controls_UCAttachments
{
//lots of functions
static public void loadById(string id)
{
string query = "SELECT * FROM table WHERE ID = " + id;
//more code
return;
}
}
and you can call using this syntax
Controls_UCAttachments.loadById(this.id);

so.. very curious thing.
when you have a form which contains a lot of user controls, you need to wait for the metadata file to reload the new methods you've created.
So i closed my visual studio and re opeened a minutes later and the bug desapeared.

Related

In relation to acumatica, is there a way to grab a variable from one table and use it as part of an id for another table?

The 'Customer' form has a variable called AcctReferenceNbr (Variable that I'm trying to grab shown in yellow) which takes a two-letter abbreviation of the customer name. I am currently editing the Projects form, and I want to use this abbreviation as part of the External Ref. Nbr.
The attached image End Result I'm trying to achieve shows what the end result should look like. The number from the QuoteID is appended to the abbreviation.
I am able to successfully grab the QuoteID as it is part of the Projects table, but I am currently unable to grab the AcctReference Nbr from the Customer table.
I have a RowSelected event on the QuoteID field, which is shown below:
namespace PX.Objects.PM
{
public class ProjectEntry_Extension : PXGraphExtension<ProjectEntry>
{
#region Event Handlers
protected void PMProject_RowSelected(PXCache cache, PXRowSelectedEventArgs e)
{
PMProject row = (PMProject)e.Row;
if (row.ContractCD != null) {
PMProject item = PXSelectorAttribute.Select<PMProject.contractCD>(cache, row) as PMProject;
// The "UP" string is where the abbreviation is supposed to be,
// but I just added two letters to test if the appending works, which it does.
row.ExtRefNbr = "UP" + item.ContractCD;
}
}
#endregion
}
}
What I've tried so far:
Accessing the Customer table namespace to grab the value and pass it to the Projects form, which didn't work because it didn't accept the Customer type in the Projects form.
Adding a PXDefault attribute to the External Ref. Nbr which would try and grab the variable using SQL.
I'm a bit stuck on what else I can try. Any help would be appreciated :)
UPDATED
Below is how I went about trying to grab the AcctReferenceNbr value from the Customer table.
The reason why I tried using the PXSelectorAttribute method was that I added the AcctReferenceNbr as a column to the Quote ID selector (selector is shown in the link above called 'End Result I'm trying to achieve').
So I figured I could try and grab that value in the Customer namespace, as that is where the variable resides, and pass that up to the Project namespace above.
Then, I would call the public method below in the Project namespace to get the required abbreviation:
// instead of this
row.ExtRefNbr = "UP" + item.ContractCD;
// it would be this
row.ExtRefNbr = PX.Objects.AR.CustomerMaint_Extension.getAcctReferenceNbr(cache, e) + item.ContractCD;
namespace PX.Objects.AR
{
public class CustomerMaint_Extension : PXGraphExtension<CustomerMaint>
{
#region Event Handlers
public static string getAcctReferenceNbr(PXCache cache, PXRowSelectedEventArgs e)
{
BAccount row = (BAccount)e.Row;
BAccount item = PXSelectorAttribute.Select<BAccount.acctReferenceNbr>(cache, row) as BAccount;
return item.acctReferenceNbr;
}
}
#endregion
}
}
Is there a proper way to target the actual table?
try this. I haven't tested this but give it a go.
protected void PMProject_RowSelected(PXCache cache, PXRowSelectedEventArgs e)
{
PMProject row = (PMProject)e.Row;
if (row.ContractCD != null && row.CustomerID != null)
{
BAccount ba = (BAccount )PXSelectorAttribute.Select<PMProject.customerID>(cache, row) ;
row.ExtRefNbr = ba.AcctReferenceNbr+ row.ContractCD;
}
}
you certainly don't need to extend the CustomerMaint graph.

How to modify the content and create many instances for a dynamic user control?

I need to use a User Control many times in the same page.aspx
I am working with visual studio 2012 and asp.net 4.0 I trying to do many graph that receives different parameter each one.
I have an user control.ascx that has code behind control.ascx.cs with a function
public void myTask(string myParameter)
I have a page.aspx with a panel
<asp:Panel ID="Panel1" runat="server">
</asp:Panel>
I had a code behind page.aspx.cs with
protected void Page_Load(object sender, EventArgs e)
{
UserControl cuc = (UserControl)LoadControl("~/cmmon/userCntrol/myusercontrol.ascx");
Panel1.Controls.Add(cuc);
My code shows nice for just one graphic.
I am willing to create many instances for my user Control and call each function from the page.aspx int the behind code page.aspx.cs like
myTask(myParameter);
with different parameter for each one. How do I do?
You can create multiple in a loop. Make sure to give each an unique ID.
for (int i = 0; i < 5; i++)
{
WebUserControl1 cuc = (WebUserControl1)LoadControl("~/WebUserControl1.ascx");
cuc.ID = "Control" + i;
Panel1.Controls.Add(cuc);
}
Then you can locate the control somewhere else in the code based on that ID.
WebUserControl1 uc = Panel1.FindControl("Control3") as WebUserControl1;
I found and resolve two issues: 1) how to send parameters to a control object. and 2) how to reference a control in another c# page.
1) To send parameters to a control object I have to define variables to accept the values of the parameters, it is done in the object control by:
using System.Web.UI.WebControls;
public partial class myControl : System.Web.UI.UserControl
{
public string variable { get; set; }
public void start(string parameter)
{
variable = parameter;
}
}
2) To reference a control in another c# page. in the page directive should be:
<%# Reference Control="~/cmmon/userCntrol/myControl.ascx" %>
Then, as VDWWD answer, in your code behind you can include an object like:
for (int i = 0; i < 5; i++)
{
WebUserControl1 cuc = (WebUserControl1)LoadControl("~/WebUserControl1.ascx");
cuc.ID = "Control" + i;
Panel1.Controls.Add(cuc);
}
And call the function as I needed:
cuc.myTask(myParameter);
Then:
for (int i = 0; i < 5; i++)
{
WebUserControl1 cuc = (WebUserControl1)LoadControl("~/WebUserControl1.ascx");
cuc.ID = "Control" + i;
Panel1.Controls.Add(cuc);
cuc.myTask(myParameter);
}

Web User Control Causing Page Not Found

I came across a pretty weird issue. Some of my Web User Controls are causing the parent page which references it to get 404 page not found error.
Here is how I register it on the .aspx page:
<%# Register TagPrefix="uc" TagName="DonationList"
Src="~/Controls/Donation/DonationList.ascx" %>
And the line where the user control is declared on the same aspx page:
<uc:DonationList ID="seenDonationListUC" runat="server" SeenInformation="Seen" />
If I remove the above line, I don't get a 404 error page anymore.
This is a small snippet of the user control class:
public partial class DonationList : System.Web.UI.UserControl
{
public enum Seen
{
Unspecified = 0,
Seen = 1,
NotSeen = 2
}
public Seen SeenInformation
{
get
{
int temp = seenInformationHF.Value == "" ? 0 : Convert.ToInt32(seenInformationHF.Value);
result = (Seen) temp;
return result;
}
.....
Any idea on the possible causes of this?
Name of your enum and subsequent enum value both are same "Seen". Try changing the enum name to something like SeenOptions. For example,
public enum SeenOptions
{
Unspecified = 0,
Seen = 1,
NotSeen = 2
}
In this case your SeenInformation class will look like,
public SeenOptions SeenInformation
{
get
{
int temp = seenInformationHF.Value == "" ? 0 : Convert.ToInt32(seenInformationHF.Value);
result = (Seen) temp;
}
.....
And finally, your user control line on aspx page will be same as before.
<uc:DonationList ID="seenDonationListUC" runat="server" SeenInformation="Seen" />
I hope this will fix your problem.

Check permission on every page

in my web site i need to check permission on every page,
i found my self repeating the same code every page.
this is one of my pages
public partial class KitView : AmsBasePage
{
protected void Page_Load(object sender, EventArgs e)
{
IddUser user = new IddUser();
user = (IddUser)Session["user"];
bool isAdmin = user.roles.Where(IddRole => IddRole.R_ID.Equals(3)).First().IsInRole;
bool isIddTeam = user.roles.Where(IddRole => IddRole.R_ID.Equals(2)).First().IsInRole;
bool isProductionTeam = user.roles.Where(IddRole => IddRole.R_ID.Equals(1)).First().IsInRole;
if (isAdmin)
{
hypAddComponent.Visible = true;
hypAddComponent.NavigateUrl = "AddComponent.aspx?CKID=" + Request.QueryString["CKID"];
}
}
}
how is the best practice to have the roles: isAdmin,isIddTeam,isProductionTeam
in every page but not repeating the code below in every page code
IddUser user = new IddUser();
user = (IddUser)Session["user"];
bool isAdmin = user.roles.Where(IddRole => IddRole.R_ID.Equals(3)).First().IsInRole;
bool isIddTeam = user.roles.Where(IddRole => IddRole.R_ID.Equals(2)).First().IsInRole;
bool isProductionTeam = user.roles.Where(IddRole => IddRole.R_ID.Equals(1)).First().IsInRole;
You should put your authorization code in your Master Page (ASP.NET Web Form) or Layout Page (ASP.NET MVC). That way, your authorization logic will only be placed in one location and runs on every page.
If you want to avoid redundant codes, i would suggest to write your authorization logic in a sepearte class or you can even write the aurthorization logic in a MasterPage if you have any. Then inherit them in your webforms.
Note: in your webforms you will have to override your page_load event so that the authorization from your inherited base class runs first.
if you want to avoid repeating authorization code, you should do it at a central location.
there can be many ways for that, but I can suggest you few
Use Master Page - and write the authorization code in Master Page's OnLoad
Create a HttpModule - Insert your own Module in the ASP.NET Page Events PipeLine and handle all the authorization and authentication logic
Now this is what I did in a multi-million $ Project
Create a PageBase.cs being inherited from System.Web.UI.Page - which you are already doing
Create a constructor of the PageBase, in which you can pass current Page permissions i.e.
public void PageBase(AppActivityEnum PageView, AppActivityEnum PageEdit, AppActivityEnum PageDelete)
{
this.pageView = PageView;
this.pageEdit=PageEdit;
this.PageDelete=PageDelete;
VerifyPermission();
}
where VerifyPermission() is:
public void VerifyPermission()
{
var currentUser= SessionHelper.GetCurrentUser();
var permissions = Utility.GetUserPermissions(currentUser.RoleId);
this.CanView=permissions.Contains((int)this.pageView);
this.CanEdit=permissions.Contains((int)this.pageEdit);
this.CanDelete=permissions.Contains((int)this.pageDelete);
}
now these three variables i.e. CanView, CanEdit, CanDelete are public properties in PageBase, hence available to all your pages(wherever you have inherited).
and you can set your controls(add button, delete button), page visibility based on these variables.
so basically, you create an Activity Table for storing ref of each of the Pages. where Activity table looks like
Id
Name
Value
Parent
a typical entry in this table is like:
1 Module-Master MMaster NULL
2 Module-Master-View MMasterView 1
3 Module-Master-Edit MMasterEdit 1
4 Module-Master-Delete MMasterDelete 1
and you maintain RoleAppActivtyMapping (obviously):
Id RoleId AppActivityId
1 1 2
1 1 3
1 1 4
so RoleId one has all the three permissions.
so GetUserPermissions(RoleId) basically gets all the RoleAppActivityMapping entries corresponding to passed Role.
so on every page you call the PageBase' constructor to verify the view permissions. You pass the current Page's AppActivity Id in the constructor.
and if CanView is false: you redirect to "UnAuthorized" page upon hitting the url.
I added in my AmsBasePage class that all pages inherit from .
this code
private bool _isAdmin;
private bool _isIddTeam;
private bool _isProductionTeam;
protected bool isAdmin
{
get { return _isAdmin; }
set { _isAdmin = value; }
}
protected bool isIddTeam
{
get { return _isIddTeam; }
set { _isIddTeam = value; }
}
protected bool isProductionTeam
{
get { return _isProductionTeam; }
set { _isProductionTeam = value; }
}
check your authorization in the master page. That way, I will be checked once and repeatation can be avoided.

Asp.net passing values to the User control then display them

I'm trying to make a generic Search UserControl that can be given some values, based on those values the search results will display. However I'm currently trying to display the results of my values, and they always show up as my default values.
my UserControl code:
<%# Control Language="C#" AutoEventWireup="true" CodeBehind="ProductSearch.ascx.cs" Inherits="..." %>
<asp:Label ID="lblSearchWord" runat="server" />
<asp:Label ID="lblSearch" runat="server" />
Code Behind:
private string _searchWord = string.Empty;
private int _search = -1;
public string SearchWord
{
get { return _searchWord; }
set { _searchWord = value; }
}
public int Search
{
get { return _search; }
set { _search = value; }
}
protected void Page_Load(object sender, EventArgs e)
{
lblGroupId.Text = LevelId.ToString();
lblSearchWord.Text = SearchWord;
}
When I press the search button on the main aspx.cs page I do the following:
protected void btnSearch_Click(object sender, EventArgs e)
{
ucPS.SearchWord = txtProductSearch.Text;
ucPS.Search = 1
}
My aspx page contains the following
<%# Register src="UserControls/ProductSearch.ascx" tagname="ProductSearch" tagprefix="ps" %>
<ps:ProductSearch id="ucPS" runat="server" />
My problem is that I can't use Query strings as the user might have selected some other things on this page that I need to keep the state of, however I did test that one and foudn it working.
Where am I going wrong? or is there an better alternative (except for query strings).
All variables in a page are disposed at the end of the page-lifecycle. Hence SearchWord will always be initialized with the default value on every postback.
You need to persist it somewehere else, for example in a ViewState variable.
public string SearchWord
{
get
{
if (ViewState["SearchWord"] == null)
return "";
else
return (String)ViewState["SearchWord"];
}
set { ViewState["SearchWord"] = value; }
}
Nine Options for Managing Persistent User State in Your ASP.NET Application
public string SearchWord
{
get
{
if (ViewState["SearchWord"] == null)
ViewState["SearchWord"] = string.Empty;
return ViewState["SearchWord"];
}
set
{
ViewState["SearchWord"] = value;
}
}
and I use databind not pageload, this way your usercontrol doesn't load unless you call it.
protected override DataBind()
{
//you can add a condition here if you like
if(SearchWord != string.Empty)
lblSearchWord.Text = SearchWord;
}
to call this from aspx:
usercontrol.SearchWord = "my word";
usercontrol.DataBind();
and thats it..

Categories