Open WPF form from a VSTO outlook addin - c#

I have this code in Thisaddin.cs
public void Search(string input)
{
ServerList listofservers = new ServerList();
listofservers.Visibility;
}
the ServerList is a simple WPF form with listbox thats it but how to display the listofservers?
I can't find the listofserver.show();

So first of all there is no item called WPF Form, there is only User Control for WPF. So once the WPF UserControl is created in the XAML you notice that this is the code
<UserControl x:Class="SQL_openertak2.ServerList"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
mc:Ignorable="d" d:DesignHeight="454" d:DesignWidth="259" SizeToContent="WidthAndHeight">
<Grid>
<ListBox Height="410" HorizontalAlignment="Left" Margin="12,12,0,0" Name="listBox1" VerticalAlignment="Top" Width="242" />
<Button Content="Button" Height="23" HorizontalAlignment="Left" Margin="12,427,0,0" Name="button1" VerticalAlignment="Top" Width="75" Click="button1_Click" />
</Grid>
</UserControl>
So i have looked thru the XAML code. So as you can see that the whole thing is USERCONTROL
you have to change it to WINDOW then you will be able to see the .Show()
But take note that you also have to change the code in the xaml.cs
cause it will be like this by default
public partial class ServerList : UserControl
Change it to
public partial class ServerList : Window
well for obvious reasons!! :)

you can also host it in a layout panel, like:
Open Form1 in the Windows Forms Designer.
In the Toolbox, drag a TableLayoutPanel control onto the for
On the TableLayoutPanel control's smart tag panel, select Remove Last Row.
Resize the TableLayoutPanel control to a larger width and height.
In the Toolbox, double-click UserControl1 to create an instance of UserControl1 in the first cell of the TableLayoutPanel control.
The instance of UserControl1 is hosted in a new ElementHost control named elementHost1.
In the Toolbox, double-click UserControl1 to create another instance in the second cell of the TableLayoutPanel control.
In the Document Outline window, select tableLayoutPanel1. For more information, see Document Outline Window.
In the Properties window, set the value of the Padding property to 10, 10, 10, 10.
Both ElementHost controls are resized to fit into the new layout.

Change UserControl with Window as already answered in XAML and c# class.
Keep in mind that in VSTO applications, which are normally based on Windows Forms, it is important to remember to add System.XAML to references, otherwise you will probably get errors composing your forms layouts.
This could happen in VS2015 as I recently experienced, where the wizard procedure did not work as expected, missing to update class references.
Here some references: The type 'Window' does not support direct content

Related

WPF Custom TabItem - Controls not displayed in Visual Studio Designer

I created a custom TabItem with a DockPanel and a Button in it.
XAML:
<TabItem
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
mc:Ignorable="d" x:Class="MovieDB.UI.UserControlls.SearchTab" d:DesignWidth="500.038" d:DesignHeight="309.055">
<DockPanel Background="#FFE5E5E5">
<Button x:Name="button" Content="Button" Height="100" Width="75" HorizontalAlignment="Left" VerticalAlignment="Top"/>
</DockPanel>
</TabItem>
C#:
namespace MovieDB.UI.UserControlls
{
/// <summary>
/// Interaktionslogik für SearchTab.xaml
/// </summary>
public partial class SearchTab : TabItem
{
private SearchContainer<SearchMovie> results;
public SearchTab()
{
InitializeComponent();
this.Header = "Suche";
}
public SearchTab(SearchContainer<SearchMovie> results):this()
{
this.updateSearch(results);
}
public void updateSearch(SearchContainer<SearchMovie> results)
{
clear();
if(results.TotalResults == 0)
{
}
else
{
this.results = results;
Debug.WriteLine("Results: " + results.Results.Count());
}
}
private void clear()
{
}
}
}
If launch my program the button is displayed (Screenshot 2). But the button and i guess the panel itselve does noch show up in the Visual Studio 2015 Designer (Screenshot 1).
Where is the Problem?
If you put the TabItem in a TabControl it works fine.I think that's the Problem.
The designer needs a navigation control like TabControl,Window Page etc. as root.
<TabControl x:Class="CustomControls.tab"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
mc:Ignorable="d"
d:DesignWidth="500.038" d:DesignHeight="309.055">
<TabItem>
<DockPanel Background="#FFE5E5E5">
<Button x:Name="button" Content="Button" Height="100" Width="75" HorizontalAlignment="Left" VerticalAlignment="Top"/>
</DockPanel>
</TabItem>
</TabControl>
What you did should work. But it doesn't, and I'll later try to show why.
But first, my workaround:
open designer, and right-click on it,
select: Edit Additional Templates, then Edit Generated Content, then Create Empty... Give your new DataTemplate a name, say 'DataTemplate1'
Designer will generate some code - an empty DataTemplate with a key DataTemplate1, and it will add your to TabItem the ContentTemplate attribute, with DataTemplate1 assigned to it (by DynamicResource).
Now move the content of your TabItem to the DataTemplate1. The designer should correctly display your layout.
If you close and reopen your SearchTab control, you'll find that you can't see the content again. To have it back right click on the designer, select Edit Additional Template, then Edit Generated Content, then Edit Current.
Why the designer couldn't load your SearchTab? If you right-click on the designer and select Edit Template, then Edit a Copy... you'll have TabItem style generated. The header of the TabItem is displayed by the ContentPresenter, while the TabItem's content must by displayed inside the innerBorder Border. This border has Opacity set to zero, and it's being changed to 1 by MultiTriggers, which are dependent on the TabControl. The TabControl in your case doesn't exist, so all the bindings are broken. Which suggests, that changing a default Style for 'TabItem', would also solve your problem.
Although I do not have my dev machine to work with, I can only offer a suggestion. For whatever you want on your tab item control, why not put all your controls in a custom user control or grid with the premise that you KNOW you will be adding it to tab control that is dynamically added to your tab page.
The tab item needs its proper parent tab control to render it in the designer. But if you build everything as a standard control make it look and operate as you expect.
Then at run-time, add your tab item, then add the custom control to your dynamically added tab item and see if that works for you. You apparently have all the other components / processes working. Even if your sample control was just a label, textbox or something similar.

Using part of a large WinForms project inside a large WPF project

Both of these applications are rather old and have been built and maintained over several years by several people. At the moment, one of controls used in the WinForms project really needs to be displayed in the WPF project.
I've read about using WinForms controls in WPF projects, and for the most part if you're just instantiating a regular empty WinForm control, it seems relatively simple.
What I'm wondering is how you would best approach using part of a large project in another project? Ideally the WinForm control will be visible from within ONE of our WPF controls, on ONE tab, after having been sent and loaded the required data.
Here are some general guidelines.
From your WPF application, add project references to:
your WinForms project
WindowsFormsIntegration
System.Windows.Forms
Modify your XAML to include a WindowsFormsHost:
<Window x:Class="WpfApplication1.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Title="MainWindow" Height="350" Width="525">
<Grid>
<TabControl>
<TabItem Header="Old Form">
<WindowsFormsHost Name="WinFormsHost"></WindowsFormsHost>
</TabItem>
</TabControl>
</Grid>
</Window>
Instantiate your old Form and set it as the child of the WindowsFormsHost. Set TopLevel to false or it'll complain that "the child control cannot be a top-level form." Change the FormBorderStyle too, to prevent the Form's title bar from showing up and allowing the user to drag the Form around.
public MainWindow()
{
InitializeComponent();
WinFormsHost.Child =
new Form1 { TopLevel = false, FormBorderStyle = FormBorderStyle.None };
}
You end up with something like this:
You can read more in "Walkthrough: Hosting a Windows Forms Control in WPF" and the MSDN documentation for the "WindowsFormsHost Class".

Correct way to set the Parent property of a WinForms control hosted in a C# WPF project?

I have a C# WPF app that has a WinForms control hosted in a WindowsFormsHost container. When I run my app the WinForms control does nothing in its OnPaint() event handler because the ParentForm property is NULL. In a pure WinForms project, this property is not NULL and is set to the Form the control was drawn on.
In my WPF project, since I can't figure out how to get the WinForms control to appear in the Designer, I added the control via the project XAML file. The control appears when the project is run but as I said, it never repaints because its ParentForm property is NULL.
In the main form's Window_Loaded() event I tried setting the WinForms control Parent property to the top level Window in the XAML file. I did not use the ParentForm property since it is read-only. However the compiler gives me this error:
Cannot implicitly convert type 'RawDataTestApp.Window1' to 'System.Windows.Forms.Control'
I assume I'm getting this error because Window1 is not a control? In any case, I don't know how to properly attach the WinForms control to the main form in my WPF project. How should I be doing that?
I've included the pertinent parts of the project's XAML file below. It's from an open source C# project. I added a WinForms graph control to the project hosted by a WindowsFormsHost container:
// Here's the source line that gets the error. pdeAffectiv is the WinForms graphcontrol that is hosted in a WindowsFormsHost container:
pdeAffectiv.Parent = MainForm;
// -------------------------- WPF Project XAML file ----------------------------------
<!-- Copyright © 2010 James Galasyn -->
<Window x:Name="MainForm" x:Class="RawDataTestApp.Window1"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Title="EmotivEngine Realtime Client" Height="454" Width="1042" Background="#FF000033" Foreground="#FF33FFFF" xmlns:emoclient="clr-namespace:EmoEngineClientLibrary;assembly=EmoEngineClientLibrary"
xmlns:eecontrol="clr-namespace:EmoEngineControlLibrary;assembly=EmoEngineControlLibrary"
xmlns:local="clr-namespace:RawDataTestApp" Loaded="Window_Loaded" Closing="Window_Closing"
xmlns:wf="clr-namespace:System.Windows.Forms;assembly=System.Windows.Forms"
xmlns:graphlib="clr-namespace:GraphLib;assembly=GraphLib">
<Grid>
<!--- CONTENTS SNIPPED FOR BREVITY -->
<WindowsFormsHost x:Name="wfhAffectiv" HorizontalAlignment="Left" Height="148" Margin="530,75.493,0,0" VerticalAlignment="Top" Width="471" >
<graphlib:PlotterDisplayEx x:Name="pdeAffectiv" >
</graphlib:PlotterDisplayEx>
</WindowsFormsHost>
</Grid>
</Window>

WPF WindowsFormsHost Winform user control shows but does not function

I am trying to migrate an existing Winforms project into WPF. However: there are some user controls I need to leave as WinForm controls.
I have added a WinForms UserControl into a WPF Window. It consists of a RichTextBox and some buttons and labels. This is subclassed into various further user controls.
When I embed the UserControl into a WPF window it renders - but none of the buttons appear to do anything. When underlying processes update e.g. the RichTextBox it does not display the content. Yet when I inspect the textbox in debug I can see the content (though I have to click on 'base' to see this.)
[ One difference I have spotted - though it may not be relevant - is that when this control is on a WPF and non-working Visual Studio shows the object as 'sealed' but when in the original Winforms project when it is fully working it does not show as sealed. ]
I have added code to change the text in the labels - and they also firmly refuse to update: yet again I can see the text if I examine the label in debug mode.
This stack overflow question may address the same issue:
WindowsFormsHost Winform pdfviewer control problem
but the answer didn't make a lot of sense to me:
It mentioned replacing
new Window { Content = CreateContent(), Title = title }.Show();
But this is not a piece of code I recognise: I am using a xaml file with code behind and it's called up using
System.Windows.Application app = new System.Windows.Application();
app.Run(new FormWPFApp());
(where FormWPFApp is my name for the WPF window)
Here is the xaml header:-
<Window x:Class="ZedApp.FormWPFApp"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:Printers="clr-namespace:ZedApp.UserControls.Printers"
xmlns:wf="clr-namespace:System.Windows.Forms;assembly=System.Windows.Forms"
Title="Conversion version" Height="661" Width="1559" Loaded="Window_Loaded">
Here is the xaml I use for the two UserControls (they both inherit from the same base class) :-
<WindowsFormsHost Height="430" HorizontalAlignment="Left" Margin="192,32,0,0" Name="windowsFormsHostTicketPrinter" VerticalAlignment="Top" Width="324" Grid.Row="1" Grid.Column="1">
<Printers:TicketPrinter x:Name="ticketPrinter">
</Printers:TicketPrinter>
</WindowsFormsHost>
<WindowsFormsHost Height="430" HorizontalAlignment="Left" Margin="522,32,0,0" Name="windowsFormsHostJournalPrinter" VerticalAlignment="Top" Width="324" Grid.Row="1" Grid.Column="1">
<Printers:JournalPrinter x:Name="journalPrinter">
</Printers:JournalPrinter>
</WindowsFormsHost>
[Another thing I have noticed is a method that clears the Rich Text Box on one of the windows starts kicking out errors of the following type if run under WindowsFormsHost in WPF -
"Invoke or BeginInvoke cannot be called on a control until the window handle has been created."
private void ClearRichTextBox(RichTextBox rtbToClear)
{
if (rtbToClear.IsHandleCreated)
{
if (rtbToClear.InvokeRequired)
{
this.Invoke(new Action<RichTextBox>(ClearRichTextBox), new object[] {rtbToClear});
return;
}
rtbToClear.Clear();
}
}
]
What is the likely cause of this behaviour and what do I need to do to get the elements within the User Control working?
Proper input interop with WinForms requires some cooperation between the host and the WPF input system. The topic Message Loops Between Win32 and WPF in the SDK explains this well. In your setup, the easiest way to make this happen is to use code like this:
Window w = new Window1();
System.Windows.Forms.Integration.ElementHost.EnableModelessKeyboardInterop(w);
w.Show();
ElementHost.EnableModelessKeyboardInterop() essentially registers an input hook with the WinForms Application object (which normally runs the message loop) and calls ComponentDispatcher.RaiseThreadMessage().

C# User Control that can contain other Controls (when using it)

I found something about this issue for ASP, but it didn't help me much ...
What I'd like to do is the following: I want to create a user control that has a collection as property and buttons to navigate through this collection. I want to be able to bind this user control to a collection and display different controls on it (containing data from that collection).
Like what you had in MS Access on the lower edge of a form ...
to be more precise:
When I actually use the control in my application (after I created it), I want to be able to add multiple controls to it (textboxes, labels etc) between the <myControly> and </mycontrol>
If I do that now, the controls on my user control disappear.
Here is an example of one way to do what you want:
First, the code - UserControl1.xaml.cs
public partial class UserControl1 : UserControl
{
public static readonly DependencyProperty MyContentProperty =
DependencyProperty.Register("MyContent", typeof(object), typeof(UserControl1));
public UserControl1()
{
InitializeComponent();
}
public object MyContent
{
get { return GetValue(MyContentProperty); }
set { SetValue(MyContentProperty, value); }
}
}
And the user control's XAML - UserControl1.xaml
<UserControl x:Class="InCtrl.UserControl1"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Height="300" Width="300" Name="MyCtrl">
<StackPanel>
<Button Content="Up"/>
<ContentPresenter Content="{Binding ElementName=MyCtrl, Path=MyContent}"/>
<Button Content="Down"/>
</StackPanel>
</UserControl>
And finally, the xaml to use our wonderful new control:
<Window x:Class="InCtrl.Window1"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:me="clr-namespace:InCtrl"
Title="Window1" Height="300" Width="300">
<Grid>
<me:UserControl1>
<me:UserControl1.MyContent>
<Button Content="Middle"/>
</me:UserControl1.MyContent>
</me:UserControl1>
</Grid>
</Window>
I'm having a hard time understanding your question, but I think what you're describing is an ItemsControl using DataTemplates to display the contents of (presumably) an ObservableCollection(T).
A UserControl may not be the best way to do this. You're wanting to add decorations around content, which is basically what Border does: it has a child element, and it adds its own stuff around the edges.
Look into the Decorator class, which Border descends from. If you make your own Border descendant, you should be easily able to do what you want. However, I believe this would require writing code, not XAML.
You might still want to make a UserControl to wrap the buttons at the bottom, just so you can use the visual designer for part of the process. But Decorator would be a good way to glue the pieces together and allow for user-definable content.
Here's a link to a built-in control (HeaderedContentControl) that does the same thing as the accepted answer except that it is an existing control in WPF since .Net 3.0

Categories

Resources