Reputation: 305
I've designed a UserControl object to implement the UI for my Word add-in. At run time, when the user opens the task pane, I add an instance of that UserControl to the active window (through the CustomTaskPanes collection), set its Visible property to true, and lo and behold, I get my task pane... except it's truncated, I only see the left 70% of it, and I need to manually resize the task pane to see the UserControl in its entirety.
First and foremost, I don't understand why the default behavior of the task pane wouldn't be to just take the designed size of whatever I put in it. But it gets worse.
My logical next step was to explicitly set the width of the task pane to that of my UserControl. Since the Windows Forms designer showed that its Size property was "700, 1500" I foolishly thought I could read that property at run time and assign it to the task pane's width. The code looks like this :
var myTaskPane = Globals.ThisAddIn.CustomTaskPanes.Add(myUserControl, title);
myTaskPane.Visible = true;
myTaskPane.Width = myUserControl.Width;
This failed spectacularly, because it turns out that, at run time, "myUserControl.Width" is zero. All I get is a very narrow task pane that only shows the left 20% of my UserControl. I've also tried assigning "myUserControl.Size.Width", with the same result.
So I saved my project to the Cloud and came back to it the next day, on a different PC, with a different display (4K). To my surprise, when I opened the Windows Forms designer the UserControl's Size was now reported as "432, 1200". Yet it looked exactly the same.
If I assign an immediate value to myTaskPane.Width, that works just fine. If that value happens to be the width reported by the Windows Forms designer, the task pane is exactly the width it needs to be to display the UserControl. Except I'm not OK with hardcoding design parameters. Besides, which value would I choose ? 700 or 432 ? Surely the task pane would look wrong on some systems.
So I have two questions : how do UserControl sizes work exactly ? And where do I read the UserControl's width at run-time ?
The worst thing is, this seems like something so fundamental it has to have a simple solution, but I just can't Google my way out of this.
Upvotes: 3
Views: 2219
Reputation: 305
EDIT : I thought I had a solution, but it turns out it's actually a workaround based on a custom method I implemented a while back. This goes to show that if you stick to proper naming conventions and reuse your code, eventually you may end-up thinking that your own methods are part of .NET. Read on, though, I've corrected my answer.
I had a brainwave... my mistake was thinking that the control properties accessible through the Windows Forms editor in Visual Studio will also be accessible to my code at run time. I still don't know why that's not the case, and what happens to the values that show up in the editor, but I guessed that there may be a method to the madness (pun intended).
IntelliSense came to my help, and now my code looks like this :
var myTaskPane = Globals.ThisAddIn.CustomTaskPanes.Add(myUserControl, title);
myTaskPane.Visible = true;
myTaskPane.Width = myUserControl.GetActualWidth();
And it works. My task pane is now the exact width it needs to be in order to display the UserControl I put inside it.
Correction : that's because I coded "GetActualWidth()" myself a while back. It works by reading the width of the largest control within my UserControl and adding margins to it. I had forgotten I coded it and dismissed it for being inelegant. You will not have this GetActualWidth() method in your UserControl unless you've implemented it too.
So, some questions remain : why does the same project, opened on the same Visual Studio but on two different computers, show me different values for the UserControl's width in the Windows Forms editor ? Does it have something to do with DPI scaling ? Is there some documentation on this ? Why can't the task pane simply show 100% of its contents by default ?
There's now an additional question : how come I can read the width of a control within my UserControl and get its designed valued, yet I can't do the same thing with the UserControl itself ?
Upvotes: 3