I have a user control on a web form that is declared as follows:
<nnm:DeptDateFilter ID="deptDateFilter" runat="server" AllowAllDepartments="True" />
In the code-behind for this control, AllowAllDepartments is declared as follows:
internal bool AllowAllDepartments { get; set; }
Yet when I view the page, and set a breakpoint in the control's Page_Load event handler, my AllowAllDepartments property is always false. What are possible reasons for this?
BREAKING NEWS: Even setting the property programmatically has no effect on the property value when I hit my breakpoint in Page_Load of the control. Here is the Page_Load of the host page:
deptDateFilter.FilterChanged += deptDateFilter_FilterChanged;
if (!IsPostBack)
{
deptDateFilter.AllowAllDepartments = true;
PresentReport();
}
Try adding the property value to the ViewState:
protected bool AllowAllDepartments
{
get
{
if (ViewState["AllowAllDepartments"] != null)
return bool.Parse(ViewState["AllowAllDepartments"]);
else
return false;
}
set
{
ViewState["AllowAllDepartments"] = value;
}
}
EDIT
Furthermore, you may want to handle the control's PreRender event, to see whether the the control's property has been correctly set there or not.
Make the property bindable like:
[Bindable(true), Category("Appearance"), DefaultValue(false)]
internal bool AllowAllDepartments { get; set; }
Just out of curiosity... does it work OK if you don't use the get;set; shortcut?
private bool _allowAllDepartments;
public bool AllowAllDepartments
{
get { return _allowAllDepartments; }
set { _allowAllDepartments = value;}
}
Have you tried making the property public?
Related
I have a custom CheckBox class. I have overrided getters for Enabled and Visible property (I need some complicated behavior).
When I the run application and debug it I found that my Enabled's getter is not called at all. At the same time the Visible property is called correctly, and I get the desired result.
public class CustomCheckBox : CheckBox
{
public override bool Visible
{
get
{
bool result;
//Do something
return result;
}
set
{
base.Visible = value;
}
}
public override bool Enabled
{
get
{
bool result;
//Do something
return result;
}
set
{
base.Enabled = value;
}
}
}
I have some suspicions about it. Maybe during the render stage CheckBox does not call the Enabled property, but looks for the needed attribute within InputAttribute collection. I'm not sure and do not know how to determine it.
I'm trying to figure out how to create a web server control which is basically an ExpandoObject.
The desire is to automatically create a property on the control when it is created in the aspx markup.
For example:
<x:ExpandoControl someProperty="a value"></x:ExpandoControl>
Where the someProperty attribute does not yet exist as a property on the control.
I should also mention that I don't strictly need any functionality of Control or WebControl. I just need to be able to declare it in markup with runat="server" (which in and of itself may require it to be a control, at least that's what I'm thinking).
Is it possible? If so how can I get started?
Many thanks.
I think your first bet would be to implement IAttributeAccessor:
public interface IAttributeAccessor
{
string GetAttribute(string key);
void SetAttribute(string key, string value);
}
The ASP.NET page parser calls IAttributeAccessor.SetAttribute for each attribute it cannot map to a public property.
So perhaps you can start with
public class ExpandoControl : Control, IAttributeAccessor
{
IDictionary<string, object> _expando = new ExpandoObject();
public dynamic Expando
{
{
return _expando;
}
}
void IAttributeAccessor.SetValue(string key, string value)
{
_expando[key] = value;
}
string IAttributeAccessor.GetValue(string key)
{
object value;
if (_expando.TryGetValue(key, out value) && value != null)
return value.ToString();
else
return null;
}
}
I am making a custom web control for my ASP page that inherits from CompositeDataBoundControl. I have a public property in the definition of my control that is required, if the user does not provide this property in the control definition on an ASP page it will break and we will get an exception. I want the compiler to throw a warning similar to the one when a user forgets to provide the 'runat' property of a Control.
"Validation (ASP.Net): Element 'asp:Button' is missing required attribute 'runat'."
Here is basically what my code looks like:
public class MyControl : CompositeDataBoundControl, IPostBackEventHandler
{
private string _someString;
public string SomeString
{
get { return _someString; }
set { _someString = value; }
}
// Other Control Properties, Functions, Events, etc.
}
I want "SomeString" to be a required property and throw a compiler warning when I build my page.
I have tried putting a Required attribute above the property like so:
[Required]
public string SomeString
{
get { return _someString; }
set { _someString = value; }
}
but this doesnt seem to work.
How can I generate such a compiler message?
Thats quite simple, on page load you can check if the property has some value or not. You can check it for Null or Empty case depending on your property type.
like if i have this
private string _someString;
public string SomeString
{
get { return _someString; }
set { _someString = value; }
}
On page_load event i will check if
if(_someString != null && _someString != "")
{
String message = "Missing someString property";
isAllPropertySet = false; //This is boolean variable that will decide whether any property is not left un-initialised
}
All The Best.
and finally
I have a WebControl and it has a property. However, value of this property should not be changed once the control has been constructed... in other words, the property can be set only in some code like:
<ct:Acontrol ID="xxx" Aproperty="xxx" runat="server"></ct:Acontrol>
but not:
xxx.Aproperty=...
so what is the normal way to do that? Thanks!
The properties that you are using in markup must be public properties with a public getter and setter. There is no special syntax for "only set this once".
What you can do is check in the setter whether it was already set and if so, not set to the new value.
private string _aProperty;
public string Aproperty
{
get { return _aProperty;}
set
{
if(_aProperty == null)
{
_aProperty = value;
}
}
}
You should be able to use
xxx.Attributes("Aproperty")
All ASP.NET markup attributes are set as properties after the constructor is executed. You can select specific read-only properties to be set only in the constructor by using sub-classes of the control.
<!-- Aproperty=xxx -->
<ct:Acontrolxxx ID="xxx" runat="server"></ct:Acontrolyyy>
<!-- Aproperty=yyy -->
<ct:Acontrolyyy ID="yyy" runat="server"></ct:Acontrolxxx>
public class Acontrolxxx : Acontrolbase
{
public Acontrolxxx () { base.Aproperty = xxx; }
}
The property is probably using a combination of the EditorBrowsable and DesignerSerializationVisibility attributes:
[EditorBrowsable(EditorBrowsableState.Never)]
[DesignerSerializationVisibility(DesignerSerializationVisibility.Visible)]
public string SomeProperty { get; set; }
The DesignerSerializationVisibility attribute shows the property in markup, and the EditorBrowsable attribute hides the property in code-behind.
I have a question, and it may be because I'm not understanding the way viewstate works. I have some code that sets a viewstate variable in the setter for a property in a custom control I have made.
public bool EditMode
{
get { return (bool)(ViewState["editMode" + this.ID] ?? false); }
set {ViewState["editMode" + this.ID] = value;}
}
The editmode is being set during a button click event.
public void shippingButton_Click(object sender, EventArgs e)
{
if (((Button)sender).CommandName== "Edit")
{
ctrlShippingAddress.EditMode = true;
}
else
{
Page.Validate();
if (Page.IsValid)
{
ctrlShippingAddress.SaveAddress();
ctrlShippingAddress.EditMode = false;
}
}
}
I've tried manually setting it on page load in case I wasn't adding this to the viewstate at the correct point in the page cycle, but as I understand it events occur before render. I have also tried adding ViewStateMode="Enabled" to the control, then to the page using it, then to the master page with no luck.
If I debug at the point of the get/set I see that viewstate is an empty collection (which doesn't make sense because it's also saving form data that is persisting as it should).
I appreciate any help.
You don't need to append the control ID to the ViewState key. I assume you're doing that for uniqueness, but it's not necessary.
The above may fix your problem, but if not try something like this instead:
public bool EditMode
{
get
{
bool editMode = false;
if (ViewState["editMode"] != null)
editMode = (bool)ViewState["editMode"];
return editMode;
}
set
{
ViewState["editMode"] = value;
}
}
After reviewing with a co-worker I discovered that the issue was in the pages node of the web.config
<pages enableViewState="false">
needed to be set to true