17
votes

I wanted to wrap a windows forms control in a wpf UserControl

<UserControl x:Class="MVVMLibrary.ReportViewer"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    xmlns:ws="clr-namespace:Microsoft.Reporting.WinForms;assembly=Microsoft.ReportViewer.WinForms"
    Height="Auto" Width="Auto">
    <Grid>
        <WindowsFormsHost Name="Host">
            <ws:ReportViewer/>
        </WindowsFormsHost>
    </Grid>
</UserControl>

Notice that Height and Width are auto.

When I have it in a stackpanel or grid control it sets its height to 0 and basically disappears. The user is then required to resize the window(which shrunk because the usercontrol said I don't need no space, thanks). When the user resizes it stretches to whatever the user specifies.

So my question is what did I do wrong? How do I make my usercontrol take all the space available instead of not asking for any?

5

5 Answers

21
votes

I find a better answer.

Use a dockPanel with LastChildFill=true and then put inside the WindowsFormsHost with Horizontal and Vertical Alignement to Strech, and of course the WindowsForms control have to fill.

<DockPanel LastChildFill="true">
    <WindowsFormsHost HorizontalAlignment="Stretch" VerticalAlignment="Stretch">
        <Panel Dock=Fill />
    </WindowsFormsHost>
</DockPanel>

Enjoy',

6
votes

Some corrections: DockPanel has LastChildFill enabled by default, and Horizontal and Vertical alignments are also automatically set to stretch.

So the concise answer is: Use a DockPanel

<DockPanel>
     <WindowsFormsHost>
     </WindowsFormsHost>
</DockPanel>
4
votes

The same problem here. What I have done is to bind the WindowsForm control (that must be embeded) dimensions to the dimensions (Width and Height) of the parent Host(i.e. the WindowsFormHost) see the code below. This is done after the windows form is loaded:

 private void Window_Loaded(object sender, RoutedEventArgs e)
 {
    UserWinFormControl.Height = UserWinFormControl.Parent.Height;
    UserWinFormControl.Width = UserWinFormControl.Parent.Width;

 }   

Where UserWinFormControl is the control to be embeded/hosted by the WindowsFormHost In the Xaml write:

<Window x:Class="myAppWpf.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:WinForms="clr-namespace:System.Windows.Forms;assembly=System.Windows.Forms"
        Title="MyApp" 
        Height="737" 
        Width="1024"
        WindowStartupLocation="CenterScreen" 
        Loaded="Window_Loaded">
        <......>
        <DockPanel LastChildFill="true">
                        <WindowsFormsHost Name="windowsFormsHost1"DockPanel.Dock="Top" 
                                          Background="Yellow"         
                                          HorizontalAlignment="Stretch"             
                                          VerticalAlignment="Stretch" >
                         </WindowsFormsHost>
        </DockPanel>
        </....>
</Window>

All is working fine no flickers when resizing the app.

3
votes

I had this same problem. The way I fixed it was to change the size of the control inside the WindowsFormsHost at runtime.

In my case I used a StackPanel to host the control and at runtime I set the Height and Width of the control inside my WindowsFormsHost to the height and width of the Stackpanel. You want to use the ActualHieight and ActualWidth properties.

Unfortunately I had to hook up to the sizing event change it each time the window was resized.

2
votes

I had some sort of similar problem. I was able to fix my issue by removing the min and max Height and Width settings from the winForm form.

After that I used the DockPanel like ykatchou suggested. I still have some issues with DPI but I don't think they'll matter much. It's ugly, but it's working