Set public property of user control on button click - c#

I have a user control on a page. The user control has a public property on it that I need to set after a button click. How do you do this?
It appears that the control is rendered before the button click event fires, so setting the property has no effect.
Page:
<%# Register src="Email.ascx" tagname="Email" tagprefix="uc2" %>
protected void Page_Load(object sender, EventArgs e)
{
if(!IsPostBack)
EmailList.IsEditable = false;
}
protected void btn_Click(object sender, EventArgs e)
{
EmailList.IsEditable = true;
}
User Control:
public bool IsEditable { get; set; }
The public property gets set correctly when I set it in the page load event, but not on the button click.
The button is used to change the form from read-only to edit mode. Is there a way to set a public property in the button click event? If so, how?

The property is getting set just fine. The problem is where in your usercontrol you set it's controls to readonly/enabled.
If you want to be able to affect how the usercontrol gets rendered, you must do the logic where you're setting the readonly/enabled properties of the subcontrols in the Page_PreRender event of the usercontrol. This event is executed after the buttonclick events.
A must read on msdn: the page lifecycle. You'll notice the control events get processed after Page_Load and before Page_LoadComplete.

Related

Why are routed events fired after initializing the user control?

I am working on a WPF application and I have a window with a grid in it and a few user controls. The problem arises when I add these user controls to the grid from the code behind (through C#),
// UserControlA is the user control with all the working content
var ucA = new UserControlA;
Grid.Children.Add(ucA);
There are two things that happen here, one is the user control is initialized, the second is any load events I have in the code behind of the user control also get fired.
The reason I have these load events like is because before the user control is presented to any employee then it should check for employee authorization, so instead of doing this
public partial class UserControlA : UserControl
{
public UserControlA()
{
IntializeComponent();
Authorize();
}
}
I do this:
public partial class UserControlA : UserControl
{
public UserControlA()
{
IntializeComponent();
}
private void UserControlA_Loaded(object sender, RoutedEventArgs e)
{
Authorize();
}
}
I only want to know why the Loaded event is fired without any reason?

Enable / Disable the Button using MVVM from another UserControl

I Have UserControl called "Footer.xaml" and "Header.xaml" Both User Control are place to different window.
Footer.xaml have two button :-
btnBasic
btnStandard
Header.xaml have one button :-
lobby
When i click on Lobby button from the Header.xaml i want to change the IsEnabled property of the both button [ btnBasic and btnStandard ] on my condition.
I Try the below things [ Footer.xaml.cs ] by default the both button IsEnabled = true
public partial class Footer : UserControl
{
static Footer objFooter = new Footer();
public Footer()
{
InitializeComponent();
objFooter = this;
}
public static Footer GetFooterInstance()
{
return objFooter;
}
}
and on Header.xaml.cs
private void btnLobby_Click(object sender, RoutedEventArgs e)
{
Footer objFooter;
objFooter = Footer.GetFooterInstance();
objFooter.btnBasic.IsEnabled = false;
objFooter.btnStandard.IsEnabled = false;
}
But nothings is effect with button.
You tagged your question for MVVM but posted code is completely violating the rules of MVVM here. You can achieve this by stricting to the rules of MVVM in following manner -
Create a ViewModel class which will serve as DataContext for both of your views.
Create a bool property inside it and bind IsEnabled DP for your buttons namely btnBasic and btnStandard with this property.
Create an ICommand in your ViewModel class which will be invoked on lobby button click and will set this bool property to true or false depending on your situation.
But as you posted in comment above, you already have seperate ViewModels for both Views, you can use Event Aggregator to communicate between two ViewModels.

Customize events handling of an asp.net user-control depending on the calling form

I'm using an asp.net user-control in two different aspx forms. How can I customize the events handling of the user-control depending on the calling form ?
void ComboboxCountry_SelectedIndexChanged(object sender, RadComboBoxSelectedIndexChangedEventArgs e)
{
if it is form1 that called the User-control => do process 1
if it is form2 that called the User-control => do process 2
}
Thanks.
Despite the fact if this is a good design you are trying to implement: you could add a property to your control like
public BehaviourEnum Behaviour { get; set; } // You need to implement the enum
Then you could
void ComboboxCountry_SelectedIndexChanged(object sender, RadComboBoxSelectedIndexChangedEventArgs e)
{
if (Behaviour == BehaviourEnum.Behave1) // etc.
}
The pages implementing your control would need to set the Behaviour-Property accordingly.
Edit: If your control needs to interact with the parent page, I would introduce an interface on the parents page. Then you could design something like this:
// The page containing this control needs to implement IMasterpage
public IMasterpage Masterpage { get; set; }
void ComboboxCountry_SelectedIndexChanged(object sender, RadComboBoxSelectedIndexChangedEventArgs e)
{
// Propagate the behavour to your parent page
Masterpage.CallwatheverMethodInYourInterface();
}
The goal is to propagate behavour which depends on the parent page into the parent page itself. That way you can keep your control slim and independent.

Setting a control's ID in code behind for use in a validation control

How can I use validation controls within server controls? The issue that I have is that by default if I do something like this:
private TextBox _textbox;
RequiredFieldValidator _validator;
protected override void OnInit(object sender, EventArgs e)
{
_textbox= new TextBox {ID = "test"};
_validator = new RequiredFieldValidator{ControlToValidate = _textbox.ID};
}
protected override void OnLoad(object sender, EventArgs e)
{
this.Controls.Add(_textbox);
this.Controls.Add(_validator);
}
Then it works fine but because I've set the ID in code behind the textbox has an ID of test in the actual generated HTML (instead of ctl1_ctl2_test or or something.) This means that if I use the control twice on the same page then I get an error. If I don't set an ID then it is null and the validator can't find the control.
Any help would be great,
Thanks,
Joe
Just add INamingContainer to the list of interfaces implemented by your server control:
public class RequiredTextBox : Control, INamingContainer
Now the ID of the child TextBox will be scoped by the ID of the server control, thus avoiding ID conflicts.

Asp.net Event for change tracking of entities

I have an asp.net page with many dozens of controls representing multiple database entities. I would like to track when any of the data for these entities is changed.
If I add a page member such as
public Page1 : System.Web.UI.Page
{
protected bool Entity1HasChanged { get;set; }
protected void RegisterChange(object sender, EventArgs e)
{
Entity1HasChanged = true;
}
}
Then for each control OnTextChanged event or equivalent I call a method that sets this boolean to true.
I would then like to run a method AFTER all control events have completed which does some database updates. What page event can I hook into to do this? Reading the page on the LoadComplete event it only states that all load events will have completed.
Does anyone know how I should achieve this? Am I doing this completely the wrong way?
Thanks,
Ian
Look at INotifyProperyChanged, INotifyPropertyChanging and INotifyCollectionChanged as your starting point.
Try OnPreRender.
ASP.NET Page Life Cycle Overview
This will also still allow you to modify the page output once you've completed the database operations (e.g. if you want to show a status box to say that the operations completed).
This is a really good question. I messed around with something quick that I think will work. You could create your won TextBox that inherits from TextBox:
namespace ServerControl1
{
[DefaultProperty("Text")]
[ToolboxData("<{0}:ServerControl1 runat=server></{0}:ServerControl1>")]
public class TextBoxWithChange : TextBox
{
[Bindable(true)]
[Category("Appearance")]
[DefaultValue("")]
[Localizable(true)]
public bool HasEntityChanged
{
get
{
bool hasEntityChanged = (bool) ViewState["HasEntityChanged"];
return hasEntityChanged;
}
}
protected override void RenderContents(HtmlTextWriter output)
{
output.Write(Text);
}
}
}
Then you could write a little jQuery script to change that attribute when the client side OnTextChanged event fires. On submit of the form you then could query that HasEntityChanged attribute for any of these TextBoxes.
For this example I put the server control in it's own Library and registered it like this:
<%# Register TagPrefix="MyCompanyName" Namespace="ServerControl1" Assembly="ServerControl1" %>
Then you can declare it on your page like this:
<MyCompanyName:TextBoxWithChange ID="ChangerTextBox" runat="server" HasEntityChanged="false"></MyCompanyName:TextBoxWithChange>

Categories