Winforms / WPF interop - изменение размера вложенного usercontrol - PullRequest
0 голосов
/ 18 октября 2018

У меня есть wincont usercontrol, который содержит элемент host, который сам содержит wpf usercontrol, который содержит текстовое поле.

Похоже, у меня не работает изменение размера самого внутреннего текстового поля.В идеале размер должен был бы изменить размер для заполнения элемента-элемента, а сам размер был бы изменен для заполнения пользовательского элемента управления winforms при его изменении.

Пользовательский элемент управления winforms имеет следующий код конструктора

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);
    }

    ...

Обратите внимание, что свойство Dock имеет видзадано значение Fill

Я также попытался обработчик изменения размера в пользовательском контроле Winforms

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

, поскольку при трассировке по высоте и ширине текстовое поле wpf всегда меньше

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

Это, кажется, отражается, когда он используется (см. Рис. 3 ниже) - хотя я действительно задавался вопросом, были ли единицы измерения одинаковыми для всех трех элементов управления.

WAPF usercontrol xaml выглядит так

<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"
         >
...

, а в текстовом поле xaml для высоты и ширины установлено значение «Авто».Я также попытался установить горизонтальное / вертикальное выравнивание и ContentAlignment в значение Stretch.

Когда это отображается, оно изначально выглядит так.(Я поместил 2 одинакового размера, чтобы показать изменения)

enter image description here

Изначально верхний фокус имеет фокус, но если я убираю фокус с него, он изменяет размер дото, что выглядит как текст (хотя я явно установил для Autosize значение false).

enter image description here

Если я запутался в цвете фона, он выглядит следующим образомэто, кажется, показывает различный размер текстового поля для его контейнеров с полями внизу и слева

enter image description here

В идеале все элементы управления должны быть одинаковымиразмер (и тот же цвет спины!).

Я не очень знаком с wpf, поэтому мне интересно, если кто-то может указать на мою ошибку.

EDIT-1: Так что я все ещепытаясь понять, в чем проблема на самом деле!

Если я обновляю задний цвет пользовательского элемента управления winforms и не изменяю фон пользовательского элемента управления или текстового поля XAML, это выглядит так, когда текстовое поле не есть фокус

enter image description here

However, когда он получает фокус, он выглядит так, как будто wpfusercontrol / textbox расширяется, чтобы заполнить контейнер winforms usercontrol - таким образом:

enter image description here

и затем при потере фокуса, он возвращается к своему предыдущему размеру, снова раскрывая фон пользовательского контроля winforms.

Я не совсем понимаю, поскольку, когда я проследил ширину и высоту элемента-элемента, его размер был таким же, как в пользовательском контроле winforms.Я дал wpf usercontrol свой собственный цвет фона, но я никогда не вижу того, что, на мой взгляд, указывает на то, что текстовое поле действительно правильно заполняет wpf usercontrol.Просто кажется, что wpf usercontrol / textbox изменяет размер в точках, которых я не ожидаю.

Это ожидаемое поведение?

Thx снова.

Ответы [ 2 ]

0 голосов
/ 22 октября 2018

Оказывается, это была проблема с масштабированием.

У меня было пользовательское масштабирование текста (115%) в базовой ОС (win7) и при рисовании пользовательского контроля в пользовательском контроле COM старого стиля, размерТекстовое поле wpf usercontrol отображалось слишком маленьким.Если я сбрасываю пользовательское масштабирование до 100%, все работает нормально.

0 голосов
/ 18 октября 2018

В WPF вы обычно работаете с Styles, Templates и Custom Controls.Есть много учебников для них, и я рекомендую взглянуть на них.UserControls не так гибки, как они, и обычно используются для создания больших пользовательских интерфейсов, которые не должны быть такими гибкими.Например, чтобы создать форму.

В идеале все элементы управления должны быть одинакового размера (и с одинаковым цветом спины!).

В этом случае я бы порекомендовал вам использовать Style.

Здесь объясняется, как работают Auto и * и как вы можете использовать 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>

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...