locked
WindowsStore App - Cannot resize canvas programmatically if it contains children controls

    Question

  • I'm creating a simple framework on top of the provided UI components, and I'm stuck on the layout engine.

    To make things simple to see and understand, I created a hello world app programmatically in C++. Just copy and past this into App.xaml.cpp (comment out the "navigate to default page" code)

    auto backgroundView = ref new Canvas();
    backgroundView->Background = ref new SolidColorBrush(Windows::UI::Colors::Gray);
    
    auto redView = ref new Canvas();
    redView->Background = ref new SolidColorBrush(Windows::UI::Colors::Red);
    redView->Width = 300;
    redView->Height = 300;
    Canvas::SetLeft(redView, 50);
    Canvas::SetTop(redView, 50);
    
    auto button = ref new Button();
    button->Content = L"Hello World";
    
    backgroundView->Children->Append(redView);
    redView->Children->Append(button);
    
    auto _event = ref new EventHandler<Object ^>([backgroundView, redView, button](Object ^sender, Object ^args){
    	auto page = static_cast<Windows::UI::Xaml::Controls::Page^>(backgroundView->Parent);
    	auto width = page->ActualWidth;
    	auto height = page->ActualHeight;
    
    	backgroundView->Width = width;
    	backgroundView->Height = height;
    
    	redView->Width = width - 100;
    	redView->Height = height - 100;
    	Canvas::SetLeft(redView, 50);
    	Canvas::SetTop(redView, 50);
    
    	Canvas::SetLeft(button, 10);
    	Canvas::SetTop(button, 10);
    
    });
    backgroundView->LayoutUpdated += _event;
    
    rootFrame->Navigate(Page::typeid);
    safe_cast<Page^>(rootFrame->Content)->Content = backgroundView;
    

    In this app, I have a red view with a set width, height, left and top. When the Page resizes, the red view is told to be as big as it's parent minus 100 in width and height, and also to be 50 for top and bottom. Essentially, a margin.

    If you run this code, you'll see that this does not happen. But, if you remove the line "redView->Children->Append(button);" then it all works.
    So my question, is this a bug or intended? Why does the view resize if it does not have the button in it?
    Note, this is a very simplistic example of a much bigger project.

    Sunday, October 5, 2014 5:13 PM

Answers

  • You might want to look into how the Measure and Arrange Methods on UIElements in Windows Store Apps work. I believe calling InvalidateArrange on the outer-most element should trigger another layout run on the contained UIElements.

    If every change to the desired values would trigger such an update your code would trigger quite a lot of those. Removing the button however is seen as a rather big change affecting layout so that is triggering the update automatically.

    Sunday, October 5, 2014 6:34 PM