none
Get dynamically generated Grid width and height

    Question

  • I have searched through many times but have not seen this before. Probably really simple question but can't wrap my head around it.

    Wrote a VSTO add-in for Excel that draws an XAML Grid dynamically. Then launches a new window and replaces the contents of the Canvas with the generated Grid. The problem is with printing. When I call the print procedure the canvas.height and canvas.width returned is the old value prior to replacing it with the grid.

    Sample:

    string LssAllcChrt ="<Grid Name=\"CanvasGrid\" Background=\"WhiteSmoke\" xmlns=http://schemas.microsoft.com/winfx/2006/xaml/presentation\>..Lots of stuff..</Grid>";

    // Launch new window and replace the Canvas element

    WpfUserControl newWindow = new WpfUserControl();
    newWindow.Show();

    //To test MessageBox.Show(myCanvas.ActualWidth.ToString()); //return 894 Grid testGrid = myCanvas.FindName("CanvasGrid") as Grid; MessageBox.Show("Grid " + testGrid.ActualWidth.ToString()); //return 234

    StringReader stringReader = new StringReader(LssAllcChrt); XmlReader xmlReader = XmlReader.Create(stringReader);

    Canvas myCanvas = newWindow.FindName("GrphCnvs") as Canvas; myCanvas.Children.Clear(); myCanvas.Children.Add((UIElement)XamlReader.Load(xmlReader));

    //To test MessageBox.Show(myCanvas.ActualWidth.ToString()); //return 894 but should be much larger the Grid spans all three of my screens Grid testGrid = myCanvas.FindName("CanvasGrid") as Grid; MessageBox.Show("Grid " + testGrid.ActualWidth.ToString()); //return 234 but should be much larger the Grid spans all three of my screens

    //Run code from WpfUserControl.cs after it loads from button click Grid testGrid = canvas.FindName("CanvasGrid") as Grid; MessageBox.Show("Grid " + testGrid.ActualWidth.ToString()); //return 234 but should be much larger the Grid spans all three of my screens

    So basically I have no way of telling what my new width and height are

    Any Ideas

    Thanks

    Jack

    Friday, March 12, 2010 12:38 AM

All replies

  • Try wait for ApplicationIdle or SystemIdle before getting the actual width and height of Grid.

            WaitFor(TimeSpan.Zero, DispatcherPriority.SystemIdle);
            // Get the actual width and height of Grid

            private void WaitFor(TimeSpan time, DispatcherPriority priority)
            {
                DispatcherTimer timer = new DispatcherTimer(priority);
                timer.Tick += new EventHandler(OnDispatched);
                timer.Interval = time;
                DispatcherFrame dispatcherFrame = new DispatcherFrame(false);
                timer.Tag = dispatcherFrame;
                timer.Start();
                Dispatcher.PushFrame(dispatcherFrame);
            }
            private void OnDispatched(object sender, EventArgs args)
            {
                DispatcherTimer timer = (DispatcherTimer)sender;
                timer.Tick -= new EventHandler(OnDispatched);
                timer.Stop();
                DispatcherFrame frame = (DispatcherFrame)timer.Tag;
                frame.Continue = false;
            }

    Hope it helps.


    William
    Friday, March 12, 2010 4:16 AM
  • Wait won't work. I can see that the new grid replaces the old grid fine. OnLoad I have the grid with a TextBlock says "Loading..." and the dynamic grid is a chart. The button on the child window once clicked gives my the previous grid Height and Width. I waited 30 minutes and it returns the old attributes every time. The grid is fine and dispalys properly but I just can't seem to get the AcutalHeight and ActualWidth of the grid that was generated and loaded.
    Friday, March 12, 2010 11:14 PM
  • Here is some follow-up information maybe it will help.

    VSTO plugin launches WPF Window. Generates an XAML grid and adds the xaml grid to canvas on child window.

    WpfUserControl newWindow = new WpfUserControl();
    newWindow.Show();
    StringReader stringReader = new StringReader(LssAllcChrt);
    XmlReader xmlReader = XmlReader.Create(stringReader);
    Canvas myCanvas = newWindow.FindName("GrphCnvs") as Canvas;
    myCanvas.Children.Clear();
    myCanvas.Children.Add((
    UIElement)XamlReader.Load(xmlReader));

    From the Child Window I try to render the grid (Maybe I should be going this from parent??)

    double
    scale = Math.Min(canvas.ActualWidth / grid.ActualWidth, canvas.ActualHeight /grid.ActualHeight);
    grid.LayoutTransform =
    new ScaleTransform(scale, scale);
    Grid testGrid = canvas.FindName("CanvasGrid") as Grid;
    canvas.Measure(size);
    grid.Measure(size);
    ((
    UIElement)grid).Arrange(new Rect(new Point(canvas.ActualWidth, canvas.ActualHeight),size));
    rtb.Render(testGrid);

    This renders the old Grid (Which is just a TextBlock "Loading Graph") and not the new Grid which should have replaced and not just layed on  top of the old grid.
    I can see that the new grid is there and Children.Clear() should have cleared the old Grid.

    How can I get the attributes of the new Grid?

    Monday, March 15, 2010 5:30 PM