Save/Open Dynamically Created Controls In a Form - c#

I am trying to develop a program in which it could create forms and add controls to it at runtime.
It also should be able to save, (Open and Edit) the forms created with the new controls added it at Runtime.The Application starts In the Main form.
CODE BEHIND MAIN Form
private void Btn_CREATE_FORM_Click(object sender, EventArgs e)
{
Form_Properties fp = new Form_Properties();
fp.Show();
}
private void BTn_ADD_BTN_Click(object sender, EventArgs e)
{
/// WHAT CODE SHOULD I ENTER TO ADD BUTON TO NEW FORM
}
Basically the main form is used to create/open/save new forms and add controls to it.
When the user clicks on Create New Form button the user will be presented with the following form (FORM_PROPERTIES) in which the user can customize the name, width and height of the new form.
CODE BEHIND FORM_PROPERTIES Form
public partial class Form_Properties : Form
{
public Form_Properties()
{
InitializeComponent();
}
String form_name;
int form_width;
int form_height;
private void Btn_OK_Click(object sender, EventArgs e)
{
form_name = TBox_NAME.Text;
form_width = Convert.ToInt32(TBox_WIDTH.Text);
form_height = Convert.ToInt32(TBox_HEIGHT.Text);
New_Form nf = new New_Form();
nf.Text = form_name;
nf.Width = form_width;
nf.Height = form_height;
nf.Show();
}
}
The following image shows what happens at runtime based on the code I have written so far.
ISSUES
Need help to Write Code
To add controls to new form created.
To Save/Open/Edit Functionalities.
I also need to know the method to access properties of added controls at runtime.
eg: If the user adds a text box to the NEW FORM and decides to type some text in it, I need a method to save that text.
Is there a way for me to name the added controls?

It seems you want to build some kind of WinForms' form designer. Your program would be similar to Glade (though Glade is much more powerful).
I'm afraid the question is too broad, though. There are many questions to answer, for example, how do you describe the created interface.
While Glade uses XML, you can choose another format, such as JSON. Let's say that you have a TextBox with the word "example" inside it.
{ type:"textbox" text:"example" }
It seems you want to add your components to the form as in a stack. Maybe you could add its position. For example, a form containing a label
("data"), a textbox ("example"), and a button ("ok"), would be:
{
{ pos:0, type:"label", text:"data" },
{ pos:1, type:"textbox", text:"example" },
{ pos:2, type:"button", text:"ok" },
}
But this is just a representation. You need to a) store this when the form is saved, and b) load it back when the form is loaded.
For that, you will need a class representing the components, such as:
public class Component {
public override string ToString()
{
return string.Format( "position:{0}, text:{1}", this.Position, this.Text );
}
public int Position { get; set; }
public string Text { get; set; }
}
public class TextBoxComponent: Component {
public override string ToString()
{
return base.ToString() + "type:\"textbox\"";
}
}
...and so on. This is a big task, I'm afraid, with no simple answer.

Related

How to transport information from one form to another using dto, C# Windows Forms?

I'm having trouble transporting information from one form to another, is to make a single save, but the information is distributed in 2 forms and I have to do it using dto. I know that for this I have to send the data that I want by the form builder method, as you can see in the code below:
public FrmModalFornecedor(int providerId, int providerDoc)
{
InitializeComponent();
CbxListarFornecedor();
providerDoc = Convert.ToInt32(txtDoc.Text);
providerId = Convert.ToInt32(((Provider)cbxFornecedor.SelectedItem).ProviderId);
}
But now my questions are:
How to make these variables take their respective text box and combo box values?
How to make the next form have access to this data?
You can create additional properties in the second form and you can pass the values from first form to second form.
Hope this gives some ideas for you.
private void button1_Click(object sender, EventArgs e)
{
Form2 frm = new Form2();
frm.MyName = "Pass my name here";
frm.Show();
}
public partial class Form2 : Form
{
public string MyName { get; set }
public Form2()
{
InitializeComponent();
}
}

Passing data and calling functions between forms without having to make them static - C#

I have the following static method that adds a selected product into an order.
public static void addToOrderFromPicture(string product, string qty, string _price)
{
//I've cut the code as it's not important to the question.
order.Add(product);
}
The products are displayed as Controls on a flow layout panel. The user will click the 'Add to Order' button on the control. This activates the following method.
private void btn_add_Click(object sender, EventArgs e)
{
if (Main.sessionInProgress == true)
{
OrderQty qty = new OrderQty(lbl_caseSize.Text.ToString(), lbl_wholesale.Text.ToString(), lbl_product.Text, lbl_volume.Text.ToString(), lbl_physical.Text, lbl_available.Text, lbl_oo.Text, lbl_inner.Text, lbl_pltQty.Text, lbl_repeat.Text);
qty.StartPosition = FormStartPosition.CenterParent;
DialogResult result = qty.ShowDialog();
if (result == DialogResult.Yes)
{
if (Main.roundCheck == true)
{
// MessageBox.Show(qty.qtyReturn.ToString());
qty.qtyReturn = autoRoundToCaseSize(qty.qtyReturn);
//MessageBox.Show(qty.qtyReturn.ToString());
Main.addToOrderFromPicture(lbl_product.Text.ToString(), qty.qtyReturn.ToString(), qty.priceReturn.ToString());
}
else
{
Main.addToOrderFromPicture(lbl_product.Text.ToString(), qty.qtyReturn.ToString(), qty.priceReturn.ToString());
}
btn_add.Text = "X";
btn_add.BackColor = Color.FromArgb(236, 112, 99);
}
}
}
The reason for the main function being static is so I can call it from this method. In Swift I would use a delegate to pass data between forms etc. However, I'm unsure on how to do this within C#.
Is there a similar method for passing data between forms as there is in Swift. How would I go about doing it? Or is there a way for me to call the method in Main without the need for it to be static.
EDIT: I don't think I've explained the forms etc very well so will try clear it up.
The addToOrderFromPicture method is contained within Main. This function adds products to the order list which is also static and contained within Main.
The 'btn_add_Click' method is contained in Product.cs which is a UserControl. This user control is displayed on a flowPanel which sits on the main form.
So the user clicks activates a function on Product.cs, this creates an instance of OrderQty.cs which is returns a qty to Product.cs - From Product.cs the addToOrder method within Main is called and the data like qty etc is passed to it.
So Product.cs -> OrderQty.cs -> Product.cs -> Main.cs
Your form is still accessible after you've called this.Close() and ShowDialog has returned, so you can do this:
OrderQty qty = new OrderQty(lbl_caseSize.Text.ToString(), lbl_wholesale.Text.ToString(), lbl_product.Text, lbl_volume.Text.ToString(), lbl_physical.Text, lbl_available.Text, lbl_oo.Text, lbl_inner.Text, lbl_pltQty.Text, lbl_repeat.Text);
qty.StartPosition = FormStartPosition.CenterParent;
DialogResult result = qty.ShowDialog();
if (result == DialogResult.Yes)
{
qty.addToOrderFromPicture(lbl_product.Text.ToString(), qty.qtyReturn.ToString(), qty.priceReturn.ToString());
}
Maybe you can keep your logic in a separate class instead of Main.
public class Service
{
public List<Product> Order { get; set; }
public void addToOrderFromPicture(string product, string qty, string _price)
{
Order.Add(product);
}
}
3 methods to do this.
First as the main window is created once use singleton pattern on it, declare a public static instance of form and access public methods,
Second pass a reference of main window to usercontrol and use its public methods.
Third add an event to usercontrol and hook handler in main window, whenever user clicks button, fire an event.

Detecting tab changed event

I am working on xamarin.forms. I need to detect the event of tab being changed either by swapping left or right or by clicking without using custom renderer
I tried below event but it is firing in both cases when child page being pushed or tab being changed. how can i get isolated event of tab being changed
public class MyTabbedPage : TabbedPage
{
public MyTabbedPage()
{
this.CurrentPageChanged += CurrentPageHasChanged;
}
protected void CurrentPageHasChanged(object sender,EventArgs e)
{
var pages= Navigation.NavigationStack;
if (pages.Count > 0)
{
this.Title = pages[pages.Count - 1].Title;
}
else
this.Title = this.CurrentPage.Title;
}
}
This issue I am facing is: In below screenshot part1 is Homepage(title="Diary") & part2 is Childpage(title="Homework") when I change tab & again come to first tab than navigationbar title getting changed "Homework" to "Diary"(Screeshot2)
As you are on your tabbed page already you can literally just do the following
public partial class MyTabbedPage : TabbedPage
{
public MyTabbedPage()
{
InitializeComponent();
CurrentPageChanged += CurrentPageHasChanged;
}
private void CurrentPageHasChanged(object sender, EventArgs e) => Title = CurrentPage.Title;
}
if you want to use the sender you can do the following
public partial class MyTabbedPage : TabbedPage
{
public MyTabbedPage()
{
InitializeComponent();
CurrentPageChanged += CurrentPageHasChanged;
}
private void CurrentPageHasChanged(object sender, EventArgs e)
{
var tabbedPage = (TabbedPage) sender;
Title = tabbedPage.CurrentPage.Title;
}
}
Or if you can elaborate on what you are trying to do exactly I can give a better answer as I do not know what it is that you are trying to do exactly
I don't think you can achieve what you want to do, at least not like this. The event behaves the way it does and as described: it is fired whenever the current page changes, also for children.
That being said, I think you should focus on implementing the functionality you want with the tools we have. I can't really deduce from your code what you are trying to do, but it looks like you want to change the title? When a tab is changed? Why not just make some kind of condition to only do it for certain pages? For example when the page is contained in the Children collection?

passing to a form which is already open

What I'm trying to do it load some information from a database.
To do this I open a form that lists everything that can be loaded.
When you click load I want to pass the ID back to the original form.
However I can't seem to be able to call a method in that form.
Any help would be appreciated.
I would flip this around:
Make the selection form into a modal dialog that is created and displayed by the form where you want to load something
Expose the selection made in the dialog through a property or method in the dialog form
This way the selection form will be decoupled from the caller, and can be reused wherever it makes sense without the need to modify it.
In the selection dialog form class:
public string GetSelectedId()
{
return whateverIdThatWasSelected;
}
In the calling form:
using(var dlg = new SelectionDialogForm())
{
if (dlg.ShowDialog() == DialogResult.OK)
{
DoSomethingWithSelectedId(dlg.GetSelectedId());
}
}
You could add a property to your form class and reference it from your other form.
eg.
public class FormA : Form
{
private string _YourProperty = string.empty;
public string YourProperty
{
get
{
return _YourProperty;
}
set
{
_YourProperty = value;
}
}
}
public class FormB : Form
{
public void ButtonClick(object sender, EventArgs args)
{
using (FormA oForm = new FormA)
{
if (oForm.ShowDialog() == DialogResult.OK)
{
string Variable = oForm.YourProperty;
}
}
}
You just need to set your property on a button click on form A then you can access it from form B
}
Why not create a public property for the selected item in the dialog form, something like this.
public int SelectedItemId {get;private set;}
//In your item selected code, like button click handler..
this.SelectedItemId = someValue;
Then just open the form as a Dialog
//Open the child form
using (var form = new ChildForm())
{
if (form.ShowDialog(this) == DialogResult.OK)
{
var result = form.SelectedItemId;//Process here..
}
}
The proper way to do this is to introduce a Controller class which is used by both forms. You can then use a property on the Controller, when that is set will trigger the NotifiyPropertyChanged event.
see INotifyPropertyChanged for more info

.net ASCX help with passining info & Hiding Div

Alright, I am trying to accomplish this: When a user clicks a button that is on a ascx web user control with text boses, it first displays a DIV that is hidden, this div contains a ascx web user control. Basically I want that web user control to grab what they typed in the boxes on the first web user control, and then apply to a SQL search from what the users type in the text boxes on the first page. Is this possible or do I need to rethink my strategy on this? I am programming in c# for the SQL statements.
It is possible.
You can define properties of the control which accepts the text input, and expose the values using direct field access, variables, or session variables; you can then use FindControl from within the newly displayed control, and, if found, utilise the now exposed properties to gather the values required.
For instance, your input control code-behind might look something like this:
partial class MyControl : UserControl
{
public string MyFieldValue
{
get { return MyFieldTextBox.Text; }
}
}
And in the next control, to use it, a little like this:
partial class MyControl : UserControl
{
protected void Page_Load(object sender, EventArgs e)
{
var myControl = Page.FindControl("MyControlInstanceName") as MyControl;
if (myControl != null)
{
var myFieldValue = myControl.MyFieldValue;
}
}
}
Is the 2nd user control embedded in the 1st or not?
If not, you can make anything available upwards between user controls by simply adding public properties to your user controls. This means they can then be accessed from the page level or the containing user control. For example, if I have UCA, UCB, UCC
UCA contains UCB and UCC is hidden.
UCB has the following property
public string UserEnteredName
{
get { return NameTextBox.Text; }
}
UCC has the following property and method
public string UserEnteredName { get; set; }
public BindResults()
{
UserEnteredLiteral.Text = UserEnteredName;
}
Then tie it together with UCA:
protected MyButton_Click(object sender, EventArgs e)
{
UCC.UserEnteredName = UCB.UserEnteredName;
... some logic herre.
UCC.BindResults();
}
You can also raise an event from UCB that can be responded to in UCA if your button or submit action exists in UCB.

Categories

Resources