WPF ContentControl 宽度增加但在 ScrollViewer 中包装时不会缩小
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/21782730/
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 ContentControl width grows but doesn't shrink when wrapped in a ScrollViewer
提问by kosdos
I'm trying to figure out how to make my ContentControlto correctly scroll Horizontally (Vertically its fine at the moment). By correctly i mean i would like to see the content to stretch (expand infinitely) while having minimum sizes to which a scrollbar would appear in order for the content not to overflow behind the ContentControl's area, so here's a quick introduction:
我试图弄清楚如何让我ContentControl正确地水平滚动(目前垂直滚动很好)。正确地说,我的意思是我希望看到内容可以拉伸(无限扩展),同时具有最小尺寸,滚动条会出现在最小尺寸上,以便内容不会溢出ContentControl's 区域后面,所以这里有一个快速介绍:
The main window is structured in this way:
主窗口的结构如下:
- Grid (2 columns of .3* and .7*)
- Border
- Grid (7 rows, one set to * where ContentControl is)
- ScrollViewer with StackPanel (purely for test) wrapping a ContentControl that has Auto Width
- Grid (7 rows, one set to * where ContentControl is)
- Border
- 网格(2 列 .3* 和 .7*)
- 边界
- 网格(7 行,一组设置为 * ContentControl 所在的位置)
- 带有 StackPanel(纯粹用于测试)的 ScrollViewer 包装了一个具有自动宽度的 ContentControl
- 网格(7 行,一组设置为 * ContentControl 所在的位置)
- 边界
ContentControl's Template:
ContentControl的模板:
- Grid (Width set to UserControl's ActualWidth, 6 rows with one set to Auto where ItemsControl go
- ItemsControl that describes an ItemTemplate of a type DataTemplate which contains a Grid inside of which i have a DataGrid
- 网格(宽度设置为 UserControl 的 ActualWidth,6 行,其中 ItemsControl 设置为 Auto
- ItemsControl 描述类型为 DataTemplate 的 ItemTemplate,其中包含一个网格,其中我有一个 DataGrid
The actual problem is that the ContentControl grows as you resize the window, but does not shrink with window resize.
实际问题是 ContentControl 会随着您调整窗口大小而增长,但不会随着窗口大小调整而缩小。
Main View XAML (truncated for clarity):
主视图 XAML(为清晰起见被截断):
<ScrollViewer Grid.Row="5" VerticalScrollBarVisibility="Auto" HorizontalScrollBarVisibility="Auto">
<ContentControl Grid.Row="5" Background="Transparent" Focusable="False" Margin="0,5,0,0"
Content="{Binding CurrentSection}" ContentTemplateSelector="{StaticResource templateSelector}/>
</ScrollViewer>
Tempate XAML (truncated for clarity):
Tempate XAML(为清晰起见被截断):
<Grid>
...
<ItemsControl Grid.Row="4" ItemsSource="{Binding Data.QualifyingDistributionsDividends}" x:Name="QualifyingItemsControl">
<ItemsControl.ItemTemplate>
<DataTemplate>
<Grid x:Name="DTLayoutGrid">
...
<Grid Grid.Row="1" x:Name="DataLayout" Width="{Binding ElementName=DTLayoutGrid, Path=ActualWidth}" HorizontalAlignment="Stretch">
...
<DataGrid Grid.Row="1" Grid.Column="0" Grid.ColumnSpan="8" HorizontalScrollBarVisibility="Disabled"
ItemsSource="{Binding Payments}" Style="{StaticResource DataGridStyle}" CellStyle="{StaticResource DataGridNormalCellStyle}">
</DataGrid>
</Grid>
</Grid>
</DataTemplate>
</ItemsControl.ItemTemplate>
</ItemsControl>
</Grid>
So what happens? Datagridassumes width of the entire DataTemplate(well its underlying controls that are set to be DataTemplatessize, then * column assumes all empty space. When you try to resize the entire window that holds this code it will grow correctly, expanding the * column but it seems shrinking is not "registered" and it keeps the size you expanded it to, applies a scrollbar over that and forgets about it.
那么会发生什么?Datagrid假定整个宽度DataTemplate(以及它的底层控件设置为DataTemplates大小,然后 * 列假定所有空白空间。当您尝试调整包含此代码的整个窗口的大小时,它将正确增长,扩展 * 列但它似乎缩小未“注册”,它保持您将其扩展到的大小,在其上应用滚动条并忘记它。
What i've tried so far was to set widths for ItemsControl, its underlying parents like Grid etc, also setting size to ContentControl, StackPanel, ScrollViewerand parent Grid of that.
I've also tried using scrollviewers directly on the Datagridwhich produces an epileptic "1 million resizes a second" scenario. I've also played around with HorizontalAlignmentsUnder certain situations i DID managed to get the horizontal scrollbar to appear correctly but unfortunately that makes my DataGrid's * column to assume AutoWidth rather then Starso DataGridstarts having an empty area to the right (unacceptable unfortunately...)
我已经试过到目前为止是为一组宽度ItemsControl,它的底层父母喜欢网等,还设置大小ContentControl,StackPanel,ScrollViewer那和家长电网。我还尝试scrollviewer直接在 s 上使用s ,Datagrid这会产生癫痫症“每秒调整 100 万次”的场景。我也玩过HorizontalAlignments在某些情况下,我确实设法让水平滚动条正确显示,但不幸的是,这使我DataGrid的 * 列假定为AutoWidth 而不是Star因此DataGrid开始在右侧有一个空白区域(不幸的是,这是不可接受的... )
I understand that in order for horizontal scrollbar to work the parent or child of the scrollviewer needs Width set, i guess i can't work out where exactly do i need to restrict it. DataGrids NEED to infinitely expand with the main window while having first column fill all the available space. Do let me now if you need more information on this and I will gladly answer.
我知道为了让水平滚动条工作,滚动查看器的父级或子级需要设置宽度,我想我无法弄清楚我到底需要在哪里限制它。DataGrids 需要随着主窗口无限扩展,同时让第一列填充所有可用空间。如果您需要更多信息,请现在告诉我,我会很乐意回答。
回答by Sheridan
It seems to me that this is just another case of the dreaded StackPanellayout problem. This problem comes up again and again and I confess that I had the very same problem when I started learning WPF. The StackPaneldoes nottake the available size of its parent into consideration whereas other Panels such as a DockPanelor a Grid(yes, that's actually a Paneltoo) do.
在我看来,这只是可怕的StackPanel布局问题的另一个例子。这个问题一次又一次地出现,我承认当我开始学习 WPF 时,我遇到了同样的问题。该StackPanel不会不采取其父的可用大小考虑,而其他PanelS,从而为一个DockPanel或一个Grid(是的,这实际上是一个Panel太)做的。
It's explained in the How to: Choose Between StackPanel and DockPanelpage on MSDN:
MSDN 上的“如何:在 StackPanel 和 DockPanel 之间选择”页面对此进行了解释:
Although you can use either DockPanel or StackPanel to stack child elements, the two controls do not always produce the same results. For example, the order that you place child elements can affect the size of child elements in a DockPanel but not in a StackPanel. This different behavior occurs because StackPanel measures in the direction of stacking at Double.PositiveInfinity; however, DockPanel measures only the available size.
尽管您可以使用 DockPanel 或 StackPanel 来堆叠子元素,但这两个控件并不总是产生相同的结果。例如,您放置子元素的顺序可能会影响 DockPanel 中子元素的大小,但不会影响 StackPanel 中的子元素大小。出现这种不同的行为是因为 StackPanel 在 Double.PositiveInfinity 的堆叠方向上进行测量;但是,DockPanel 仅测量可用大小。
The StackPanelshould only really be used to align a number of items, such as Buttons or other controls in a straight line where available space is nota concern. So anyway, the solution should be simple... just remove the StackPanelfrom the ScrollViewer. It doesn't appear to serve any purpose there anyway.
本StackPanel应只有真正被用于对准了一些项目,如Button在一条直线S或其他控件,其中可用空间是不是一个问题。所以无论如何,解决方案应该很简单……只需StackPanel从ScrollViewer. 无论如何,它似乎在那里没有任何用途。
UPDATE >>>
更新 >>>
After looking again, it seems as though you're saying that the problem is insidethe DataTemplate, right? You mightbe able to fix that by setting the ItemsControl.HorizontalContentAlignmentproperty to Stretch. That would ensure that each item remains within the boundary of the ItemsControl.
再次看后,好像你说的问题是内部的DataTemplate,对不对?您可以通过将ItemsControl.HorizontalContentAlignment属性设置为 来解决这个问题Stretch。这将确保每个项目保持在ItemsControl.
I'd also remove your Bindingon the Grid.Widthas you don't need it... a child Gridwill take up the full space of a parent Gridby default. If these ideas don't work, just simplify your problem. Seriously, if you follow the advise in the linked page from the Help Center that I gave you in the comments, then you'll either fix the problem, or be able to come back here and provide a complete, but concise example that we could test.
我也会删除你的Binding,Grid.Width因为你不需要它......默认情况下,孩子Grid会占据父母的全部空间Grid。如果这些想法不起作用,请简化您的问题。说真的,如果您遵循我在评论中给您的帮助中心链接页面中的建议,那么您要么解决问题,要么回到这里并提供一个完整但简洁的示例,我们可以测试。
回答by Ben
I've found the behavior I was looking for by using a UniformGridas the ItemsPanel, with its rows bound to the count of the ItemsSourcemodel:
我通过使用 aUniformGrid作为找到了我正在寻找的行为ItemsPanel,其行绑定到ItemsSource模型的计数:
<ScrollViewer>
<ItemsControl ItemsSource="{Binding MyCollection}">
<ItemsControl.ItemsPanel>
<ItemsPanelTemplate>
<UniformGrid Rows="{Binding MyCollection.Count}" />
</ItemsPanelTemplate>
</ItemsControl.ItemsPanel>
<ItemsControl.ItemTemplate>
<DataTemplate>
...
</DataTemplate>
</ItemsControl.ItemTemplate>
</ItemsControl>
</ScrollViewer>
As @Sheridan pointed out above, it seems the StackPanelis causing trouble. Also, credit to https://stackoverflow.com/a/23375262/385273for pointing out the UniformGridoption.
正如@Sheridan 上面指出的那样,这似乎StackPanel造成了麻烦。此外,感谢https://stackoverflow.com/a/23375262/385273指出该UniformGrid选项。

