none
Strange behaviour of VSTO WinForm/WPF control in Word Addin RRS feed

  • Question

  • Hi,

    I am developing VSTO Addin for Microsft Word 2010+. The addin adds WinForm UserControl controls to Document text. From other site each WinForm control host WPF User Control. I am using VSTO Document.Controls.AddControl method to add my custom controls. In general I've used the following sequence of calls:

    1. var cntrl = Document.AddControl(control, range, width, height);
    2. cntrl.ConvertToShape() - I want to be Shape not InlineShape, so to be able to change offset.
    3. cntr.Left = -38;

    What happened is that sometimes some of the controls are not functional. Actually, they appeared like images. User can right click on them, they render some content (and some black area too). And for some controls the message box with message 'Windows Forms controls have been disabled because the document has been scaled. When zoom is returned to 100%, controls will reactivate.'. But the Zoom is 100%.

    After running few tests, I discovered that I need to set correct sizes (width and height passed to AddControl) to match correctly to WinForm dimensions (and transformation between points and pixels needs to take in account). After that what happened most of the controls are functional correctly but the ones which are close to bottom of first page are act as images (not functional).  Also, when I changed the DPI > 96, some of the working controls are rendered incorrectly. Also the controls are not act consistently on Windows 8 + Office 2010 and Windows 7 + Office 2010.

    I've decided to take different approach. Instead added the controls as InlineShape (using AddControl with range parameter) and converted it to Shape, I've started to add the controls directly as Shape (using AddControl with top, left paramteres). The preliminary test shows that behaviour of controls is consistent no matter of DPI and OS. But I've faced different problem to discover correct positions (top and left) of Range object.

    So, I have two questions:

    1. What may cause that unstable render of controls when changing DPI of system?
    2. How I can determine correct top and left positions (in points) of Range object (for pages different than first one)?

    Best Regards

    Veselin

    Friday, December 13, 2013 3:15 PM

Answers

  • Ok I found one solution.

    I am using 3 different technologies: 

    1. VSTO - office interop operations
    2. Hosting WinForms inside VSTO
    3. Hosting WPF controls inside WinForms

    The problem came from callculation of sizes of those controls and more in different metrics. If hosted control has un-proper size to host space within text the control is rendered as it is zoomed (means as image instead as real active control).

    And if we take in account that those technologies works in different metrics, the whole picture get really funny. Word works in points, WinForms is sized in pixels and WPF controls in independent device units.

    Ok, when a new control is added here is the workflow what should be done:

    1. Calc desired size of control in advanced in POINTS (you can use the Application.PixelToPoints or Application.PointsToPixel methods)
    2. Add the control via Controls.AddControl and you can pass the desired size here. If not, follow the next steps.
    3. Convert the control from InlineShape to Shape
    4. Convert the desired size from step 1 into Pixels and update the widht/height of corresponded ElementHost control.
    5. Conver the size from Pixel to device uints (for WPF purpose) and update width/height of hosted WPF control. To convert from pixel to device unit use formula: Math.Floor(height_in_pixels / 0.75) or Math.Floor(width_in_pixels / 0.75).

    NOTE: When you host WPF inside WinForms which is host inside ContentControl in VSTO, you need to define sizes for both WPF and WinForms in advanced. And you should restrict the height/width to some maximum value. You cannot leave one of them to fit to content. Otherwise there is chance Word to not match sizes correctly and will render it as image instead working control.


    Monday, February 17, 2014 11:56 AM

All replies

  • Hi,

    I'm trying to involve some senior engineers into this issue and it will take some time. Your patience will be greatly appreciated.Sorry for any inconvenience and have a nice day!

    Best regards.


    We are trying to better understand customer views on social support experience, so your participation in this interview project would be greatly appreciated if you have time. Thanks for helping make community forums a great place.
    Click HERE to participate the survey.

    Monday, December 16, 2013 6:22 AM
  • Hi,

    Well, the problem is reduced to only one. When ElementHost control is added to document via (AddControl method of VSTO Document.Controls collection) the control is not rendered correctly. Actually nothing is show at all. It's displayed as black rectangle.

    It's appear when we tried to insert the control close to bottom of the page. The control is inserted as InlineShape and immediately convert to Shape via InlineShape.ConvertToShape method.

    The strange thing is that for other places everything works fine.

    Sometimes (when I play with different widths and height parameters for both shape and ElementHost control) instead black rectangle an stretched image of control is displayed but still un-functional.

    The ElementHost control which host WPF UserControl.

    What may cause the rendering to be failed?

    Additional researches shows that this behaviour of control is connected to Shape.RelatevieVerticalPosition property value. If this property is relative to Page everything works fine. If it's relative to Line the control is disabled.

    Wednesday, December 18, 2013 1:17 PM
  • Hi,

    I've found something interesting. I am doing the following things:

    1. Via VSTO I am adding custom control ActiveDocument.Controls.AddControl(range object, ...). The controll is added as InlineShape. The range is collapsed range positioned at beginning of paragraph.

    2. I am converting InlineShape to Shape object via InlineShape.ConvertToShape

    3. Usually this works, except in cases where paragraph is split between two pages. It's seems that if control has larger height than the portion of paragraph before page boundary, ActiveDocument.Controls.AddControl throws exception with ArgumentException (Parameter is not valid.) and later on, during InlineShape.ConvertToShape throws COMFailException (Error HRESULT E_FAIL has been returned from a call to a COM component.). It seems that WORD cannot manage correctly the shapes object.

    Monday, February 3, 2014 1:11 PM
  • Ok I found one solution.

    I am using 3 different technologies: 

    1. VSTO - office interop operations
    2. Hosting WinForms inside VSTO
    3. Hosting WPF controls inside WinForms

    The problem came from callculation of sizes of those controls and more in different metrics. If hosted control has un-proper size to host space within text the control is rendered as it is zoomed (means as image instead as real active control).

    And if we take in account that those technologies works in different metrics, the whole picture get really funny. Word works in points, WinForms is sized in pixels and WPF controls in independent device units.

    Ok, when a new control is added here is the workflow what should be done:

    1. Calc desired size of control in advanced in POINTS (you can use the Application.PixelToPoints or Application.PointsToPixel methods)
    2. Add the control via Controls.AddControl and you can pass the desired size here. If not, follow the next steps.
    3. Convert the control from InlineShape to Shape
    4. Convert the desired size from step 1 into Pixels and update the widht/height of corresponded ElementHost control.
    5. Conver the size from Pixel to device uints (for WPF purpose) and update width/height of hosted WPF control. To convert from pixel to device unit use formula: Math.Floor(height_in_pixels / 0.75) or Math.Floor(width_in_pixels / 0.75).

    NOTE: When you host WPF inside WinForms which is host inside ContentControl in VSTO, you need to define sizes for both WPF and WinForms in advanced. And you should restrict the height/width to some maximum value. You cannot leave one of them to fit to content. Otherwise there is chance Word to not match sizes correctly and will render it as image instead working control.


    Monday, February 17, 2014 11:56 AM