User avatar
digimbyte
Topic Author
Posts: 47
Joined: 14 Nov 2017, 21:42

Re: How to get Actual Size programmatically based on internal content?

27 Jun 2019, 07:00

hey, I hate to bump an old thread, but following up with the `.UpdateLayout()`
im getting some unexpected results with the following code
        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); 
        };
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.
 
User avatar
sfernandez
Site Admin
Posts: 3154
Joined: 22 Dec 2011, 19:20

Re: How to get Actual Size programmatically based on internal content?

28 Jun 2019, 13:32

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.
 
User avatar
digimbyte
Topic Author
Posts: 47
Joined: 14 Nov 2017, 21:42

Re: How to get Actual Size programmatically based on internal content?

30 Jun 2019, 01:38

        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
        };
it does update when being moved/dragged, but not after the button click despite just copying the clamp code used

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?
 
User avatar
sfernandez
Site Admin
Posts: 3154
Joined: 22 Dec 2011, 19:20

Re: How to get Actual Size programmatically based on internal content?

03 Jul 2019, 17:48

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.
 
User avatar
digimbyte
Topic Author
Posts: 47
Joined: 14 Nov 2017, 21:42

Re: How to get Actual Size programmatically based on internal content?

04 Jul 2019, 06:22

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
        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.
 
User avatar
sfernandez
Site Admin
Posts: 3154
Joined: 22 Dec 2011, 19:20

Re: How to get Actual Size programmatically based on internal content?

04 Jul 2019, 12:20

That code contains a bug, you are clamping vertically using uiRoot.ActualWidth and Window.ActualWidth, instead of using the Height:
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);
};
 
User avatar
digimbyte
Topic Author
Posts: 47
Joined: 14 Nov 2017, 21:42

Re: How to get Actual Size programmatically based on internal content?

05 Jul 2019, 01:43

I can't believe I missed that, I conformed all clamping to a function now to prevent this from happening again.
it works.

Who is online

Users browsing this forum: maherne and 2 guests