I am developping a VSTO Add-In for Microsoft Office using C# and WPF. The framework is .NET framework 4.8.
The Add-In consists of several buttons in the ribbon and several task panes that can be visible or hidden.
My problem is similar to this post which has no responses: Office addin custom task pane display issue but I have here more context.
The controls in the custom task pane are designed using WPF, and including in an ElementHost which is added to a WinForm control children. This WinForm control is added to the CustomTaskPanes property of ThisAddIn class.
The WPF control contains a TextBlock and a Combobox with few elements in it.
As far as I understood, this is the only way to use WPF for the task panes for Office.
public partial class TaskPaneWinForm : UserControl
{
public TaskPaneWinForm()
{
InitializeComponent();
var wpfHost = new ElementHost
{
Dock = DockStyle.Fill,
AutoSize = true,
Margin = new Padding(0)
};
wpfHost.Child = new HostedWpfTaskPane();
Controls.Add(wpfHost);
}
}
private void ThisAddIn_Startup(object sender, System.EventArgs e)
{
var taskPane = CustomTaskPanes.Add(new TaskPaneWinForm(), "Task pane");
taskPane.Width = 400;
taskPane.Visible = false; // will be set to true on a click to a button in the ribbon
_ribbon.TaskPane = taskPane;
}
The Add-In can also open a new WPF window as a modal dialog, from a button in the ribbon.
Now here is my problem: in the Windows screen settings, if the screen Scaling parameter is set to something higher than 100%, the texts, borders, etc. of both the WPF dialogs and task panes become blurry:
Task pane is blurry
Window is blurry
Starting with the window, I made a call just before the creation of the window to SetThreadDpiAwarenessContext with parameter PerMonitorAware.
public void OnButtonClicked(IRibbonControl control)
{
DpiHelper.SetThreadDpiAwareness(DpiAwarenessContext.PerMonitorAware);
new Window1().ShowDialog();
}
Using this code, the window appear clear, not blurry at all. However, the button flickers when the mouse hovers it near the bottom and right borders, making the click nearly impossible.
Animated gif showing the flickering of my window
Then, I created an instance of System.Windows.Application durint ThisAddIn.BeginInit() method and makes also a call to SetThreadDpiAwarenessContext before:
public override void BeginInit()
{
DpiHelper.SetThreadDpiAwareness(DpiAwarenessContext.PerMonitorAware);
_ = new Application
{
ShutdownMode = ShutdownMode.OnExplicitShutdown
};
}
Doing so fixes my window: text is not blurry anymore and the buttons does not flickers. Note that I had to do both, calling SetThreadDpiAwareness and create the application, in this order. It is still unclear to me why a new System.Windows.Application need to be created.
At this point, the task pane appears still blurry, but the behavior of the combobox inside is worse: now the list of elements in the combobox flickers, and select one element is really difficult!
Animated gif showing the flickering of the Combobox
I tried several combinations of calling SetThreadDpiAwareness, like making a call just before making the task pane visible the first time, or in the constructor of the WPF control hosted in the ElementHost without success.
I also tried what is explained in this message: /a/50252643/23786564. This is unclear what should I do once I hooked the WM_DPICHANGED message.
The flickers in the task pane starts with the initialization of the System.Windows.Application.
The flickering makes the click on the buttons / selection of the combobox items difficult, because the control actually losts the focus, or the mouse hover trigger switches from true to false repeatidly.
Is there a way to achieve what I want, meaning both windows and hosted WPF controls look clear, and no flickers is observed?
The problem is reproducible with a minimal project you can found on github: https://github.com/GradlonGwen/PPT-VSTO-AddIn/tree/main/PowerPointAddIn1
1