首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >ListBox,ScrollViewerиCanContentScroll

ListBox,ScrollViewerиCanContentScroll
EN

Stack Overflow用户
提问于 2010-06-12 20:25:26
回答 1查看 1.9K关注 0票数 2

我有ListBox和ScrollViewer

代码语言:javascript
复制
<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=的“真”不起作用。它还在实体单位中滚动。我的代码有什么问题?谢谢!

EN

回答 1

Stack Overflow用户

发布于 2010-06-13 06:21:15

问题在于您的ScrollViewer和StackPanel之间的边界,这阻碍了ScrollViewer查找StackPanel。StackPanel实现了IScrollInfo接口来执行逻辑滚动,但是如果ScrollViewer找不到IScrollInfo子级,它就会返回到进行物理滚动。

在ScrollViewer中获得逻辑滚动有三种方法:

让ScrollViewer的直接子组件成为一个可以进行逻辑滚动的面板(例如StackPanel)

  • Let,
  1. 的直接子组件是一个显示这样一个面板的ItemsPresenter
  2. ,让ScrollViewer的直接子类是您自己编写的实现IScrollInfo

的自定义类

简单解决方案

前两个解决方案是不言自明的,但我想指出,使用ItemsPresenter可能比直接将StackPanel包含在模板中更好。这样,解决方案中的其他ListBoxes就可以利用您的ControlTemplate,而不必被迫使用相同的面板。换句话说,我会这样做,而不是你写的:

代码语言:javascript
复制
<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.

  • Give

  • 创建一个"CompoundScrolling“自定义控件来管理它,该控件实现了"CompoundScrolling”控件--一个包含网格的模板。网格中的

  • 通过调用StackPanel上的等效方法,将边框和StackPanel放在边框和适当的边框中,从而在StackPanel上调用等效的方法(您可以给它一个PART_名称,并在OnApplyTemplate)

  • Whenever IScrollInfo方法中找到它的代理,也可以在OnMeasure、OnArrange等,等等),检查StackPanel的滚动状态,并更新边界的匹配位置。

可以通过在0和Items.Count-1上调用ItemContainerGenerator.ContainerFromIndex来检测StackPanel的滚动状态,然后检查这些容器在StackPanel中的位置,以确定它们是否可见。如果是这样的话,您的边界的顶部和底部(或Orientation=Horizontal的左边和右侧)应该是可见的,否则它们不应该是可见的。当然,其他方面总是可见的。

票数 3
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/3029981

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档