I want to create a sort of side-window next to another window.
It should resize with the mainwindow and also move with it when I drag the mainwindow. How do I do this?
the first thing you do is to create your second window.
SecondWindow secondwindow;
Then you call the window directly next to your MainWindow.
secondwindow = new Secondwindow();
secondwindow.WindowStartupLocation = WindowStartupLocation.Manual;
secondwindow.Left = this.Left + this.Width;
secondwindow.Top = this.Top;
secondwindow.Height = this.Height;
secondwindow.Show();
If you want the second window to resize with your MainWindow (I guess just the height) type this in your
MainWindow - SizeChanged - event.
private void mainwindow_SizeChanged(object sender, SizeChangedEventArgs e)
{
if (secondwindow != null)
{
secondwindow.Left = this.Left + this.Width;
secondwindow.Top = this.Top;
secondwindow.Height = this.Height;
}
}
Same without the height-change for the LocationChanged.
private void mainwindow_LocationChanged(object sender, EventArgs e)
{
if (secondwindow != null)
{
secondwindow.Left = this.Left + this.Width;
secondwindow.Top = this.Top;
}
}
Related
I am trying to send a window to a screen, and place that window in the center of the screen. When the button is clicked, it send / close the window and change button content.
My first issue is I can open and close the Window, but only 1 time. The second time I receive:
System.InvalidOperationException: 'Cannot set Visibility or call Show, ShowDialog, or WindowInteropHelper.EnsureHandle after a Window has closed.'
Also, if the button is closed manually, it does not change the button content.
Finally, it does not place the window in the center of the screen. I try to place the window in the center of the screen using:
window.HorizontalAlignment = System.Windows.HorizontalAlignment.Center;
window.VerticalAlignment = VerticalAlignment.Center;
but this does not work, it place the window upper left corner.
Can anyone out there guide me on how this should be handled?
Window1 w1 = new Window1();
private void ShowByCoordinates(Window window, string screenName, int LeftTransform, int TopTransform)
{
if (button4.Content.ToString() == "Send")
{
Screen s0 = Screen.AllScreens.FirstOrDefault(s => s.DeviceName == screenName) ?? Screen.PrimaryScreen;
Rectangle bounds = s0.WorkingArea;
window.Left = bounds.X + LeftTransform;
window.Top = bounds.Y + TopTransform;
window.HorizontalAlignment = System.Windows.HorizontalAlignment.Center;
window.VerticalAlignment = VerticalAlignment.Center;
window.Show();
button4.Content = "Stop";
}
else
{
window.Close();
button4.Content = "Send";
}
}
private void Button4_Click(object sender, RoutedEventArgs e)
{
ShowByCoordinates(w1, "DISPLAY2", 1920, 0);
}
First, once you close the window, it's disposed and you can't show it again. Use Show() and Hide() instead.
When you set WindowStartupLocation to CenterScreen ther is a problem: after the window is shown any programmatical changes to its position will be ignored. So you can only do it once this way.
To do it manually, you need to set WindowStartupLocation to Manual and then set your window's Top and Left properties.
The next problem you'll have to consider is the fact that there may be multiple monitors. If you only need to center the window on the monitor set as primary in the system, then:
w.Left = (SystemParameters.WorkArea.Width - w.ActualWidth) / 2 + SystemParameters.WorkArea.Left;
w.Top = (SystemParameters.WorkArea.Height - w.ActualHeight) / 2 + SystemParameters.WorkArea.Top
is enough. If you want to center the window on the current monitor, then you'll need to do something like this:
(method from here):
public static void PostitionWindowOnScreen(Window window, double horizontalShift = 0, double verticalShift = 0)
{
Screen screen = Screen.FromHandle(new System.Windows.Interop.WindowInteropHelper(window).Handle);
window.Left = screen.Bounds.X + ((screen.Bounds.Width - window.ActualWidth) / 2) + horizontalShift;
window.Top = screen.Bounds.Y + ((screen.Bounds.Height - window.ActualHeight) / 2) + verticalShift;
}
To call it:
TestWindow w;
//....
w = new TestWindow();
w.WindowStartupLocation = WindowStartupLocation.Manual;
w.Closed += w_Closed;
//....
private void w_Closed(object sender, EventArgs e)
{
// to make sure there is no disposed window to access when user closes it manually
w = null;
// or:
// w = new TestWindow();
}
private void Button_ShowWindow_Click(object sender, RoutedEventArgs e)
{
if (w == null) return;
PostitionWindowOnScreen(w, 0, 0);
w.Show();
}
private void Button_HideWindow_Click(object sender, RoutedEventArgs e)
{
if (w == null) return;
w.Hide();
}
First, if you Close window, you cannot Show it again as already mentioned. You need to use Hide instead of Close.
To center your screen, just use this line:
this.WindowStartupLocation = WindowStartupLocation.CenterScreen;
I try to avoid the XY Problem by saying immediately what I want and then what I get. 😛
So, first of all, I minimize my MainWindow and thoroguh its NotifyIcon ContextMenu I want that my MainWindow reappears.
The problem: the MainWindow doesn't appear/show as Window, but it appears as Icon in the toolbar (see figure 2).
The code:
This is the TrayIcon initializer:
private void InitializeTrayIcon()
{
KyactusTrayIcon = new NotifyIcon();
KyactusTrayIcon.Icon = AppIcon;
KyactusTrayIcon.Visible = true;
KyactusTrayIcon.ContextMenu = new ContextMenu(new []
{
new MenuItem("Chiudi", ExitApplication),
new MenuItem("Mostra", ShowMainWindow),
});
ShowNotification(#"Ciao " + Globals.CurrentUser.Name + #"!", #"Benvenuto su Kyactus");
}
This is the delegate responsible to show the minimized MainWindow (not working at all):
private void ShowMainWindow(object sender, EventArgs e)
{
WindowState = WindowState.Normal;
Topmost = true;
Show();
Activate();
}
This is what happens when the MainWindow is minimized by clicking the [-] button (ie the Hide() method):
private void MainWindow_OnStateChanged(object sender, EventArgs e)
{
switch (this.WindowState)
{
case WindowState.Maximized:
ShowNotification("Bleah!", "Questo è proprio brutto! :(");
break;
case WindowState.Minimized:
Hide();
ShowNotification("Avviso", "L'applicazione è ora minimizzata qui");
break;
case WindowState.Normal:
break;
}
}
Step one. The method MainWindow_OnStateChanged will be invoked when click on [-]:
Step two. The window disappears (ok) and the Tray icon appears (ok). Then I click on 'Mostra' (translated as 'Show') and the ShowMainWindow delegate will be invoked
Step three. This is the final step, that is, what I do not expect. The MainWindos 'lives' as an Icon in the toolbar. But I can't see it as a Window.
Please note that I have not this problem when I close the window by clicking [X] instead of [-]. So, my suspect is the MainWindow's Window.State. I tried to restore it implementing the WindowState.Normal into the ShowMainWindow, but nothing.
Update: if is use WindowState.Maximized in the ShowMainWindow method,
I can see the window again, but it is maximized and this is bad and ugly.
Just change the order of operation when showing the window
private void ShowMainWindow(object sender, EventArgs e)
{
Show();
WindowState = WindowState.Normal;
Topmost = true;
Activate();
}
Simply,create some class-level integer variables and store the height,width and positioning values there.Then use them to get back the size of your window :
int height;
int width;
double left;
double top;
private void MainWindow_SizeChanged
{
height = this.Height;
width = this.Widthl
left = this.Left;
top = this.Top;
}
private void ShowMainWindow(object sender, EventArgs e)
{
this.Height = height;
this.Width = width;
this.Left = left;
this.Top = top;
}
I have a WPF custom control and I needs to open it from WinForm. I have followed all steps mentioned in http://weblogs.asp.net/jdanforth/open-a-wpf-window-from-winforms and Open WPF window in WindowsForm APP
But still it gives me an object reference not set to an instance of exceptions.
Winform:
private void button1_Click(object sender, EventArgs e)
{
var notificatioinapp = new WpfCustomControlLibrary1.Window1();
ElementHost.EnableModelessKeyboardInterop(notificatioinapp);
notificatioinapp.Show();
}
WPF custom control:
public partial class Window1 : Window
{
public Window1() : base()
{
InitializeComponent();
this.Closed += this.NotificationWindowClosed;
}
public new void Show()
{
this.Topmost = true;
base.Show();
this.Owner = System.Windows.Application.Current.MainWindow;
this.Closed += this.NotificationWindowClosed;
var workingArea = Screen.PrimaryScreen.WorkingArea;
this.Left = workingArea.Right - this.ActualWidth;
double top = workingArea.Bottom - this.ActualHeight;
foreach (Window window in System.Windows.Application.Current.Windows)
{
string windowName = window.GetType().Name;
if (windowName.Equals("NotificationWindow") && window != this)
{
window.Topmost = true;
top = window.Top - window.ActualHeight;
}
}
this.Top = top;
}
private void ImageMouseUp(object sender,
System.Windows.Input.MouseButtonEventArgs e)
{
this.Close();
}
private void DoubleAnimationCompleted(object sender, EventArgs e)
{
if (!this.IsMouseOver)
{
this.Close();
}
}
private void NotificationWindowClosed(object sender, EventArgs e)
{
foreach (Window window in System.Windows.Application.Current.Windows)
{
string windowName = window.GetType().Name;
if (windowName.Equals("NotificationWindow") && window != this)
{
// Adjust any windows that were above this one to drop down
if (window.Top < this.Top)
{
window.Top = window.Top + this.ActualHeight;
}
}
}
}
}
Appreciate any support.
Application.Current is Specific for WPF Application actually. So I think since you are trying to open WPF application from WinForms Application you need to initialize instance of WPF Application first before accessing it.
if ( null == System.Windows.Application.Current )
{
new System.Windows.Application();
}
If this doesn't work try setting Application.Current.MainWindow = this; in loaded event of WPF window.
This should do the fix.
EDIT :
private void button1_Click(object sender, EventArgs e)
{
if (null == System.Windows.Application.Current)
{
new System.Windows.Application();
}
var wpfwindow = new Window();
wpfwindow = new WpfCustomControlLibrary1.Window1();
ElementHost.EnableModelessKeyboardInterop(wpfwindow);
wpfwindow.Show();
}
suppose i have have two sdi form and when apps run then a sdi form show and from there i am showing another sdi form but the problem is i can drga any where the second sdi form which i do not want. in case of MDI form the mdi child form can not be drag out of mdi form boundary.so in my case i want to simulate the same thing. i want no other sdi form can not be drag out form my main sdi form's boundary. so just guide me how to do this.
i could guess that i have to work with form drag event and from there i have to check form top and left but need more suggestion.
private void Form1_Move(object sender, EventArgs e)
{
this.Location = defaultLocation;
}
i try to do it this way but it is not working.
public partial class Form2 : Form
{
Form1 _parent = null;
public Form2()
{
InitializeComponent();
}
public Form2(Form1 parent)
{
InitializeComponent();
_parent = parent;
}
private void Form2_Move(object sender, EventArgs e)
{
if((this.Location.X+this.Width) > _parent.Width)
{
this.Location = new System.Drawing.Point(_parent.ClientRectangle.Width-this.Width,this.Location.Y);
}
if ((this.Location.Y + this.Height) > _parent.Height)
{
this.Location = new System.Drawing.Point(_parent.ClientRectangle.Height - this.Height, this.Location.X);
}
if (this.Location.Y < 0)
{
this.Location = new System.Drawing.Point(this.Location.X);
}
if (this.Location.X < 0)
{
this.Location = new System.Drawing.Point(this.Location.Y);
}
}
}
please guide me where i made the mistake.
thanks
UPDATE
private void Form2_Move(object sender, EventArgs e)
{
int left = this.Left;
int top = this.Top;
if (this.Left < _parent.Left)
{
left = _parent.Left;
}
if (this.Right > _parent.Right)
{
left = _parent.Right - this.Width;
}
if (this.Top < _parent.Top)
{
top = _parent.Top;
}
if (this.Bottom > _parent.Bottom)
{
top = _parent.Bottom - this.Height;
}
this.Location = new Point(left, top);
}
I recomend to you follow the #ProgrammerV5 recomendation. But if you realy need to control the form movement, please see the use of Cursor.Clip property
here are some information: http://www.codeproject.com/Tips/375046/The-Cursor-Clip-Property
Also you may need to do a MouseCapture.
I am trying to open a (non decorated) childform at the upper right corner of my main form no matter if the main form is maximized or at it's normal size.
But no matter how I try I don't get it to open where I want it to.
I found a post that described how to open the form relative to another control in the form, but that didn't work either:
How to display a Modal form in a position relative to the a control in the parent window (opener)
Have tried to search for a few hours now on google for a solution, but either there's no answer (doubdfull) or I am not searching for the tight words combination (more likely).
Could anyone please either point me to a similar question, or help me how to achieve what I am hoping for?
Sounds to me you ought to be using a UserControl that you anchor to the top and right. But let's make a form work. You'll need to wire its Load event so you can move it into the right spot after it rescaled itself. Then you need the main form's LocationChanged and Resize events so you can keep the child form in the right spot.
So a sample program with boilerplate Form1 and Form2 names and a button on Form1 to display the child could look like this:
public partial class Form1 : Form {
public Form1() {
InitializeComponent();
this.button1.Click += button1_Click;
this.Resize += this.Form1_Resize;
this.LocationChanged += this.Form1_LocationChanged;
}
Form child;
private void button1_Click(object sender, EventArgs e) {
if (child != null) return;
child = new Form2();
child.FormClosed += child_FormClosed;
child.Load += child_Load;
child.Show(this);
}
void child_FormClosed(object sender, FormClosedEventArgs e) {
child.FormClosed -= child_FormClosed;
child.Load -= child_Load;
child = null;
}
void child_Load(object sender, EventArgs e) {
moveChild();
}
void moveChild() {
child.Location = this.PointToScreen(new Point(this.ClientSize.Width - child.Width, 0));
}
private void Form1_Resize(object sender, EventArgs e) {
if (child != null) moveChild();
}
private void Form1_LocationChanged(object sender, EventArgs e) {
if (child != null) moveChild();
}
}
Try something like that:
private void button1_Click(object sender, EventArgs e)
{
ChildForm win = new ChildForm();
int screenHeight = Screen.PrimaryScreen.WorkingArea.Height;
int screenWidth = Screen.PrimaryScreen.WorkingArea.Width;
Point parentPoint = this.Location;
int parentHeight = this.Height;
int parentWidth = this.Width;
int childHeight = win.Height;
int childWidth = win.Width;
int resultX = 0;
int resultY = 0;
if ((parentPoint.X + parentWidth + childWidth) > screenWidth)
{
resultY = parentPoint.Y;
resultX = parentPoint.X - childWidth;
}
else
{
resultY = parentPoint.Y;
resultX = parentPoint.X + parentWidth;
}
win.StartPosition = FormStartPosition.Manual;
win.Location = new Point(resultX, resultY);
win.Show();
}
I think you should try something like this:
private void buttonOpen_Click(object sender, EventArgs e)
{
Form2 frm2 = new Form2();
frm2.Show();
//"this" is the parent form
frm2.DesktopLocation = new Point(this.DesktopLocation.X + this.Width - frm2.Width, this.DesktopLocation.Y);
}
Simple, easy, and works (for me).