2
votes

I have a winforms usercontrol which contains an element host which itself contains a wpf usercontrol which contains a textbox.

It seems that I've not got the resizing of the innermost textbox working properly. Ideally it would resize to fill the elementhost and that would itself resize to fill the winforms usercontrol as it resizes.

The winforms usercontrol has the following constructor code

public partial class TextBox : UserControl, ITextBox
{
    private System.Windows.Forms.Integration.ElementHost _textBoxHost;
    private TextBoxExViewModel _viewModel;
    private TextBoxEx _textBoxEx;

    public TextBox()
    {
        InitializeComponent();

        this._textBoxHost = new System.Windows.Forms.Integration.ElementHost();           
        this._textBoxEx = new IfxNetControls.TextBoxEx();
        this._viewModel = new TextBoxExViewModel();

        _textBoxEx.DataContext = _viewModel;

        this.SuspendLayout();

        // set up wpf host elementHost1             
        this._textBoxHost.Dock = System.Windows.Forms.DockStyle.Fill;
        this._textBoxHost.Location = new System.Drawing.Point(0, 0);
        this._textBoxHost.Name = "textBoxHost";
        this._textBoxHost.Size = new System.Drawing.Size(340, 245);
        this._textBoxHost.TabIndex = 0;
        this._textBoxHost.Text = "textBoxHost";
        this._textBoxHost.AutoSize = false;
        this._textBoxHost.ChildChanged += new System.EventHandler<System.Windows.Forms.Integration.ChildChangedEventArgs>(this.ChildChanged);
        this._textBoxHost.Child = this._textBoxEx;
        //this._elementHost1.Child = this._wpfTextBox;

        // set up usercontrol textbbox 
        this.Controls.Add(this._textBoxHost);
        this.Name = "TextBox";
        this.Size = new System.Drawing.Size(340, 245);
        this.AutoSize = false;

        //
        this.ResumeLayout(false);
    }

    ...

Note the Dock property is set to Fill

I also tried a resize handler in the Winforms usercontrol

private void TextBox_Resize(object s, EventArgs e)
{                
    this._textBoxEx.Width = this._textBoxHost.Width;
    this._textBoxEx.Height = this._textBoxHost.Height; 
}

since when I have traced with height and width the wpf textbox is always smaller

WinformsUserControl: 208,35
ElementHost: 208,35
WpfUsercontrol: 181.527272727273,30.5454545454545

This seems to be reflected when it is being used (see img 3 below) - although I did wonder whether the units of measurement were the same across all 3 controls.

The wpf usercontrol xaml looks like this

<UserControl x:Class="IfxNetControls.TextBoxEx"
         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" 
         xmlns:local="clr-namespace:..."             
         mc:Ignorable="d" 
         d:DesignHeight="450" d:DesignWidth="800"
         HorizontalAlignment="Stretch"
         VerticalAlignment="Stretch"
         HorizontalContentAlignment="Stretch"
         VerticalContentAlignment="Stretch"
         Height="Auto"
         Width="Auto"
         Margin="0"
         Padding="0"
         >
...

and the textbox xaml has the Height and Width set to "Auto". I've also tried setting the Horizontal/Vertical Alignment and ContentAlignment to Stretch.

When this gets displayed it initially looks like this. (I have placed 2 the same size to show changes)

enter image description here

Initially the top one has focus but if I move focus off it, it resizes to what appears to be the text (even though I have explicitly set Autosize to false).

enter image description here

If I mess with the background colour, it looks like this which seems to reveal the different size of the textbox to its containers with margins at the bottom and left

enter image description here

Ideally, all controls would be the same size (and the same back colour!).

I'm not very familiar with wpf so I wonder if someone could point out my error.

EDIT-1: So I'm still trying to work out what the problem actually is!

If I update the backcolor of the winforms usercontrol and not change the background of the XAML usercontrol or textbox, it looks like this when the textbox doesn't have focus

enter image description here

However, when it gets focus, it looks like the wpfusercontrol/textbox expands to fill the winforms usercontrol container - thus:

enter image description here

and then on losing focus, it returns back to its previous size revealing the background of the winforms usercontrol again.

I don't quite understand since when I have traced the width and height of the elementhost, it's size has been the same as the winforms usercontrol. I have given the wpf usercontrol it's own background colour but I never see that which to my mind indicates that the textbox is actually correctly filling the wpf usercontrol. It just seems that the wpf usercontrol/textbox resize at points I am not expecting.

Is that expected behaviour?

Thx again.

2

2 Answers

0
votes

In WPF you usually work with Styles, Templates and Custom Controls. There are many tutorials for these and I recommend to have a look at these. UserControls are not as flexible as these and are usually used to create large UIs which don't have to be that flexible. For example to create a form.

Ideally, all controls would be the same size (and the same back colour!).

In this case I would recommend you to use a Style.

Here explained how Autoand * works and how you can use a Style.

<Window x:Class="WpfApp1.MainWindow"
    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"
    xmlns:local="clr-namespace:WpfApp1"
    mc:Ignorable="d"
    Title="MainWindow" Height="450" Width="800">
<Window.Resources>
    <Style TargetType="{x:Type TextBox}"> <!-- Style for all Textboxes on this window -->
        <Setter Property="TextAlignment" Value="Left"/>
        <Setter Property="Width" Value="180"/>
        <Setter Property="Margin" Value="5"/> <!-- the same as 5,5,5,5  left,top,right,bottom  -->
        <Setter Property="Background" Value="Blue"/>
    </Style>
</Window.Resources>
<Grid>
    <Grid.ColumnDefinitions>
        <ColumnDefinition  Width="2*"/><!-- It's 2 times wider than the other colums with * -->
        <ColumnDefinition Width="Auto"/> <!-- the Column width is based on the widest control in this column -->
        <ColumnDefinition /><!-- you can also write Width="*" -->
    </Grid.ColumnDefinitions>
    <Grid.RowDefinitions>
        <RowDefinition/> <!-- you can also write Height="*" -->
        <RowDefinition Height="Auto"/> <!-- the Row's Height is based on the highest control in this row -->
        <RowDefinition Height="Auto"/> <!-- the Row's Height is based on the highest control in this row -->
        <RowDefinition Height="Auto"/> <!-- the Row's Height is based on the highest control in this row -->
        <RowDefinition Height="Auto"/> <!-- the Row's Height is based on the highest control in this row -->
        <RowDefinition/> <!-- you can also write Height="*" -->
    </Grid.RowDefinitions>
    <Grid Grid.Row="1" Grid.Column="1" Background="red"> <!-- Just to have a container. In your example this is the UserControl -->
        <TextBox />
    </Grid>
    <TextBox Grid.Row="2" Grid.Column="1"/>
    <TextBox Grid.Row="3" Grid.Column="1"/>

</Grid>

0
votes

Turns out it was a scaling issue.

I had custom text scaling (115%) on the underlying OS (win7) and when drawing the usercontrol into the old-style COM usercontrol, the size of the wpf usercontrol textbox was being rendered too small. If I reset the custom scaling to 100% it all works fine.