c# - Winforms/WPF 互操作 - 调整嵌套用户控件的大小
问题描述
我有一个 winforms 用户控件,其中包含一个元素主机,该主机本身包含一个 wpf 用户控件,其中包含一个文本框。
似乎我没有调整最里面的文本框的大小正常工作。理想情况下,它会调整大小以填充元素主机,并且它本身会在调整大小时调整大小以填充 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)——尽管我确实想知道所有 3 个控件的测量单位是否相同。
wpf 用户控件 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 个相同尺寸来显示变化)
最初顶部有焦点,但如果我将焦点从它移开,它会调整为看起来是文本的大小(即使我已明确将 Autosize 设置为 false)。
如果我弄乱了背景颜色,它看起来像这样,它似乎向其容器显示了不同大小的文本框,底部和左侧有边距
理想情况下,所有控件的大小都相同(并且背景颜色相同!)。
我对 wpf 不是很熟悉,所以我想知道是否有人能指出我的错误。
EDIT-1:所以我仍在努力找出问题所在!
如果我更新 winforms 用户控件的背景色而不更改 XAML 用户控件或文本框的背景,当文本框没有焦点 时,它看起来像这样
但是,当它获得焦点时,看起来 wpfusercontrol/文本框会扩展以填充 winforms 用户控件容器 - 因此:
然后在失去焦点时,它会返回到以前的大小,再次显示 winforms 用户控件的背景。
我不太明白,因为当我跟踪元素主机的宽度和高度时,它的大小与 winforms 用户控件相同。我已经给 wpf 用户控件赋予了它自己的背景颜色,但我从来没有看到我认为文本框实际上正确填充了 wpf 用户控件。似乎 wpf 用户控件/文本框在我没想到的地方调整大小。
这是预期的行为吗?
再次感谢。
解决方案
在 WPF 中,您通常使用Styles
,Templates
和Custom Controls
. 这些有很多教程,我建议看看这些。 UserControls
不如这些灵活,通常用于创建不必那么灵活的大型 UI。例如创建一个表格。
理想情况下,所有控件的大小都相同(并且背景颜色相同!)。
在这种情况下,我建议您使用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>
推荐阅读
- c# - C# Unity:消息/事件系统的动态使用
- firebase - firebase 是否将多个云功能放在一个容器中?或者每个容器用于不同的功能?
- html - 是否可以使用 CSS 网格完全自由地漫游/放置我的 DOM 元素?
- javascript - Express.json 不解析 POST 正文 - 未定义
- amazon-web-services - AWS Glue 的工作原理是什么?
- c# - 将 DataGrid 表调整为窗口大小,并为窗口大小之外的数据使用滚动条 - 永远不会显示滚动条
- node.js - Heroku 调度程序问题:每隔一天跳过每日作业 - 节点 JS *已解决*
- excel - 根据单元格值隐藏一行
- graph - 如何在 x 轴值的特定范围内绘制 yline?
- django-rest-framework - 在 Django rest 框架中更新用户信息权限