WPF 文本框和滚动行为
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/386039/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
WPF TextBox and Scroll behavior
提问by Oleg
I have a problem. I need to host grid with controls in ScrollViewer to prevent textbox from being either truncated or collapsed to zero-with at the UI. Also I want the with of textbox to be expanded when user change windows width. I'm setting Window's content to following code
我有个问题。我需要在 ScrollViewer 中托管带有控件的网格,以防止文本框在 UI 处被截断或折叠为零。我还希望在用户更改窗口宽度时扩展文本框。我正在将 Window 的内容设置为以下代码
<DockPanel>
<TreeView DockPanel.Dock="Left" Width="150"/>
<ScrollViewer VerticalScrollBarVisibility="Auto" HorizontalScrollBarVisibility="Auto">
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="Auto"/>
<ColumnDefinition />
</Grid.ColumnDefinitions>
<Grid.RowDefinitions>
<RowDefinition Height="Auto"/>
</Grid.RowDefinitions>
<TextBlock Text="Name"
Margin="5"
VerticalAlignment="Center"/>
<TextBox Grid.Column="1"
Text="Some Name"
Margin="5"
VerticalAlignment="Center"
MinWidth="200"/>
</Grid>
</ScrollViewer>
</DockPanel>
All work fine, but when user types very long text in TextBox it is being expanded and horizontal scroll appears. Is there any easy way to limit TextBox maximum width and allow it to be expanded only when user changes window size.
一切正常,但是当用户在 TextBox 中键入很长的文本时,它会被展开并出现水平滚动。有什么简单的方法可以限制 TextBox 的最大宽度,并仅在用户更改窗口大小时才允许扩展它。
回答by Robert Macnee
The problem is that the parent elements are providing TextBox with as much space as it thinks it needs, and when more text is present it will expand instead of staying at the initial automatic size.
问题是父元素为 TextBox 提供了它认为需要的空间,当出现更多文本时,它将扩展而不是保持初始自动大小。
One solution here is to make another auto-sized element and bind the TextBox.Width to it:
这里的一个解决方案是制作另一个自动调整大小的元素并将 TextBox.Width 绑定到它:
<DockPanel>
<TreeView Width="150" DockPanel.Dock="Left"/>
<ScrollViewer HorizontalScrollBarVisibility="Auto" VerticalScrollBarVisibility="Auto">
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="Auto"/>
<ColumnDefinition/>
</Grid.ColumnDefinitions>
<Grid.RowDefinitions>
<RowDefinition Height="Auto"/>
</Grid.RowDefinitions>
<TextBlock Margin="5" VerticalAlignment="Center" Text="Name"/>
<Border x:Name="b" Grid.Column="1" Margin="5"/>
<TextBox Width="{Binding ActualWidth, ElementName=b}"
MinWidth="200"
Grid.Column="1"
Margin="5"
VerticalAlignment="Center"
Text="Some Name"/>
</Grid>
</ScrollViewer>
</DockPanel>
Note that we set the Margin property of the auto-sizing element (the Border).This is important because if it's not set, there will be a loop:
请注意,我们设置了自动调整大小元素(边框)的 Margin 属性。这很重要,因为如果未设置,则会出现循环:
- Border width autosizes to Grid column width
- TextBox width resizes to Border.ActualWidth
- Grid column width resizes to TextBox width + TextBox margin
- Border width autosizes to Grid column width again
- 边框宽度自动调整为网格列宽
- 文本框宽度调整为 Border.ActualWidth
- 网格列宽调整为 TextBox 宽度 + TextBox 边距
- 边框宽度再次自动调整为网格列宽
By setting the Margin to the same as the TextBox, the resizing of the TextBox won't affect the Grid size.
通过将 Margin 设置为与 TextBox 相同,TextBox 的大小调整不会影响 Grid 大小。
回答by chickenpie
Overriding TextBox.MeasureOverride
like so worked for me:
TextBox.MeasureOverride
像这样覆盖对我有用:
protected override Size MeasureOverride(Size constraint)
{
Size origSize = base.MeasureOverride(constraint);
origSize.Width = MinWidth;
return origSize;
}
回答by Karl Xaml
no - this is a well known problem of wpf and is expected to be fixed in the next release. thanks
否 - 这是 wpf 的一个众所周知的问题,预计将在下一个版本中修复。谢谢