WPF ContentControl 宽度会增加,但在包裹在 ScrollViewer 中时不会缩小
Posted
技术标签:
【中文标题】WPF ContentControl 宽度会增加,但在包裹在 ScrollViewer 中时不会缩小【英文标题】:WPF ContentControl width grows but doesn't shrink when wrapped in a ScrollViewer 【发布时间】:2014-02-14 15:03:08 【问题描述】:我试图弄清楚如何让我的ContentControl
正确地水平滚动(目前垂直滚动很好)。正确地说,我的意思是我希望看到要拉伸(无限扩展)的内容,同时具有滚动条出现的最小尺寸,以便内容不会在ContentControl
的区域后面溢出,所以这里有一个快速介绍:
主窗口的结构如下:
网格(2 列 .3* 和 .7*) 边框 网格(7 行,一组设置为 * ContentControl 所在的位置) 带有 StackPanel 的 ScrollViewer(纯粹用于测试)包装了具有 Auto Width 的 ContentControlContentControl
的模板:
实际的问题是 ContentControl 会随着您调整窗口大小而增长,但不会随着窗口大小调整而缩小。
主视图 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(为清楚起见截断):
<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>
那么会发生什么? Datagrid
假定整个 DataTemplate
的宽度(以及它的底层控件设置为 DataTemplates
大小,然后 * 列假定所有空白空间。当您尝试调整包含此代码的整个窗口的大小时,它将正确增长, 扩展 * 列,但它似乎没有“注册”收缩,它保持你扩展它的大小,在上面应用滚动条并忘记它。
到目前为止,我尝试的是为 ItemsControl
设置宽度,它的底层父级如 Grid 等,还将大小设置为 ContentControl
、StackPanel
、ScrollViewer
和父级 Grid。
我还尝试在Datagrid
上直接使用scrollviewer
s,这会产生癫痫“每秒调整一百万”的场景。我也玩过HorizontalAlignments
在某些情况下,我确实设法让水平滚动条正确显示,但不幸的是,这使我的DataGrid
的 * 列假设Auto
宽度而不是Star
所以DataGrid
开始在右侧有一个空白区域(不幸的是无法接受...)
我知道为了让水平滚动条工作,滚动查看器的父级或子级需要设置宽度,我想我无法确定我需要在哪里限制它。 DataGrids 需要随着主窗口无限扩展,同时让第一列填满所有可用空间。 如果您需要这方面的更多信息,请立即告诉我,我会很乐意回答。
【问题讨论】:
将 Grid 的宽度提供给 ContentControl 会做出正确的反应,但是一旦达到最小尺寸,模板就会溢出并且不会出现滚动条,给它一个HorizontalAlignment="Stretch"
什么都不做,删除 ScrollViewer.CanContentScroll="False"
也是如此
老兄……这太长了……我们不需要你的生活史,只需要relevant part of your program。
如何详细解释一个问题,以便人们更好地理解它的生活故事?由于未知问题的来源,必须放入大量代码。我想我会削减 sn-ps...
原谅我的措辞...我只是给你很好的建议来帮助你回答你的问题。这里的许多用户会看到您的问题持续了多长时间,然后简单地转到下一个问题。 +1 虽然做得更简洁,但做得很好。
别担心!我在想这不是一件容易的事,所以决定详细说明这个场景。
【参考方案1】:
在我看来,这只是另一个可怕的StackPanel
布局问题的案例。这个问题一次又一次地出现,我承认我在开始学习 WPF 时遇到了同样的问题。 StackPanel
确实不考虑其父级的可用大小,而其他Panel
s,例如DockPanel
或Grid
(是的,这实际上也是Panel
)做。
在 MSDN 的How to: Choose Between StackPanel and DockPanel 页面中有解释:
虽然您可以使用 DockPanel 或 StackPanel 来堆叠子元素,但这两个控件并不总是产生相同的结果。例如,放置子元素的顺序会影响 DockPanel 中子元素的大小,但不会影响 StackPanel 中的大小。出现这种不同的行为是因为 StackPanel 在 Double.PositiveInfinity 的堆叠方向上测量;但是,DockPanel 仅测量可用大小。
StackPanel
只应真正用于对齐多个项目,例如Button
s 或其他控件,可用空间不是问题。所以无论如何,解决方案应该很简单......只需从ScrollViewer
中删除StackPanel
。无论如何,它似乎没有任何用途。
更新>>>
再看一遍,你的意思好像是问题出在内部DataTemplate
,对吧?您可能可以通过将ItemsControl.HorizontalContentAlignment
属性设置为Stretch
来解决此问题。这将确保每个项目都保持在ItemsControl
的边界内。
我还将删除您在 Grid.Width
上的 Binding
,因为您不需要它...默认情况下,子 Grid
将占用父 Grid
的全部空间。如果这些想法不起作用,只需简化您的问题。说真的,如果您遵循我在 cmets 中提供的帮助中心链接页面中的建议,那么您将解决问题,或者能够回到这里并提供一个完整但简洁的示例,我们可以测试。
【讨论】:
是的,我已经添加了stackpanel作为测试,用一个网格替换它似乎有相似的结果,但略有不同,ScrollBar
出现时最多有1个像素,不幸的是没有能够缩小ContentControl
问题仍然存在。删除它与在那里拥有Grid
没有区别。还没有尝试过DockPanel
,因为我个人避免使用它,但我还是会试一试。睡一觉后我会尝试制作一个小重现应用程序,看看这是否会更有意义,也许这会更准确地查明问题出在哪里
问题是Grid.Width
。不幸的是,删除它会使Datagrid
s 中的所有Star
列都采用自动大小,这是我首先尝试解决的问题,因为第一列需要假设所有可用的屏幕空间。
我已经剥离了所有内容并了解到这只是一个典型问题,即如果存在任何 Star Width 列,则 ScrollViewer 元素内的 DataGrids 将无法正确运行。这就是Grid.Width
被设置成这种方式的原因。我已经尝试了很多不同的解决方法,但都无济于事,我会继续寻找更多
似乎***.com/a/20120082/3008444 和在Datagrid 周围使用边框的类似方法会产生同样的问题,无论它是在ContentControl
的内部还是外部
***.com/a/17876732/3008444 看起来 mardok 也有同样的问题,无法收缩。【参考方案2】:
我通过使用UniformGrid
作为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>
正如@Sheridan 上面指出的那样,StackPanel
似乎正在造成麻烦。另外,感谢https://***.com/a/23375262/385273 指出UniformGrid
选项。
【讨论】:
以上是关于WPF ContentControl 宽度会增加,但在包裹在 ScrollViewer 中时不会缩小的主要内容,如果未能解决你的问题,请参考以下文章
WPF - 将 ContentControl 添加到自定义画布
[WPF自定义控件]从ContentControl开始入门自定义控件
带有 DataTemplate 的 ContentControl 不显示任何内容(WPF MVVM)