I have a form with a lot of user input controls; most of them are optional, and for reasons beyond my control the required elements are scattered around the form. I've been asked to add a button that opens a second form (henceforth called ChildForm) which is linked to the original form (henceforth called ParentForm) and has only the required controls from ParentForm.
I want the controls in ChildForm to be linked to the same datasource as their corresponding controls in ParentForm. I'd like to create this linkage programmatically in a loop so that later changes to ParentForm don't require manually editing the databindings of ChildForm controls.
I tried ChildControl.DataBindings.Add(ParentControl.DataBindings[0]); but I get a dataBinding belongs to another BindingsCollection ArgumentException at runtime.
How can I bind a new control to the same column of a DataTable as an existing control without manually doing it for each control?
If your Binding is simple (doesn't have any Format and Parse event handler registered), you can do a shallow clone like this:
public void CloneBinding(Control control, Binding bind){
Binding bind = new Binding(bind.PropertyName, bind.DataSource, bind.BindingMemberInfo.BindingMember);
control.DataBindings.Add(bind);
}
//Use it
CloneBinding(ChildControl, ParentControl.DataBindings[0]);
Related
As the title suggests, we are having issues getting the correct text value of a Textbox after a post back.
Context:
The Textbox is called textbox_registration
The Textbox is in a dynamically loaded control.
The dynamic control is recreated every post back and has its data set in the OnInit event.
The dynamic controls are within a PlaceHolder inside an UpdatePanel.
It is expected that the value posted in the form will then be present in the Text property of the Textbox. The first form submission is fine, then it gets weird. The UniqueID of textbox_registration changes in every subsequent submission, breaking the expected value stored in the Text property. The following is an example of the UniqueIDs of the Textbox.
ctl00$CollapsableSidebar$panel_editAsset$ctl01$textbox_registration
ctl00$CollapsableSidebar$panel_editAsset$ctl02$textbox_registration
My theory is that when the dynamic control it loaded in init again it avoids a collision with the previous instance of the Textbox by changing the generated UniqueID, then when the second post back occurs the ID has to be different, and thus corrupting the ViewState initialisation between the init and load methods.
This is very irritating, because looking in the Request.Form collection I can see the correctly posted value.
How can I retrieve the posted value for textbox_registration.Text?
Edit 1:
Just to clarify textbox_registration is a normal static ASP Textbox within a UserControl that we have loaded dynamically.
Edit 2:
To outline the scenario, the source code has been stripped down to the following files:
Item Page, a page to display items.
Edit Pane, a custom UserControl on the Item Page that is used to load the dynamic controls.
Dynamic Control, an example of a dynamic item editing control loaded into the Edit Pane.
IEditItemPanel, an interface that the edit controls must implement.
Try setting ClientIDMode property when you create your TextBox control
textbox_registration.ClientIDMode = ClientIDMode.Static;
Then when you want to retrieve the text
var textBox = (TextBox)this.Form.FindControl("textbox_registration");
var textBoxText = textBox.Text;
After investigating the issue, it was a logical error causing the issue.
Because the edit control was loaded dynamically it was important that the control was loaded for post backs by the end of OnInit or up to OnLoad as long as the item was loaded in the control before Controls.Add() was called.
With this knowledge, the OnInit event was investigated closely in the dynamic control. It was being called twice on the post backs! A logic error! This caused the controls to be created twice and the posted form values corresponded to the controls created in the first OnInit call. Therefore, the second OnInit call generated different UniqueIDs for the controls. When the ViewState was restored the controls did not exist.
The solution was to make sure the control is created properly every post back like the first time it is created. The first time didn't make a duplicate control, so neither should the second!
Turns out a look back at the 'Dynamic Controls Basics 101' was needed.
This link 'Dynamic Controls Made Easy in ASP.Net' finally made the solution click into focus.
I am creating an application where the controls on the form will be created at run-time using web-service. Web-Service return a class object using that information I create control on the UI.
The problem that I am facing is when the controls are rendered on the UI and I want access any one of the control I need to specify name which is hard-coded , as below.
TextBox txtbx = (TextBox)Controls["txtbx1"];
Since the names of the control are also dynamic I don't want to hard-code them.
What is the best solution to solve this problem
Use the FindName(string) method of the containing FrameworkElement (e.g. Window or other container control): TextBox txtbx = (TextBox)mainWindow.FindName("txtbx1");
I have a Form with variable number of UserControls. This UserControl allow adding/removing labels and has an event of changing the text of each label by additional small form. How to save the state of the Main Form with number of UserControls(with labels) from previous Form loading and editing and event of label name changing?
See this how to save and load the properties to xml. As addition to save all the control you had on the form, loop through the controls and use a propertie in your settings class to save the control name. This can be used when you're instantiate / load the controls back up.
In my C# WPF .NET 4.0 application, I have a listbox containing user control items. What I want is to call some functions from these user controls to the parent form.
Item user controls have binding to the listbox via view model class.
What do you propose.
Thank you,
You can bind a command to your user control the same way as it would be a parent view. Then you can process this command in the appropriate view model.
I'm not entirely clear on what you're trying to do, but it sounds like you have a bunch of user controls and you want those controls to be able to call methods on the containing Window instance.
From inside your controls, you can use the following to get hold of the Window instance:
Window parentWindow = Window.GetWindow(this);
Note though that you can't do this from the control's constructors, because during the constructor the control won't yet have a parent window and the above will return null. The best place to do this would be from the control's Initialized or Loaded events.
I have some problems trying to update components of surface elements. I dont know if my approach to the problem is wrong, since I'm new to the topic.
My point is represented by the following diagram
According to the option that is selected in the menu, load different user controls as only child of StackPanel but i'm habing problems for update the Listview from loaded user controls, example: when I save a new item I need to recharge the list of items in the ListView
MVVM would be a good pattern here. If you have a problem passing data between controls - why not introduce them on top of unified data layer? Consider this:
Three radio buttons in your Menu, each one's IsChecked property bound to Visibility property of your respective UserControl.
StackPanel holding all three UserControls
ListView bound to ViewModel's List<Item>
Each of your UserControls bound to ListView.SelectedItem: one of them using TextBlock for read-only, one using TextBox for editing. Third one would create new item in your List<Item>. You would have to create ItemTemplate for each or create one UserControl (since they look very much alike) and use DataTemplateSelector.
If you're not familiar with MVVM here is a good start. You can also use one of the existing frameworks like MVVM Light
You can create an event on your child
public delegate void HandleNAMEOFYOURHANDLEEVENT();
on your child class
public event HandleNAMEOFYOURHANDLEEVENT yourInstance;
to use it on your child class
if (!ReferenceEquals(yourInstance, null))
{
yourInstance();
}
and you declare it on your parent like other event.