Lets say i have this usercontrol
public class test : UserControl {
public int Count { get; set; }
public test() {
Count = 3;
}
public override DataBind() {
aRepeater.DataSource = dal.GetObjects(Count);
base.DataBind();
}
}
and i use it on my page like this
<my:test runat="server" Count="<# something %>" />
my problem now is that i am not able to get the value of Count in my usercontrol before after the call to base.DataBind(). I guess its something with databinding values to itself. The workaround sofar has therefor been
public override DataBind() {
base.DataBind(); // to bind values to self
aRepeater.DataSource = dal.GetObjects(Count);
base.DataBind(); // to bind new values that is dependent on the the first bind
}
It works, but it just doesn't seem right. My question is therefor whats the best practices is for this scenario.
Just override OnDataBinding method, not DataBind:
protected override void OnDataBinding(EventArgs e) {
base.OnDataBinding(e);
aRepeater.DataSource = dal.GetObjects(Count);
}
DataBind method essentially consists of two steps: 1) OnDataBinding(), 2) DataBind() for each child control.
It makes sense, because Count="<# something %>" occurs at DataBind(). I think you should handle all the data binding at DataBind() in this case (and not to use page binding methods). Of course this is only a matter of beautifying the code - nothing more.
Do you have to set the Count property of your user control in you .ascx file? How about not having a Count property at all or setting Count in the code behind of the page that includes the user control?
<my:test runat="server" id="test1" />
Code behind:
//User control code behind. GetCount() returns an int.
public override DataBind() {
aRepeater.DataSource = dal.GetObjects(GetCount());
base.DataBind();
}
or
//Page that has the user control.
protected void Page_Load(object sender, EventArgs e)
{
this.test1.Count = 5;
}
//User control code behind.
public override DataBind()
{
aRepeater.DataSource = dal.GetObjects(this.Count);
base.DataBind();
}
Related
using xamarin forms & PCL.
i want to validate the Picker using the Behavior to ensure that user picked an item from the Picker.
my behavior class is
public class PickerValidationBehaviour :Behavior<Picker>
{
private Picker _associatedObject;
public string PropertyName { get; set; }
protected override void OnAttachedTo(Picker bindable)
{
base.OnAttachedTo(bindable);
_associatedObject = bindable;
if (_associatedObject.SelectedIndex < 0 )
{
HandleValidation();
}
}
private void HandleValidation()
{
}
private void _associatedObject_SelectedIndexChanged(object sender, EventArgs e)
{
}
protected override void OnDetachingFrom(Picker bindable)
{
base.OnDetachingFrom(bindable);
_associatedObject = null;
}
}
}
and i was stuck because i want execute the validation before user action, such that the submit button will be hidden until the user fill the form.
and beside if there is any easy efficient way that i can perform the validation please mention it.
I think this scenario you should put logic in VM instead of using behavior.
Cause behavior can change some UI element, like color something and most of them are the element itself's property.
In your case, you want to change another element in Page. There is a problem, how to access another element in your page.
If you binding SelectedIndex in you VM, and when property changed you can raise another property which controls the submit button. That will be easier then do it in behavior.
I'm approaching to Metro App world in this days, please be gentle.
Here's the problem:
a page receives a string from another page
protected override void OnNavigatedTo(NavigationEventArgs e)
{
Title.Text = e.Parameter.ToString();
}
and I need to pass this string to an User Control of the receiving page.
How can I pass a parameter from a page to an UserControl of another page?
Like this:
Add a property to your user control:
public string MyText { get; set; }
Give your user control a name.
<src:TopBarControl x:Name="MyTopBarControl" />
Then use your NavigatedTo method:
protected override void OnNavigatedTo(NavigationEventArgs e)
{
var _TextParam = e.Parameter.ToString();
this.MyTopBarControl.MyText = _TextParam;
}
This will feed your User Control what it needs.
You could also bind to it by setting the parameter to some public property of the page. If you attempt this approach, please remember to make the User Control's property a Dependency property and not a CLR property. I wrote an article on binding if you want a better explaination http://blog.jerrynixon.com/2012/10/xaml-binding-basics-101.html
Best of luck!
Assuming usercontrol is part of navigated page, you have to do set Property of User Control on OnNavigatedTo override.
Example:
class MyUserControl : UserControl
{
public object Parameter {get;set;}
}
Suppose this user control is part of MyPage
class MyPage : Page
{
private MyUserControl myUserControl; // It is only for illustrations, Otherwise it goes to .designer.cs
protected override void OnNavigatedTo(NavigationEventArgs e)
{
Title.Text = e.Parameter.ToString();
myUserControl.Parameter = e.Parameter; // This is how to set the parameter in usercontrol.
}
}
I am using devexpress controls in my page, but that is not the problem.
Here is what happens, I have created a property in the page with a get only, this property will retrieve query string value from a ViewState. I store the value in the ViewState on page load event which is enclosed in !IsPostBack. After I store
note that i have put an update panel on my master page.
I searched the net and found that ViewState values are never stored in callbacks, I don't know if that is the reason. Here is my code:
public partial class _Default : BasePage
{
private Int64 RequestId
{
get
{
return (Int64.Parse(ViewState["RequestId"].ToString()));
}
}
protected override void Page_Load(object sender, EventArgs e)
{
//Check for security
base.Page_Load(sender, e);
if (!IsPostBack)
{
GetQueryString();
gridBind();
}
}
private void GetQueryString()
{
string requestId = this.Request.QueryString["RID"];
if(!String.IsNullOrEmpty(requestId))
ViewState["RequestId"] = Int64.Parse(this.Server.UrlDecode(requestId))
else
ViewState["RequestId"] = 0;
}
}
I edited the question, the first problem i had was due to the IE7 stupidity, but nevertheless ViewState after each postback is null. I tried to use the EnableViewState but it's always null. It's the same in any page I use in my solution. We can't use ViewStates at all. There is definitely something wrong.
I have inherited an asp.net web app , that passes information to a gridview. Each row has different buttons and links on it and they are enabled/disabled based on the information received. There is a very long chain of logic that each row goes through to set up the buttons, which makes it very difficult to read. Is there a way to set up a class of buttons to make this easier to read?
Not sure what you mean by a "class of buttons", but you can create a custom server controls as a wrapper to the button control, and provide some extra properties or methods to simplify the GridView logic.
Here's a quick and dirty example of a RadioButton wrapper that we built, which extends the properties of the standard Radio Button so it can hold extra information. You can try doing something similar for your GridView buttons:
[DefaultProperty("Text")]
[ToolboxData("<{0}:RadioButton runat=server></{0}:RadioButton>")]
public class RadioButton : System.Web.UI.WebControls.RadioButton
{
[Bindable(true)]
[DefaultValue("")]
[Localizable(true)]
public string Value
{
get
{
string RadioValue = (string)ViewState["Value"];
return (RadioValue == null) ? String.Empty : RadioValue;
}
set
{
ViewState["Value"] = value;
}
}
protected override void RenderContents(HtmlTextWriter output)
{
output.Write(Text);
}
}
One thing that you could do quickly would be to convert the DataSource to a report class. You could then move the logic for enabling/disabling into that class (i.e., individual property per button), and update the grid to simply check the appropriate property per link/button.
This at least moves the logic out of the aspx file to somewhere it can be maintained/perused more easily.
For example:
grid.DataSource = MyReportClass.GetReport();
Where
public MyReportClass
{
public string Name { get; set; }
public string EnableLink1 { get { //logic here } }
public string EnableButton3 { get { ///logic here } }
public static List<MyReportClass> GetReport()
{
// get the data
}
}
then the aspx becomes
<gridview id="grid" runat="server" ... >
...
<asp:templatefield headertext="Link1" ><itemtemplate>
<asp:linkbutton id="l1" runat="server" ...
visible='<%# !(bool)DataBinder.Eval(Container.DataItem, "EnableLink1") %>'
/>
</itemTemplate></asp:templatefield>
...
</gridview>
How can I pass user control properties to the page AND make these properties available to all methods on the page (and not just to one method that is fired on a control action, e.g. onControlClick)
I have a set up of essentially 3 pages:
user control (ascx/cs)
class (cs) - that contains user control properties
host page (aspx/cs) - references the user control
The user control consists of 3 interrelated dropdowns. I'm having success passing these dropdown values through a class onto the page via an event that is fired when a user clicks on the dropdown menu. So this way the host page is continously aware of the values in the user control. However, I want the page to use the control's properties (stored in a class) on all of its methods - how do I make this user control class available to all?
Also I'm using ASP.NET and C# by the way.
Here's the Code (not sharing the full code here - just the snippets of a similar code block)
On the ASPX for Menu Host Page:
<linked:LinkMenu2 id="Menu1" runat="server" OnLinkClicked="LinkClicked" />
Host Page (cs):
protected void dropdownclicked(object sender, ddtestEventArgs e)
{
if (e.Url == "Menu2Host.aspx?product=Furniture")
{
lblClick.Text = "This link is not allowed.";
e.Cancel = true;
}
else
{
// Allow the redirect, and don't make any changes to the URL.
}
}
Host Page (aspx)
<asp:dropdowncustom ID="dddone" runat="server" OnddAppClicked="dropdownclicked" />
Control (cs)
public partial class usercontrol_tests_dropdown1 : System.Web.UI.UserControl
{
public event ddtestEventHandler ddAppClicked;
}
public void selectapp_SelectedIndexChanged(object sender, EventArgs e)
{
ddtestEventArgs args = new ddtestEventArgs(selectlink.SelectedValue);
ddAppClicked(this, args);
}
Class:
public class ddtestEventArgs : EventArgs
{
// Link
private string link;
public string Link
{
get { return link; }
set { link = value; }
}
public ddtestEventArgs(string link)
{
Link = link;
}
}
public delegate void ddtestEventHandler(object sender, ddtestEventArgs e);
Hopefully this is what you're after. The best way to do it is to expose your controls as public properties from your user control. So, in your user control, for each drop down list add a property:
public DropDownList DropDown1
{
get { return dropDownList1; }
}
public DropDownList DropDown2
{
get { return dropDownList2; }
}
You can do the same for any other properties you want to access on the host page:
public string DropDown1SelectedValue
{
get { return dropDownList1.SelectedValue; }
set { dropDownList1.SelectedValue = value; }
}
Then, from your host page you can access the properties through the user control:
string value = UserControl1.DropDown1SelectedValue;
or
string value = UserControl1.DropDownList1.SelectedValue;
Here's a couple of other answered questions that you might find useful as I think (if I've understood correctly) this is what you're doing:
Getting data from child controls loaded programmatically
How to change the value of a control in a MasterPage.