使 WrapPanel 尊重其父级的宽度
好的,这是我的代码。请注意,StackPanel 直接位于 UserControl 中。
<UserControl>
<StackPanel Orientation="Horizontal">
<ScrollViewer Width="450"
VerticalScrollBarVisibility="Auto"
HorizontalScrollBarVisibility="Disabled">
<Rectangle Width="400" Height="4000" Fill="BlanchedAlmond"/>
</ScrollViewer>
<ScrollViewer VerticalScrollBarVisibility="Auto"
HorizontalScrollBarVisibility="Disabled">
<ItemsControl BorderBrush="Green"
BorderThickness="2"
ItemsSource="{Binding Path=MyObservableCollection}"
ItemTemplate="{StaticResource FatTemplate}">
<ItemsControl.ItemsPanel>
<ItemsPanelTemplate>
<WrapPanel Orientation="Horizontal"/>
</ItemsPanelTemplate>
</ItemsControl.ItemsPanel>
</ItemsControl>
</ScrollViewer>
</StackPanel>
</UserControl>
(代码已编辑)
请注意,矩形就在那里,因为滚动查看器的内容无关。
问题是 WrapPanel 只是水平扩展并且不换行...
我找到了一些解决方案:
为 WrapPanel 提供绝对宽度(但随后它不会随窗口调整大小)。
将宽度绑定到其父宽度 - ItemsControl 或 ScrollViewer(ScrollViewer 在像这样的有限情况下效果更好)。
Width="{绑定RelativeSource= {相对源查找祖先, AncestorType={x:Type ScrollViewer}}, 路径=实际宽度}”
此技术的问题在于,如果 StackPanel 或 Grid 中某个控件位于其旁边,则需要将其绑定到其父级大小减去其旁边的控件的大小。然后是困难的事情。我构建了一个转换器,它对收到的数字应用数学运算,这样我就可以从其父宽度中减去给定的宽度:
Width="{Binding RelativeSource=
{RelativeSource FindAncestor,
AncestorType={x:Type UserControl}},
Path=ActualWidth,
Converter={StaticResource Convertisseur_Size_WXYZ},
ConverterParameter=-260}"
但是,由于您无法将传递给 ConverterParameter 的值绑定,
ConverterParameter={Binding ...} (doesn't work)
我希望:
- 能够调整我的大小我的 WrapPanel 和 ScrollViewer 大小调整得很好,
- 我的 UserControl 易于维护,
- 我的代码比这些依赖于父控件类型的大绑定表达式更干净。
什么是更好的解决方案?
注意:如果有任何不清楚的地方,我可以添加详细信息。
Ok here's my code. Note that the StackPanel is directly in a UserControl.
<UserControl>
<StackPanel Orientation="Horizontal">
<ScrollViewer Width="450"
VerticalScrollBarVisibility="Auto"
HorizontalScrollBarVisibility="Disabled">
<Rectangle Width="400" Height="4000" Fill="BlanchedAlmond"/>
</ScrollViewer>
<ScrollViewer VerticalScrollBarVisibility="Auto"
HorizontalScrollBarVisibility="Disabled">
<ItemsControl BorderBrush="Green"
BorderThickness="2"
ItemsSource="{Binding Path=MyObservableCollection}"
ItemTemplate="{StaticResource FatTemplate}">
<ItemsControl.ItemsPanel>
<ItemsPanelTemplate>
<WrapPanel Orientation="Horizontal"/>
</ItemsPanelTemplate>
</ItemsControl.ItemsPanel>
</ItemsControl>
</ScrollViewer>
</StackPanel>
</UserControl>
(Code EDITED)
Note that the rectangle is just there because the content of that scroll viewer is irrelevant.
The problem is that the WrapPanel just expands horizontally and doesn't wrap...
I found a few solutions:
Giving absolute width to the WrapPanel (but then it doesn't resize with the window).
Binding width to its parent width - either ItemsControl or ScrollViewer (ScrollViewer worked better in a limited situation like this one).
Width="{Binding RelativeSource= {RelativeSource FindAncestor, AncestorType={x:Type ScrollViewer}}, Path=ActualWidth}"
The problem with this technique is that if a control is beside it in a StackPanel or Grid, you need to bind it to it's parent size minus the control next to it. Then comes the hard stuff. I built a converter which applies mathematical operations on the number received so I could subtract a given width from its parent width:
Width="{Binding RelativeSource=
{RelativeSource FindAncestor,
AncestorType={x:Type UserControl}},
Path=ActualWidth,
Converter={StaticResource Convertisseur_Size_WXYZ},
ConverterParameter=-260}"
But still, since you can't bind a value you pass to a ConverterParameter,
ConverterParameter={Binding ...} (doesn't work)
I want:
- to be able to resize my app with my WrapPanel and ScrollViewer resizing well,
- my UserControl to be easily maintainable,
- my code cleaner than these big binding expressions which rely on parent control's Type.
What's a better solution?
Note: If anything isn't clear, I can add detail.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
当
ScrollViewer
允许水平滚动时,为什么它会换行?您应该在ScrollViewer
中禁用水平滚动:编辑后编辑:这是因为您的
StackPanel
是水平方向的。水平方向的 StackPanel 将为其子级提供其请求的任何宽度 - 它根本不会限制它。使用正确的面板,一切都会好起来的。可能您只需要一个包含两列的Grid
。Why would it wrap when the
ScrollViewer
allows horizontal scrolling? You should disable horizontal scrolling in theScrollViewer
:EDIT AFTER YOUR EDIT: It's because your
StackPanel
is oriented horizontally. A horizontally-orientedStackPanel
will give whatever width its child requests to it - it won't constrain it at all. Use the right panel, and you'll be fine. Likely you just want aGrid
with two columns.