Main form used as MDI parent form and it has got DevExpress.XtraBars.Bar and it contains a DevExpress.XtraBars.BarSubItem as a menu. When I click menu item, child form mounts this main form, an open file dialog is shown, selected an XML file and datas from XML file fill textbox controls. These textbox controls from child form are located in group control box.
I tried too many trials like this:
private void bbiHakimIsListesiBilgileri_ItemClick(object sender, DevExpress.XtraBars.ItemClickEventArgs e)
{
if (ActiveMdiChild != null && ActiveMdiChild.Name == "_child_form")
{
var h = Control; // I don't know how I access GroupBox Control where located from child form.
GetXMLDatas(h);
}
else
{
var frm = new _child_form { MdiParent = this, Dock = DockStyle.Fill };
frm.Show();
var h = Control; // I don't know how I access GroupBox Control where located from child form.
GetXMLDatas(h);
}
}
Here is the GetXMLDatas method:
private void GetXMLDatas(Control k)
{
ofd.Title = #"Select an XML file.";
ofd.Filter = #"(*.xml)|*.xml|All files(*.*)|*.*";
ofd.FilterIndex = 1;
ofd.InitialDirectory = Tools.documents;
ofd.Multiselect = false;
ofd.ShowDialog();
if (string.IsNullOrEmpty(ofd.FileName)) return;
var data = XElement.Load(ofd.FileName).Descendants("field");
foreach (var f in Fields(k))
{
var value = data.FirstOrDefault(v => v.Attribute("key")?.Value == f.Name);
if (value != null) f.Text = value.Attribute("value")?.Value;
}
}
I don't know how I access GroupBox Control where located from child form in main form.
EDIT - 1: As a result, I want to find a groupbox control on an mdi child form from code on the mdi parent form. I have 3 mdi child form and two child forms have a groupbox. I want to reach these. Because if I manage to reach these two, I think, I can reach under these groupbox
EDIT - 2: After GuidoG's answer, I tried these:
MDI Child form name ise FormMDIChild_1. I added this code to FormMDIChild_1 text:
public GroupBox GetGroupBox()
{
return groupBox1;
}
Later, I added this code to mdi parent form called main form:
if (ActiveMdiChild is FormMDIChild_1)
{
GroupBox myGroupBox = (FormMDIChild_1)GetGroupBox();
}
But it gives errors like the screenhot:
Screenshot - 1
Screenshot - 2
Screenshot - 3
quick and dirty method :
create a method on each MDI Child form like this :
// suppose this mdi child is called FormMDIChild_1
public GroupBox GetGroupBox()
{
return Groupbox1;
}
in MDI Parent do this :
if (ActiveMdiChild is FormMDIChild_1)
{
GroupBox myGroupBox = ((FormMDIChild_1)ActiveMdiChild).GetGroupBox();
}
Better solution :
Create an MDI Child and call it for example FormBaseMDIChild
On this FormBaseMDIChild create a virtual method
public virtual GroupBox GetGroupBox()
inherit all other MDI Childs forms from FormBaseMDICHild and override the method GetGroupBox()
In MDI Parent do this
myGroupBox = ((FormBaseMDICHild)ActiveMdiChild).GetGroupBox();
Related
I am creating a C# .Net 4.8 Winform app with one MDI Form. This MDI Form has several panels and a split container.
When adding a childform I use the following code:
frm.Text = formTitleText;
frm.MdiParent = this;
frm.TopLevel = false;
frm.FormBorderStyle = FormBorderStyle.None;
frm.Dock = DockStyle.Fill;
panelDeskTop.Controls.Add(frm);
panelDeskTop.Tag = frm;
frm.BringToFront();
lblTitleChildForm.Text = $"{frm.Text}({this.MdiChildren.Length})";
frm.Show();
The form shows in the panel, but is not added as a MDI Child. The Parent (This) is the MDI Parent and has property of IsMDIContainer. So the this.MdiChildren.Length is always 0.
Not sure why?
Thanks in advance.
It's expected. You've set another parent for it: panelDeskTop.Controls.Add(frm);.
Consider the following points:
An MDI parent form has a control of type MdiClient. When you set MdiParent of a form, basically you are adding it to the controls collection of the MdiClient control.
When you ask MdiChildren of an MDI parent form, it returns the child forms of the MdiClient.
A form or a control, can have only one parent at time, and when you add it to controls collection of new parent, it will be removed from controls collection of the old parent.
Now I believe, it's clearer:
frm.MdiParent = this;
...
...
panelDeskTop.Controls.Add(frm);
The last line, removes the form from MdiChildren of the parent. That's why the array is empty.
Do you really need MDI?
It looks like you don't need MDI. If the child form is gonna fill the main panel without showing titlebar, then it basically means it doesn't need an mdi parent. Just make it a non-toplevel and add it to the controls collection of the main panel and show it.
Resizable sidebar for MDI parent
If you want have a resizable sidebar for MDI parent, then it's enough to Dock a panel and the splitter to left of the parenr, and then the right side will be occupied by the MdiClient. For example:
var mdiParent = new Form() { Size = new Size(700, 450), Text = "parent" };
mdiParent.Load += (obj, args) =>
{
mdiParent.IsMdiContainer = true;
mdiParent.Controls.Add(new Splitter()
{ Dock = DockStyle.Left, BackColor = Color.White, Width = 8 });
mdiParent.Controls.Add(new Panel()
{ Dock = DockStyle.Left, BackColor = Color.Black });
var child1 = new Form()
{ MdiParent = mdiParent, Text = "child1", Size = new Size(400, 300) };
var child2 = new Form()
{ MdiParent = mdiParent, Text = "child2", Size = new Size(400, 300) };
child1.Show();
child2.Show();
};
mdiParent.ShowDialog();
In my c# program it contains mainForm and user-control1 which has buttons , when I press a user control1 button I need it to open branchForm but inside mainForm while IsMdiContainer is true I tried many ways and solutions but not working.
In button in mainForm this code below works for me but I need it from user control button.
branchForm newMDIChild = new branchForm();
newMDIChild.TopLevel = true;
newMDIChild.MdiParent = this;
newMDIChild.Show();
As I understand you code will be like this :
UserControl code
First you have to define the Parent
public mainForm main
{
get
{
var parent = Parent;
while (parent != null && (parent as mainForm) == null)
{
parent = parent.Parent;
}
return parent as mainForm;
}
}
In Button Add this code
branchForm newMDIChild = new branchForm();
newMDIChild.TopLevel = true;
newMDIChild.MdiParent = main;
newMDIChild.Show();
I have a form page with text boxes and data grid view and other forms that contain a tab control. I want to add the first form tab in the second form. I tried to write the code for the form to appear but it is larger than the tab container and doesn't fit. Only half of the form appears.
This is my code:
private void tcMainPage_SelectedIndexChanged(object sender, EventArgs e)
{
if (tcMainPage.SelectedIndex == 0)
{
GTOWN.PrintingPage BookInfo = new PrintingPage();
BookInfo.TopLevel = false;
BookInfo.FormBorderStyle = FormBorderStyle.None;
BookInfo.Dock = DockStyle.Fill;
tpSearch.Controls.Add(BookInfo);
BookInfo.Show();
}
}
this is the form
and that is what appears
Set your main FORM as a Container.
yourForm.IsMdiContainer = true;
Then add the child form to the tabPage:
private void tcMainPage_SelectedIndexChanged(object sender, EventArgs e)
{
if (tcMainPage.SelectedIndex == 0)
{
PrintingPage newFrm = new PrintingPage
{
MdiParent = this,
// This set the form parent as the tabClicked
Parent = tcMainPage.TabPages[0]
};
newFrm.Show();
}
}
my tab form work good in the same code
thank you all my code was correct but the problem was in tab property i deleted the tab and add another one and the code is working now
thank you
I face this issue and I create this if may help
public void addform(TabPage tp, Form f)
{
f.TopLevel = false;
//no border if needed
f.FormBorderStyle = FormBorderStyle.None;
f.AutoScaleMode = AutoScaleMode.Dpi;
if (!tp.Controls.Contains(f))
{
tp.Controls.Add(f);
f.Dock = DockStyle.Fill;
f.Show();
Refresh();
}
Refresh();
}
Forms are top-most objects and cannot be placed inside of other containers.
You may want to refactor your code so that the items on your Form are on a UserControl instead. At that point you can then add that UserControl to both a Form and a TabControl
public UserControl myControl(){ /* copy your current view code here */}
public Form myForm(){
Controls.Add(new myControl());
}
public Form myTabbedForm(){
var tabControl = new TabControl();
var page1 = new TabPage();
page1.Controls.Add(new myControl());
tabControl.TabPages.Add(page1);
this.Controls.Add(tabControl);
}
I want to show jquery lightbox style model dialog in c# windows form. My dialog box will appear from the MDI child form button's Click event.How I do that ? Please help me.
If what you mean is to mask the parent form, then there is no simple way to do this afaik, what I've done is create a transparent form on top of the parent and then open another custom form as a dialog on top of the fake mask window.
something like this, where window is your popup and owner the form that is going to be masked:
Mask = new LayerWindow();
Mask.Show(owner);
window.Show(Mask);
this is what I'm using as a mask:
public class LayerWindow : Form
{
public LayerWindow()
{
FormBorderStyle = FormBorderStyle.None;
StartPosition = FormStartPosition.Manual;
TransparencyKey = Color.Fuchsia;
base.BackColor = Color.Black;
Opacity = 0.50;
ShowInTaskbar = false;
}
public void Show(Control parent)
{
if (parent == null)
throw new ApplicationException("No parent provided");
var container = parent.FindForm();
if (container == null)
throw new ApplicationException("No parent Form found. Make sure that the control is contained in a form before showing a popup.");
Location = PointToScreen(container.Location);
Bounds = container.Bounds;
Owner = container;
Owner.Enabled = false;
base.Show(container);
}
public void Unmask()
{
if (Owner != null)
Owner.Enabled = true;
Hide();
}
I'm trying to get all controls in a winform disabled at the Load event.
I have a form (MDI) which loads a Login Form. I want to disable the controls behind the Login Form to only let the user enter his username and password, and then if the user is valid re-enable the controls again.
Just show the login form as a modal dialog, i.e., frm.ShowDialog( ).
Or, if you really want to disable each control, use the Form's Controls collection:
void ChangeEnabled( bool enabled )
{
foreach ( Control c in this.Controls )
{
c.Enabled = enabled;
}
}
I suggest doing it this way instead of simply setting the Form's Enabled propery because if you disable the form itself you also disable the tool bar buttons. If that is ok with you then just set the form to disabled:
this.Enabled = false;
However, if you are going to do this you may as well just show the login prompt as a modal dialog :)
Simple Lambda Solution
form.Controls.Cast<Control>()
.ToList()
.ForEach(x=>x.Enabled = false);
Container like Panel control that contains other controls
then I used queue and recursive function get all controls.
for (Control control in GetAllControls(this.Controls))
{
control.Enabled = false;
}
public List<Control> GetAllControls(Control.ControlCollection containerControls, params Control[] excludeControlList)
{
List<Control> controlList = new List<Control>();
Queue<Control.ControlCollection> queue = new Queue<Control.ControlCollection>();
queue.Enqueue(containerControls);
while (queue.Count > 0)
{
Control.ControlCollection controls = queue.Dequeue();
if (controls == null || controls.Count == 0)
continue;
foreach (Control control in controls)
{
if (excludeControlList != null)
{
if (excludeControlList.SingleOrDefault(expControl => (control == expControl)) != null)
continue;
}
controlList.Add(control);
queue.Enqueue(control.Controls);
}
}
return controlList;
}
Just for some fun with linq, because you can.....
What you could do is create a "BatchExecute" extension method for IEnumerable and update all your controls in 1 hit.
public static class BatchExecuteExtension
{
public static void BatchExecute<T>(this IEnumerable<T> list, Action<T> action)
{
foreach (T obj in list)
{
action(obj);
}
}
}
Then in your code....
this.Controls.Cast<Control>().BatchExecute( c => c.enabled = false);
Cool.
I agree that ShowDialog is the way to go, but to answer the original question, you can do this if you want to disable all controls:
foreach (Control c in this.Controls)
{
c.Enabled = false;
}
As Ed said, showing the form as a modal dialog will do what you want. Be sure to check the dialog result returned from ShowDialog in case they cancel it instead of clicking login.
But if you really want to disable all the controls on the form then you should be able to just disable the form itself, or some other parent control like a panel that has all controls in it. That will disable all child controls. This will also allow the child controls to go back to their previous state when the parent control is enabled again.
Trying the ShowDialog show this exception:
Form that is not a top-level form cannot be displayed as a modal dialog box. Remove the form from any parent form before calling showDialog.
What im doing is this:
private void frmControlPanel_Load(object sender, EventArgs e)
{
WindowState = FormWindowState.Maximized;
ShowLogin();
//User = "GutierrezDev"; // Get user name.
//tssObject02.Text = User;
}
private void ShowLogin()
{
Login = new frmLogin
{
MdiParent = this,
Text = "Login",
MaximizeBox = false,
MinimizeBox = false,
FormBorderStyle = FormBorderStyle.FixedDialog,
StartPosition = FormStartPosition.CenterScreen
};
Login.ShowDialog();
}