Show Form side-by-side owner Form - c#

I have a form. If someone presses a button, I want to show a second form "attached" to the original form, meaning that its left side is at the right side of the original form and they have the same height. In other words: they touch each other.
An answer seems to be Open Form next to Parent Form
However, there is a gap between the images. I want them to be exactly next to each other
main form:
private void ShowOtherForm()
{
using (var form = new OtherForm())
{
var dlgResult = form.ShowDialog(this);
ProcessDlgResult(dlgResult);
}
}
Other form, event handler Load
private void FormLoad(object sender, EventArgs e)
{
// show this form attached to the right side of my owner:
this.Location = new Point(this.Owner.Right, this.Owner.Top);
this.Height = this.Owner.Height;
}

Try to use ClientSize and Location
private void Form2_Load(object sender, EventArgs e)
{
var owner = this.Owner;
Location = new Point(owner.Location.X + owner.ClientSize.Width, owner.Location.Y);
Height = owner.Height;
}

Related

Child form opens on first screen when user has dragged the main form to the second screen

My Application's Main Form opens on the Laptop (main screen) when it starts. Then user drags it to the other screen (for big display), and opens a child form that is displayed on the Laptop screen rather than Application's Main Form (big display). I want the child form to open on the screen where Application's Main Form is open at the moment.
I tried following options, but they only worked in debug mode and did not work in production
ChildForm.ShowDialog((IWin32Window)this.MainForm);
ChildForm.ShowDialog(formMainInstance);
ChildForm.Show(formMainInstance);
I know about FormStartPosition.CenterParent, but it's not the right option for me. How can I do this?
As far as I know you have 3 options:
Use FormStartPosition.CenterScreen;
private void button2_Click(object sender, EventArgs e)
{
Form2 child = new Form2();
child.StartPosition = FormStartPosition.CenterScreen;
child.ShowDialog(this);
}
Use FormStartPosition.CenterParent
private void button2_Click(object sender, EventArgs e)
{
Form2 child = new Form2();
child.StartPosition = FormStartPosition.CenterParent;
child.ShowDialog(this);
}
}
Use FormStartPosition.Manual and pass a point
private void button2_Click(object sender, EventArgs e)
{
Form2 child = new Form2();
child.StartPosition = FormStartPosition.Manual;
child.Location = new System.Drawing.Point(0, 0);
child.ShowDialog(this);
}
The following code worked for me.
var screen = Screen.FromControl(childFormInstance);
var MainFormScreen = Screen.FromControl(_formMainInstance);
ChildForm.Left = MainFormScreen.WorkingArea.Left + 120;
ChildForm.Top = MainFormScreen.WorkingArea.Top + 120;
ChildForm.ShowDialog();
First I query which screen the child form want to open
Then I query which screen my Main form is currently open
Then I overwrite the child form screen

Why doesn't the child form appear on the same screen as the parent form?

Update
I accepted Rufus L's answer with a few mods, Relevant code follows
public partial class ClsOfficeRibbonFooTab
{
private void FooTab_Load(object sender, RibbonUIEventArgs e)
{
.
.
.
}
private void CheckResolution()
{
// set the left position so that the expanded version of the form fits on the screen
Screen screen = Screen.FromHandle(new IntPtr(Globals.ThisAddIn.Application.ActiveWindow.Hwnd));
if (screen.Bounds.Width < 1360 || screen.Bounds.Height < 768)
{
throw new FormatException(String.Format("The {0} is supported on screens with a resolution of 1360 by 768 or greater. Your screen is {1} by {2}", "Some caption text", screen.Bounds.Width, screen.Bounds.Height));
}
}
private void ObjButtonFoo_Click(object sender, RibbonControlEventArgs e)
{
using (ClsFormFoo objFormFoo = new ClsFormFoo(parentWindow: Globals.ThisAddIn.Application.ActiveWindow))
{
CheckResolution();
objFormFoo.ShowDialog();
}
}
}
public partial class ClsFormFoo : Form
{
// This form is a fixed dialog with a flyout on the right side.
// expandedWidth is a const set to the max width of this fixed dialog (i.e., the dialog with the flyout extended)
const int expandedWidth = 1345;
public ClsFormFoo(Microsoft.Office.Interop.Word.Window parentWindow)
{
InitializeComponent();
Top = parentWindow.Top;
}
private void ClsFormFoo_Load(object sender, EventArgs e)
{
Screen screen = Screen.FromHandle(new IntPtr(Globals.ThisAddIn.Application.ActiveWindow.Hwnd));
// set the left position so that the expanded version of the form fits on the screen for all legal resolutions
int halfScreenWidth = (int)(screen.WorkingArea.Width / 2);
// This form is a fixed dialog with a flyout on the right side.
// expandedWidth is a const set to the max width of this fixed dialog (i.e., the dialog with the flyout extended)
int halfFormWidth = (int)(expandedWidth / 2);
this.Left = screen.Bounds.Left + ((int)(halfScreenWidth - halfFormWidth));
}
}
Original Post
My VSTO Add-In provides a ribbon button that when clicked, calls ObjButtonFoo_Click, which in turn, shows a ClsFormFoo form (See Code below). ObjButtonFoo_Click includes code to create an IWin32Window owner value representative of Word to pass to ShowDialog.
On a multiple-monitor setup, I would expect that objFormFoo would appear on the same monitor on which Word itself is displayed. However, when I bring up Word on a secondary monitor and cause ObjButtonFoo_Click to be executed, objFormFoo appears on the Primary monitor
What do I do to make objFormFoo appear on the same monitor that Word itself is displayed on whether its the primary monitor or not?
Note: I verified that winWordMain is populated, i.e., its not null. See winWordMain below
Code
private void ObjButtonFoo_Click(object sender, RibbonControlEventArgs e)
{
NativeWindow winWordMain = new NativeWindow();
winWordMain.AssignHandle(new IntPtr(Globals.ThisAddIn.Application.ActiveWindow.Hwnd));
IntPtr(Globals.ThisAddIn.Application.ActiveWindow.Hwnd);
using (ClsFormFoo objFormFoo = new ClsFormFoo()
{
objFormFoo.ShowDialog(winWordMain);
}
winWordMain.ReleaseHandle();
}
winWordMain
I don't have VSTO to test this, but it seems to me that you could just get the position of the ActiveWindow that you're using as the parent, and then use that as a reference for positioning your child form:
private void allRootsWithChilds_CheckedChanged(object sender, EventArgs e)
{
var winWordMain = new NativeWindow();
var parent = Globals.ThisAddIn.Application.ActiveWindow;
winWordMain.AssignHandle(new IntPtr(parent.Hwnd));
using (var objFormFoo = new ClsFormFoo())
{
// Set the Left and Top properties so this form is centered over the parent
objFormFoo.Left = parent.Left + (parent.Width - objFormFoo.Width) / 2;
objFormFoo.Top = parent.Top + (parent.Height - objFormFoo.Height) / 2;
objFormFoo.ShowDialog(winWordMain);
}
winWordMain.ReleaseHandle();
}
You just need to set the StartPosition property of your form to the FormStartPosition.CenterParent value:
loginForm.StartPosition = FormStartPosition.CenterParent;
loginForm.ShowDialog(parentWindowdle);
I used to make a simple screensaver on C#. I used the following code to open the screensaver on the desired screen or on all of them.
You have to take bounds from the desired screen and pass it to the form.
// Constructor
public NameForm(Rectangle bounds)
{
InitializeComponent();
this.Bounds = bounds;
}
// In my case, this is opening the screensaver on all screens
foreach (Screen screen in Screen.AllScreens)
{
NameForm form = new NameForm (screen.Bounds);
form.Show();
}

How to bring to the front form with focus in textbox or any other control in that form

I have a Split Container that have Panel 1 (left, with menu) and Panel 2 (right, where I load the child forms), in the menu I have a button that opens a new child form. It only allows one instance of the window at a time, not duplicates.
The last form that I open always stays in front of the Panel 2, even when the focus is on the form in back.
How do I bring the back from to front when I focus a control in it?
Function that open the form
private void AddFormInPanel(object formChild)
{
Form fh = formChild as Form;
Form existe = Application.OpenForms.OfType<Form>().Where(pre => pre.Name == fh.Name.ToString()).SingleOrDefault<Form>();
if (existe == null)
{
fh.TopLevel = false;
this.splitContainer.Panel2.Controls.Add(fh);
this.splitContainer.Panel2.Tag = fh;
fh.BringToFront();
fh.Show();
}
}
Call to the function
private void buttonForm1_Click(object sender, EventArgs e)
{
AddFormInPanel(new Form1());
}
private void buttonForm2_Click(object sender, EventArgs e)
{
AddFormInPanel(new Form2());
}
In this example, i Have focused the textbox Name, but the form still in back.
Example: https://imgur.com/6jsWIgi

Using custom event to draw shapes in another form c#

I have 2 forms, Main Form & ModalBox.
In Main Form I have a button that when clicked draws a shape depending on the selected index of the comboBox.
// Create Rectangle or Ellipse
public void buttonAdd_Click(object sender, EventArgs e)
{
SolidBrush sb = new SolidBrush(Color.Red);
Graphics g = panel1.CreateGraphics();
if (shapeSizeControl1.comboBoxShapeSelection.SelectedIndex == 0)
{
g.FillRectangle(sb, Convert.ToSingle(shape.X), Convert.ToSingle(shape.Y), Convert.ToSingle(shape.Width), Convert.ToSingle(shape.Height));
}
else if (shapeSizeControl1.comboBoxShapeSelection.SelectedIndex == 1)
{
g.FillEllipse(sb, Convert.ToSingle(shape.X), Convert.ToSingle(shape.Y), Convert.ToSingle(shape.Width), Convert.ToSingle(shape.Height));
}
}
In the ModalBox form I have an Ok button which should do the same thing as the button in Main Form but it doesn't because I have no idea how to program it to do so.
What i've tried..
Copying the same code from Main Form buttonAdd_Click into ModalBox buttonOk_Click. Bad idea because I have to instantiate a new Main form to get the panel1 variable. If I do that nothing happens. Why? I'm not sure an explanation would be great.
Creating a custom event so when the ModalBox Form opens, once I press the ok button since its subscribed It will draw the shape. 1 problem I have no idea where to call the event and check for null because the button is on the second form so If I call the custom event in the first form I have no where to call the event and do null check.
Goal
My goal is to figure out how to add shapes in the Main Form from the ModalBox Form using the Ok button in the ModalBox Form.
Just create a method DrawShape() in the main form that draws your shapes and call it from the button click.
// Main Form
private void button1_Click(object sender, EventArgs e)
{
DrawShape();
}
Now create the modal form and set the owner
// Main form
private void button2_Click(object sender, EventArgs e)
{
var dlg = new ModalBox();
if (dlg.ShowDialog(this)==DialogResult.OK)
{
// do things
}
}
Finally in the modal form call the DrawShape() function
// Modal form
private void button1_Click(object sender, EventArgs e)
{
var parent = this.Owner as MainForm;
parent.DrawShape();
}

create custom datagridview popup control with close(X) button

I want to create a control in my windows form application. This control contains some data as datagridview control. But my requirement is to show this control as popup control. Below is the screen shot of this.
Please help me to overcome this problem. Any help appreciated.
NOTE:- I want my form same as above screen shot means i want only my datagridview to be visible and i don't want form header and its border.
You can create your own PopupForm with following code.
To remove the borders use FormBorderStyle
this.FormBorderStyle = System.Windows.Forms.FormBorderStyle.None;
Then place your DataGridView and your Button like that:
Use the DataGridView's Dock-Property to fill the form:
yourDataGridViewControl.Dock = DockStyle.Fill;
Place your button in the right upper corner and create an EventHandler to catch the Click-Event:
button_close.Click += button_close_Click;
private void button_close_Click(object sender, EventArgs e)
{
this.Close();
}
In your Mainform:
Create following two fields:
PopupForm popup; //PopupForm is the name of your Form
Point lastPos; //Needed to move popup with mainform
Use following code to show your popup at the button's location:
void button_Click(object sender, EventArgs e)
{
if(popup != null)
popup.Close(); //Closes the last open popup
popup = new PopupForm();
Point location = button.PointToScreen(Point.Empty); //Catches the position of the button
location.X -= (popup.Width - button.Width); //Set the popups X-Coordinate left of the button
location.Y += button.Height; //Sets the location beneath the button
popup.Show();
popup.TopMost = true; //Is always on top of all windows
popup.Location = location; //Sets the location
if (popup.Location.X < 0) //To avoid that the popup
popup.Location = new Point(0, location.Y); //is out of sight
}
Create an EventHandler to catch the MainForm's Move-Event and use following method to move your popup with your MainForm (Credit goes to Hans Passant):
private void Form1_LocationChanged(object sender, EventArgs e)
{
try
{
popup.Location = new Point(popup.Location.X + this.Left - lastPos.X,
popup.Location.Y + this.Top - lastPos.Y);
if (popup.Location.X < 0)
popup.Location = new Point(0, popup.Location.Y);
}
catch (NullReferenceException)
{
}
lastPos = this.Location;
}
Here you can get the Demoproject: LINK

Categories

Resources