我有ListBox和ScrollViewer
<ScrollViewer Focusable="False" CanContentScroll="True"
HorizontalScrollBarVisibility="Hidden" VerticalScrollBarVisibility="Disabled">
<ListBox ItemsSource="{Binding Path=MyItems}" VerticalAlignment="Stretch" Focusable="False">
<ListBox.ItemContainerStyle>
<Style TargetType="{x:Type ListBoxItem}">
<Setter Property="OverridesDefaultStyle" Value="true"/>
<Setter Property="HorizontalContentAlignment" Value="Stretch"/>
<Setter Property="VerticalContentAlignment" Value="Stretch"/>
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type ListBoxItem}">
<Border CornerRadius="3,3,3,3">
<Grid>
<myControls:MyControl/>
</Grid>
</Border>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
</ListBox.ItemContainerStyle>
<ListBox.Style>
<Style TargetType="ListBox">
<Setter Property="SnapsToDevicePixels" Value="true"/>
<Setter Property="OverridesDefaultStyle" Value="true"/>
<Setter Property="ScrollViewer.HorizontalScrollBarVisibility" Value="Auto"/>
<Setter Property="ScrollViewer.VerticalScrollBarVisibility" Value="Auto"/>
<Setter Property="ScrollViewer.CanContentScroll" Value="True"/>
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="ListBox">
<ScrollViewer Focusable="False" CanContentScroll="True">
<Border>
<StackPanel Margin="2" Orientation="Horizontal" IsItemsHost="True"/>
</Border>
</ScrollViewer>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
</ListBox.Style>
</ListBox>
</ScrollViewer>但是CanContentScroll=的“真”不起作用。它还在实体单位中滚动。我的代码有什么问题?谢谢!
发布于 2010-06-13 06:21:15
问题在于您的ScrollViewer和StackPanel之间的边界,这阻碍了ScrollViewer查找StackPanel。StackPanel实现了IScrollInfo接口来执行逻辑滚动,但是如果ScrollViewer找不到IScrollInfo子级,它就会返回到进行物理滚动。
在ScrollViewer中获得逻辑滚动有三种方法:
让ScrollViewer的直接子组件成为一个可以进行逻辑滚动的面板(例如StackPanel)
的自定义类
简单解决方案
前两个解决方案是不言自明的,但我想指出,使用ItemsPresenter可能比直接将StackPanel包含在模板中更好。这样,解决方案中的其他ListBoxes就可以利用您的ControlTemplate,而不必被迫使用相同的面板。换句话说,我会这样做,而不是你写的:
<ListBox>
<ListBox.ItemContainerStyle>
...
</ListBox.ItemContainerStyle>
<ListBox.ItemsPanel>
<ItemContainerTemplate>
<StackPanel Margin="2" Orientation="Horizontal" ... />
</ItemContainerTemplate>
</ListBox.ItemsPanel>
<ListBox.Template>
<ControlTemplate>
<ScrollViewer Focusable="False" CanContentScroll="True">
<ItemsPresenter />
</ScrollViewer>
</ControlTemplate>
</ListBox.Template>
</ListBox>先进技术
如果确实需要在逻辑滚动的StackPanel周围显示边框,但该边框似乎与数据一起滚动,则必须进行一些额外的管道处理。当StackPanel进行逻辑滚动时,StackPanel本身在排列期间滚动其内容,而ScrollViewer根本不执行任何实际滚动(它只是管理滚动条等)。您会发现StackPanel坚决拒绝滚动任何实际上不是它的子类的内容,所以除非您的边界可以是一个实际的ListBox项目,否则您需要稍微伪装一下。
为了使其看起来像一个边框与StackPanel内容一起滚动:
IScrollInfo.
可以通过在0和Items.Count-1上调用ItemContainerGenerator.ContainerFromIndex来检测StackPanel的滚动状态,然后检查这些容器在StackPanel中的位置,以确定它们是否可见。如果是这样的话,您的边界的顶部和底部(或Orientation=Horizontal的左边和右侧)应该是可见的,否则它们不应该是可见的。当然,其他方面总是可见的。
https://stackoverflow.com/questions/3029981
复制相似问题