Add a WPF UserControl to a TaskPane - wpf

I am developing an addin to Microsoft Outlook.
The following code works fine if I use an winforms UserControl:
private void ThisAddIn_Startup(object sender, System.EventArgs e)
{
var testControlView1 = new UserControl1();
var MyCustomPane = this.CustomTaskPanes.Add(testControlView, "Hello");
}
How can I do it with a WPF UserControl, instead? Does anybody know how I would achieve similar functionality?
As far as I can tell the CustomTaskPanes only allow Winforms Controls to be added to it.

Just found a solution,
https://stevepietrekweblog.wordpress.com/2009/03/24/vsto-display-wpf-user-control-in-custom-task-pane/
This update was just to update the link.

Related

XAML Islands ProgressRing White Background

I'm porting a WPF app to WPF .NET Core 3.0. I'm trying to use UWP controls using XAML Islands via WindowsXamlHost from the Community Toolkit. The WindowsXamlHost control itself has a white background and I don't know how to get rid of it. Here's an example of a ProgressRing:
<xamlHost:WindowsXamlHost x:Name="MyRing" InitialTypeName="Windows.UI.Xaml.Controls.ProgressRing"/>
private void MyRing_ChildChanged(object sender, EventArgs e)
{
if (MyRing.Child is ProgressRing progressRing)
{
progressRing.IsActive = true;
var brush = new Windows.UI.Xaml.Media.SolidColorBrush(Windows.UI.Colors.Transparent);
progressRing.Background = brush;
}
}
Giving the ProgressRing object a new background color works but doesn't help if I'm after transparency. I'm using .NET Core 3 preview 7.
I'm not sure whether it is possible. I have a similar issue which I reported here: https://github.com/windows-toolkit/Microsoft.Toolkit.Win32/issues/160#issuecomment-522288462. Hopefully, Microsoft employees will answer there.

Where is ExecWB?

If I use WPF syntax:
<WebBrowser Grid.Row="1" Grid.Column="1" x:Name="htmlView"></WebBrowser>
Or if I add a WindowsFormsHost:
<WindowsFormsHost x:Name="formsHost" Grid.Row="1" Grid.Column="1">
</WindowsFormsHost>
And in the CS file:
public partial class MainWindow : Window
{
System.Windows.Forms.WebBrowser htmlView= new System.Windows.Forms.WebBrowser();
public MainWindow()
{
InitializeComponent();
formsHost.Child = htmlView;
htmlView.Navigate("d:\\test.xml");
}
private void menuFilePageSetup_Click(object sender, RoutedEventArgs e)
{
MessageBox.Show("Do do");
}
}
Either way, the ExecWB method is not exposed. So I can't port this code over from my MFC C++ CHtmlView derived class:
ExecWB(OLECMDID_PAGESETUP, OLECMDEXECOPT_DONTPROMPTUSER, NULL, NULL);
Am I missing something? At this point in time I can't implement my print preview / page setup / zoom functionality because I can't use ExecWB.
I have tried deriving my own class from the Winforms browser but it is still not listed.
Thank you.
I don't understand why in this question:
How do I programmatically change printer settings with the WebBrowser control?
It refers to ShowPrintDialog but even that is not listed.
Partial success! I don't know why, but now, when I use the hosted Winforms version, I can atleast see some of the methods:
public partial class MainWindow : Window
{
System.Windows.Forms.WebBrowser htmlView= new System.Windows.Forms.WebBrowser();
public MainWindow()
{
InitializeComponent();
formsHost.Child = htmlView;
htmlView.Navigate("d:\\test.xml");
}
private void menuFilePageSetup_Click(object sender, RoutedEventArgs e)
{
htmlView.ShowPageSetupDialog();
}
private void MenuItem_Click(object sender, RoutedEventArgs e)
{
htmlView.ShowPrintPreviewDialog();
}
}
But ExecWb is still missing for managing things like zooming. I found this:
How do I print from the wpf WebBrowser available in .net 3.5 SP1?
One of the answers:
mshtml.IHTMLDocument2 doc = webBrowser.Document as mshtml.IHTMLDocument2;
doc.execCommand("Print", true, null);
But even if I add a reference to the mshtml library the compiler will not let me convert from HtmlDocument to IHtmlDocument2. Eventually I got this:
Clearing the selection in a webbrowser control
So now I know how to select all and copy to clipboard again (as long as I use the Winforms edition). However, having looked here:
https://msdn.microsoft.com/en-us/library/ms533049(v=vs.85).aspx
There seems to be no match for Optical Zoom:
ExecWB(OLECMDID_OPTICAL_ZOOM, OLECMDEXECOPT_DONTPROMPTUSER, &vZoom, NULL);
The basic answer for calling ExecWb is to do this:
Use the WinForms WebBrowser control
Then something like htmlView.Document.ExecCommand
Pass in commands like:
SelectAll
Copy
for clipboard items.
There are native methods for displaying the print dialogues etc..
Only thing that does not seem to be supported is:
ExecWB(OLECMDID_OPTICAL_ZOOM, OLECMDEXECOPT_DONTPROMPTUSER, &vZoom, NULL);

How to add bindings for WindowsFormHost hosted ReportViewer control

I'm using Microsoft's ReportViewer control in my WPF application. Since this is a WinForms component, I use the WindowsFormHost control.
I try to follow the MVVM pattern as supported by the WPF Application Framework, so I implemented a ReportViewModel which contains (amongst others) the current report name and the dataset (both can be selected by 'regular' WPF controls, that part works fine).
I'd like to be as "WPF-ish" as possible, so how would I properly set up the binding to the ReportViewer component (which is inside the WindowsFormHost control)? I need to set the ReportViewer.LocalReport.ReportEmbeddedResource property and have a call to ReportViewer.LocalReport.DataSources.Add (and possibly Clear) whenever the view models report name or dataset change. What's the proper way to do that?
Is there any chance to use one of the regular WPF binding mechanisms for that? If yes, how? If no, how would I set up the binding? (its my first 'real' WPF project, so don't be shy to post trivial solutions :) ...)
Thanks!
So far I've come up with the following solution (purly code-behind):
private void MyDataContextChanged(object sender, DependencyPropertyChangedEventArgs e) {
if (e.OldValue is ReportViewModel) {
var viewModel = e.OldValue as ReportViewModel;
viewModel.PropertyChanged -= ViewModelPropertyChanged;
}
if (DataContext is ReportViewModel) {
var viewModel = DataContext as ReportViewModel;
viewModel.PropertyChanged += ViewModelPropertyChanged;
SetReportData();
}
}
void ViewModelPropertyChanged(object sender, System.ComponentModel.PropertyChangedEventArgs e) {
if (e.PropertyName == "ReportName" || e.PropertyName == "ReportData")
SetReportData();
}
private void SetReportData() {
var viewModel = DataContext as ReportViewModel;
if (viewModel != null) {
var reportView = reportHost.Child as ReportViewer;
reportView.LocalReport.ReportEmbeddedResource = viewModel.ReportName;
reportView.LocalReport.DataSources.Clear();
reportView.LocalReport.DataSources.Add(new ReportDataSource("DataSet1", viewModel.ReportData as DataTable));
reportView.RefreshReport();
}
}
I'm still curious if there are any better solutions (I'm sure there are ...).

How to get Control values from a web application that has been opened thru WPF WebBrowser Control(C#)

I have a problem.
I am calling an external application(web) through a WPF WebBrowser Control. The
application is opening properly. Now in the web application, there are certain hyperelinks.
If a user click on that hyperlink, I should be able to trap it's value.
How to achieve the same using this WEB BROWSER.. I mean, in which event , what code I need to write to get it work
Using C#3.0, WPF and Dotnet framework 3.5
Thanks
Try this.
private void _webBrowser_Navigating(object sender, NavigatingCancelEventArgs e)
{
if (string.IsNullOrEmpty(e.Uri.AbsolutePath))
{
e.Cancel = true;
string actionName = e.Uri.LocalPath;
MessageBox.Show(actionName);
}
}
Regards,
Nanda

Putting a WPF UserControl on the TaskPane of an Excel2007 Addin

I am making a Excel Addin in VS2010.
The following code work fines if I make a winforms usercontrol
private void ThisAddIn_Startup(object sender, System.EventArgs e)
{
var testControlView1 = new UserControl1();
var MyCustomPane = this.CustomTaskPanes.Add(testControlView, "Hello");
}
However I would like to make my UserControl1 be a WPF UserControl. Does anybody know how I would achieve similar functionality or an alternate approach?
As far as I can tell the CustomTaskPanes only allows Winforms Controls to be added to it.
Answer summary:
1. Add a .net winforms usercontrol
2. Add a SWF.Integration.ElementHost control to the user control.
3. Add a Wpf control to your project seperately (not to the user control).
3. Use the Hosted Content property (hostedcontentName) of the ElementHost control and set it to the wpf control.
I found this blog post that answered it great...

Resources