Re: How to get Actual Size programmatically based on internal content?
hey, I hate to bump an old thread, but following up with the `.UpdateLayout()`
im getting some unexpected results with the following code
it's intention is to force the window to expand to full size, then clamp to the uiRoot's canvas.
however it does not appear to update the layout when I would expect it too.
im getting some unexpected results with the following code
Code: Select all
Minimize.Click += (object sender, RoutedEventArgs args) =>
{
Footer.Visibility = Content.Visibility = (Content.Visibility == Visibility.Visible) ? Visibility.Collapsed : Visibility.Visible;
Footer.UpdateLayout();
Content.UpdateLayout();
Window.UpdateLayout();
Window.Margin = new Thickness(
Mathf.Clamp(Window.Margin.Left, 0, uiRoot.ActualWidth - Window.ActualWidth),
Mathf.Clamp(Window.Margin.Top, 0, uiRoot.ActualWidth - Window.ActualWidth),
0, 0);
};
however it does not appear to update the layout when I would expect it too.
-
sfernandez
Site Admin
- Posts: 3154
- Joined:
Re: How to get Actual Size programmatically based on internal content?
First I want to remark that you don't need to call UpdateLayout() on each element because that function triggers a whole layout of all the invalidated elements at that moment.
To better understand what is happening we need to know the exact scenario:
The layout of any control depends on many properties:
- Width, Height, MinWidth, MinHeight, MaxWidth, MaxHeight
- HorizontalAlignment, VerticalAlignment
- Margin
If the control is inside a Canvas, then the position is also affected by the Canvas.Left, Canvas.Top, ... (and similar if it is placed inside a Grid or a DockPanel).
So if you have any of these properties set then it will affect the layout because those are not calculated properties.
To better understand what is happening we need to know the exact scenario:
The layout of any control depends on many properties:
- Width, Height, MinWidth, MinHeight, MaxWidth, MaxHeight
- HorizontalAlignment, VerticalAlignment
- Margin
If the control is inside a Canvas, then the position is also affected by the Canvas.Left, Canvas.Top, ... (and similar if it is placed inside a Grid or a DockPanel).
So if you have any of these properties set then it will affect the layout because those are not calculated properties.
Re: How to get Actual Size programmatically based on internal content?
Code: Select all
Noesis.StackPanel Window = new Noesis.StackPanel
{
HorizontalAlignment = HorizontalAlignment.Left,
VerticalAlignment = VerticalAlignment.Top,
Background = Brushes.SlateGray,
MinHeight = 20,
MaxHeight = 800,
MinWidth = 120,
MaxWidth = 500,
CanVerticallyScroll = true
};
i'm thinking I could add a onLoaded event trigger on click to callback the clamp position tool as mentioned earlier but I dont want to overlook the `UpdateLayout`
would I have to force invalidate the window?
-
sfernandez
Site Admin
- Posts: 3154
- Joined:
Re: How to get Actual Size programmatically based on internal content?
As I said before, ActualWidth and ActualHeight are values calculated during the layout process (Measure/Arrange), so any changes made to a control won't reflect until layout is finished.
If you want to force the layout you have to call UpdateLayout once, and after that ActualWidth/ActualHeight will be valid for any control.
If you are interested only in knowing when those values change so you can execute some logic, you can register to the control's SizeChanged event.
If you want to force the layout you have to call UpdateLayout once, and after that ActualWidth/ActualHeight will be valid for any control.
If you are interested only in knowing when those values change so you can execute some logic, you can register to the control's SizeChanged event.
Re: How to get Actual Size programmatically based on internal content?
I get that, I am using these implimentations in my code, but it's not working as intended.
Testing your suggestion of SizeChanged seems like it would be the ideal solution. but for some reason it still didn't clamp position based on the new actual width/height.
is actual Width perhaps calculated within the bounds of the canvas?
as it only updates when I move the panels, this would lead as to an explanation as to why other implimentations haven't worked so far
Testing your suggestion of SizeChanged seems like it would be the ideal solution. but for some reason it still didn't clamp position based on the new actual width/height.
is actual Width perhaps calculated within the bounds of the canvas?
as it only updates when I move the panels, this would lead as to an explanation as to why other implimentations haven't worked so far
Code: Select all
Window.SizeChanged += (s, a) =>
{
Window.Margin = new Thickness(
Mathf.Clamp(Window.Margin.Left, 0, uiRoot.ActualWidth - Window.ActualWidth),
Mathf.Clamp(Window.Margin.Top, 0, uiRoot.ActualWidth - Window.ActualWidth),
0, 0);
};
Last edited by digimbyte on 05 Jul 2019, 00:59, edited 1 time in total.
-
sfernandez
Site Admin
- Posts: 3154
- Joined:
Re: How to get Actual Size programmatically based on internal content?
That code contains a bug, you are clamping vertically using uiRoot.ActualWidth and Window.ActualWidth, instead of using the Height:
Code: Select all
Window.SizeChanged += (s, e) =>
{
Window.Margin = new Thickness(
Mathf.Clamp(Window.Margin.Left, 0, uiRoot.ActualWidth - Window.ActualWidth),
Mathf.Clamp(Window.Margin.Top, 0, uiRoot.ActualHeight - Window.ActualHeight),
0, 0);
};
Re: How to get Actual Size programmatically based on internal content?
I can't believe I missed that, I conformed all clamping to a function now to prevent this from happening again.
it works.
it works.
Who is online
Users browsing this forum: maherne and 2 guests