How do I force my window to re-size? - c#

I have an auto-sized application user control in WPF (Height="Auto" Width="Auto"). When a bunch of elements inside it are resized, the windows stays the same rendered size. How do I force it to resize? I have tried this line Application.Current.MainWindow.SizeToContent = SizeToContent.WidthAndHeight; in the function that resizes the components inside the window. The compiler gives me an error that there is no object associated with this call. I have tried this line MainWindowBorder.Height = Double.NaN; to trick it to resize. No luck either.

Use SizeToContent in XAML
SizeToContent="WidthAndHeight"
https://msdn.microsoft.com/en-us/library/system.windows.window.sizetocontent%28v=vs.110%29.aspx?f=255&MSPPError=-2147217396

If all the inside controls can be resized but the only one thing to resize is Window, How about this simple approach? Hope this helps..
int mycurrentscreenwidth = 1366;
int mycurrentwindowwidth = 1366;
var screen = System.Windows.Forms.Screen.PrimaryScreen.Bounds;
var screenwidth = screen.Width;
if (Convert.ToInt32(screenwidth) < 1366)
{
double calculate_scalefactor= Convert.ToInt32(screenwidth) / (double)mycurrentscreenwidth;
double newwidth_tobescaled = mycurrentwindowwidth * calculate_scalefactor;
this.Width = newwidth_tobescaled;
}

To obtain the window of your current user control, see:
Access parent window from User Control
Then use:
Window yourParentWindow = Window.GetWindow(userControl);
yourParentWindow.SizeToContent = SizeToContent.WidthAndHeight;

Related

Dynamically resize WinForms controls when Form is resized

I have a WinForms project on which I would like all of the controls to grow proportionally along with the form as the form is resized. This is what the form looks like in normal state: Normal State Form
I have tried setting the Anchor properties to their appropriate values given the location of each control on the form, and while it does move the controls, they remain the same size. I tried using the AutoSize property, but also to no avail. Here is what the form looks like after being maximized with the Anchor properties set: Maximized Form
I also tried using a formula from Shaun Halverson to dynamically resize everything but it does not relocate the control properly, and I can't seem to figure out why. Here is the code I used to try and resize dynamically:
private void Main_Load(object sender, EventArgs e)
{
originalFormSize = new Rectangle(this.Location.X, this.Location.Y, this.Size.Width, this.Size.Height);
submitBtnOriginal = new Rectangle(submitButton.Location.X, submitButton.Location.Y, submitButton.Width, submitButton.Height);
}
private void Main_Resize(object sender, EventArgs e)
{
resizeControl(submitBtnOriginal, submitButton);
}
private void resizeControl(Rectangle r, Control c)
{
float xRatio = (float)(this.Width) / (float)(originalFormSize.Width);
float yRatio = (float)(this.Height) / (float)(originalFormSize.Height);
int newWidth = (int)(r.Width * xRatio);
int newHeight = (int)(r.Height * yRatio);
int newX = (int)(r.Width * xRatio);
int newY = (int)(r.Height * yRatio);
c.Location = new Point(newX, newY);
c.Size = new Size(newWidth, newHeight);
}
When I run this code, it moves the button to the opposite corner of the form, but it resizes it properly.
This would obviously be quite redundant given that I have to get an original size for every control I want to resize, but I would be fine with that if I could get dynamic resizing to work. I am surprised that this is not a more common problem, and I couldn't find hardly anything on this specific topic other than to use the Anchor and Dock properties. Is there an easy way to do this that I am missing? Is this a more difficult problem than it seems?
Put TextBox anchor property values as Top, Bottom, Left, Right and resize the form. That should work.

Show secondary window center of main window in UWP

I started using multiple windows in UWP and need to display secondary windows center of screen or at least center of parent window.
I found nothing relevant about how to specify where to show additional windows on the screen, other than Window.Current.Bounds property.
Here is the simplified version of the method that I am using to create additional windows. The method signature is: CreateFrameWindow(Size size, Type pageType, object parameter)
CoreApplicationView newWindow = CoreApplication.CreateNewView();
ApplicationView newView = null;
bool result = await newWindow.Dispatcher.TryRunAsync(CoreDispatcherPriority.Normal, () =>
{
Frame frame = new Frame();
frame.Navigate(pageType, parameter);
Window.Current.Content = frame;
Window.Current.Activate();
newView = ApplicationView.GetForCurrentView();
});
result = await ApplicationViewSwitcher.TryShowAsStandaloneAsync(newView.Id);
newView.TryResizeView(size);
The TryResizeView works fine as long as the secondary window has enough space to resize based on its current location on the screen. I want to enable resize up to the maximum available size (size of window when it is maximized) and place it to the center of the screen. If this is not possible, placing to the center of the parent or main window is acceptable.
Show secondary window center of main window in UWP
CoreApplicationView does not provide api to set the view position manually. For your requirement please try to use AppWindow to archive this feature. And AppWindow has RequestMoveRelativeToDisplayRegion method that position the window in the specified display region at the specified offset. For more please refer official code sample scenario 5
Update
If you want to make your new window display in the center, you need know your windows size before, and calculate X Y value for RequestMoveRelativeToDisplayRegion method.
X = (1920-W)/2 //1920 is Horizontal Resolution W is the new window's width
Y = (1080-H)/2 //1080 is Vertical Resolution H is the new window's height
For get current display resolution please refer this case link
var bounds = ApplicationView.GetForCurrentView().VisibleBounds;
var scaleFactor = DisplayInformation.GetForCurrentView().RawPixelsPerViewPixel;
var size = new Size(bounds.Width*scaleFactor, bounds.Height*scaleFactor);
For AppWindow I'm using...
//Set custom window size
Windows.UI.WindowManagement.Preview.WindowManagementPreview.SetPreferredMinSize(appWindow, new Size(500, 500));
appWindow.RequestSize(new Size(500, 500));
DisplayRegion displayRegion = ApplicationView.GetForCurrentView().GetDisplayRegions()[0];
double displayRegionWidth = displayRegion.WorkAreaSize.Width;
double displayRegionHeight = displayRegion.WorkAreaSize.Height;
int horizontalOffset = (int)(displayRegionWidth - 520); //New window is 500 width + 20 to accomodate for padding
int verticalOffset = (int)(displayRegionHeight - 500); //New window is 500 height
appWindow.RequestMoveRelativeToDisplayRegion(displayRegion, new Point(horizontalOffset / 2 , verticalOffset / 2));

How to compute maximum width/height of the element?

Let's say you have WPF window with one element that changes it size as the window resizes, say DockPanel with two elements. You maximize the window, and the second element gets maximized as well. So not I could read its height/width and those would be maximum values (this is good enough for my purpose, so I don't have to worry if the taskbar takes some space or similar issues).
OK, but let's get back to the freshly started window -- I would like to compute the max width/height of the given element without actually resizing the window, just pure computation. Is it doable? How?
If I understand you correctly you want to know the maximum size the window could be. That would be the size of the screen then. Screensize is an available value:
System.Windows.SystemParameters.PrimaryScreenWidth
System.Windows.SystemParameters.PrimaryScreenHeight
Perhaps you could do something like this:
Get size of window
Get size of element
calculate offset (windowSize - elementSize)
Get Screen size
calculate maximum size (screenSize - offset)
You can create a test window which will appear as maximised, get its width and height and then close it.
This can be done every time you need to calculate values or at the start of the application, assuming you will check whether screen resolution has not changed.
private void GetMaximumWidthAndHeight(FrameworkElement element)
{
var testWindow = new Window();
testWindow.Visibility = Visibility.Collapsed;
testWindow.ShowInTaskbar = false;
testWindow.WindowState = WindowState.Maximized;
testWindow.Show();
var maximizedWindowHeight = testWindow.ActualHeight;
var maximizedWindowWidth = testWindow.ActualWidth;
testWindow.Close();
var maxToCurrentHeightRatio = maximizedWindowHeight / this.ActualHeight;
var maxToCurrentWidthRatio = maximizedWindowWidth / this.ActualWidth;
var maximumElementHeight = element.ActualHeight * maxToCurrentHeightRatio;
var maximumElementWidth = element.ActualWidth * maxToCurrentWidthRatio;
// Do something with the values
}

What is the best way to show a WPF window at the mouse location (to the top left of the mouse)?

I have found that this works PART of the time by inheriting the Windows Forms mouse point and subtracting out the height and width of my window to set the left and top (since my window's size is fixed):
MyWindowObjectThatInheritsWindow window = new MyWindowObjectThatInheritsWindow();
System.Windows.Point mouseLocation = GetMousePositionWindowsForms();
window.Left = mouseLocation.X - 300;
window.Top = mouseLocation.Y - 240;
window.Show();
Edit: Here is the code for getting the mouse position...
public System.Windows.Point GetMousePositionWindowsForms()
{
System.Drawing.Point point = System.Windows.Forms.Control.MousePosition;
return new System.Windows.Point(point.X, point.Y);
}
Note that this works by making the bottom right edge of the window touch the top left of your mouse cursor. But this breaks for different screen resolutions, or maybe multiple monitors with different resolutiosn? I haven't fully narrowed it down yet, but I just tried this same code on another PC, and it seems to spawn the window not to the top left of the mouse cursor, but to the bottom left of it, and a good distance past it...
I should probably add that my window sizes to content, width and height, so I can't just use the ActualWidth and ActualHeight properties since they're not available. Perhaps the issue is in getting that sizing right? Is there any way to do that? I know for sure the 300 and 240 is correct according to my main PC with two monitors running 1920x1080 resolutions, as I have calculated the widths and heights of all the objects in my window which I have explicitly sized. Edit: Just tried explicitly setting the height and width to 240/300, to ensure that the window is no longer sized to content, and I still have this issue when subtracting out the actual height and width!
Any ideas?
In the end, this did the trick:
protected override void OnContentRendered(EventArgs e)
{
base.OnContentRendered(e);
MoveBottomRightEdgeOfWindowToMousePosition();
}
private void MoveBottomRightEdgeOfWindowToMousePosition()
{
var transform = PresentationSource.FromVisual(this).CompositionTarget.TransformFromDevice;
var mouse = transform.Transform(GetMousePosition());
Left = mouse.X - ActualWidth;
Top = mouse.Y - ActualHeight;
}
public System.Windows.Point GetMousePosition()
{
System.Drawing.Point point = System.Windows.Forms.Control.MousePosition;
return new System.Windows.Point(point.X, point.Y);
}
Can you not use something like this?:
Point mousePositionInApp = Mouse.GetPosition(Application.Current.MainWindow);
Point mousePositionInScreenCoordinates =
Application.Current.MainWindow.PointToScreen(mousePositionInApp);
I haven't been able to test it, but I think it should work.
UPDATE >>>
You don't have to use the Application.Current.MainWindow as the parameter in these methods... it should still work if you have access to a Button or another UIElement in a handler:
Point mousePositionInApp = Mouse.GetPosition(openButton);
Point mousePositionInScreenCoordinates = openButton.PointToScreen(mousePositionInApp);
Again, I haven't been able to test this, but if that fails as well, then you can find one more method in the How do I get the current mouse screen coordinates in WPF? post.
You can also do this by slightly modifying your initial example and positioning the window before showing it.
MyWindowObjectThatInheritsWindow window = new MyWindowObjectThatInheritsWindow();
var helper = new WindowInteropHelper(window);
var hwndSource = HwndSource.FromHwnd(helper.EnsureHandle());
var transformFromDevice = hwndSource.CompositionTarget.TransformFromDevice;
System.Windows.Point wpfMouseLocation = transformFromDevice.Transform(GetMousePositionWindowsForms());
window.Left = wpfMouseLocation.X - 300;
window.Top = wpfMouseLocation.Y - 240;
window.Show();

A Toolstrip that can auto size itself

I am using this nice code which by the way if you are aware of any better way to accomplish this, I really appreciate letting us know .
so here is the Toolbar that can float :
http://en.csharp-online.net/Tool,_Menu,_and_Status_Strips%E2%80%94Floating_ToolStrips
good, but what if I only have 4 buttons on this toolbar, when I make it float it is still the same size as it was docked to the form before but I wish it could resize itself and just be as long as it needs to be to show its buttons on it .
m_floatForm.AutoSize = True
m_floatForm.AutoSizeMode = AutoSizeMode.GrowAndShrink
You can add up the widths of the individual toolstrip items and use that as the width of your form.
Replace this:
floatForm.ClientSize = this.Size;
with this:
//Adjust min value for your needs. It should account for the width of the
//toolstrip, borders, etc.
int minWidth = 20;
int newWidth = minWidth;
foreach (ToolStripItem item in this.Items)
{
newWidth += item.Size.Width;
}
floatForm.ClientSize = new Size(newWidth, this.Size.Height);
PreferredSize did the trick for me. I didn't expect to work on a ToolStip but it does, at least on .Net 4.5.
I still had to add a fixed number to account for a few pixels that I'm not sure where they are coming from.
this.Width = toolStrip.PreferredSize.Width + toolStrip.Margin.Horizontal + toolStrip.Parent.Margin.Horizontal + toolStrip.Parent.Padding.Horizontal+20;

Categories

Resources