如何覆盖Silverlight ListBox的默认行为?

时间:2010-08-18 20:34:57

标签: silverlight

当单击显示的列表项时,Silverlight ListBox控件会自动移动滚动框(如果列表框显示5个项目,则单击最后一个项目,所有项目都向下移动一个项目)。我的QA团队有一个错误告诉我,这会导致我们的具体情况混乱。如何覆盖此行为?

    <ListBox x:Name="accountsListBox" Margin="8,65,8,8" SelectionChanged="accountsListBox_SelectionChanged" VirtualizingStackPanel.VirtualizationMode="Recycling">
                    <ListBox.BorderBrush>
                        <LinearGradientBrush EndPoint="0.5,1" StartPoint="0.5,0">
                            <GradientStop Color="Black" Offset="0"/>
                            <GradientStop Color="Silver" Offset="1"/>
                        </LinearGradientBrush>
                    </ListBox.BorderBrush>
                    <ListBox.ItemTemplate>
                        <DataTemplate>
                            <TextBlock Height="19" Text="{Binding}"/>
                        </DataTemplate>
                    </ListBox.ItemTemplate>
                </ListBox>

    public partial class MainPage : UserControl
    {
        public MainPage()
        {
            InitializeComponent();
            Loaded += new RoutedEventHandler(MainPage_Loaded);
        }

        void MainPage_Loaded(object sender, RoutedEventArgs e)
        {
            List<string> names = new List<string>();
            for (int i = 0; i < 100; i++)
            {
                names.Add("Name " + i);
            }

            this.accountsListBox.ItemsSource = names;

        }

        private void accountsListBox_SelectionChanged(object sender, SelectionChangedEventArgs e)
        {
// this was an attempt but causes other unwanted behavior
            //int selectedIndex = this.accountsListBox.SelectedIndex;
            //this.accountsListBox.UpdateLayout();
            //this.accountsListBox.ScrollIntoView(this.accountsListBox.Items[this.accountsListBox.SelectedIndex - 4]);
            //this.accountsListBox.SelectedIndex = selectedIndex;
        }
    }

2 个答案:

答案 0 :(得分:2)

无需覆盖此行为。这不是一个错误,而是一个用于将部分显示列表项目滚动到视图中的功能。

自动滚动行为是由列表框不足以容纳5个项目引起的(即使它可能看起来如此)。使列表框高几个像素,问题就会消失。

希望这有帮助。

答案 1 :(得分:0)

如果要阻止ListBox自动滚动以显示整个所选项目,请为其ScrollViewer指定自定义样式(请参见下文),并在模板中为垂直滚动条指定上下边距为1000.接下来,为列表框提供1000的上下边距,并将其样式设置为使用修改后的scrollviewer样式的样式。然后,剪切列表框(如下所示),以便它不会掩盖其上方的任何内容。最后,每当您向列表框添加项目时,首先添加一个高度为1000的空ListBoxItem,然后在项目末尾追加另一个空的ListBoxItem,其高度为1000.

<Style x:Key="ScrollViewerStyleForWhiteBg" TargetType="ScrollViewer">
        <Setter Property="VerticalScrollBarVisibility" Value="Auto"/>
        <Setter Property="HorizontalScrollBarVisibility" Value="Disabled"/>
        <Setter Property="Background" Value="Transparent"/>
        <Setter Property="Padding" Value="0"/>
        <Setter Property="BorderThickness" Value="0"/>
        <Setter Property="BorderBrush" Value="Transparent"/>
        <Setter Property="Template">
            <Setter.Value>
                <ControlTemplate TargetType="ScrollViewer">
                    <Border BorderBrush="{TemplateBinding BorderBrush}" BorderThickness="{TemplateBinding BorderThickness}" Background="{TemplateBinding Background}">
                        <VisualStateManager.VisualStateGroups>
                            <VisualStateGroup x:Name="ScrollStates">
                                <VisualStateGroup.Transitions>
                                    <VisualTransition GeneratedDuration="00:00:00.5"/>
                                </VisualStateGroup.Transitions>
                                <VisualState x:Name="Scrolling">
                                    <Storyboard>
                                        <DoubleAnimation Duration="0" To="1" Storyboard.TargetProperty="Opacity" Storyboard.TargetName="VerticalScrollBar"/>
                                        <DoubleAnimation Duration="0" To="1" Storyboard.TargetProperty="Opacity" Storyboard.TargetName="HorizontalScrollBar"/>
                                    </Storyboard>
                                </VisualState>
                                <VisualState x:Name="NotScrolling"/>
                            </VisualStateGroup>
                        </VisualStateManager.VisualStateGroups>
                        <Grid Margin="{TemplateBinding Padding}">
                            <ScrollContentPresenter x:Name="ScrollContentPresenter" ContentTemplate="{TemplateBinding ContentTemplate}" Content="{TemplateBinding Content}"/>
                            <ScrollBar x:Name="VerticalScrollBar" Margin="0,1000,0,1000" HorizontalAlignment="Right" Height="Auto" IsHitTestVisible="False" IsTabStop="False" Maximum="{TemplateBinding ScrollableHeight}" Minimum="0" Opacity="0" Orientation="Vertical" Visibility="{TemplateBinding ComputedVerticalScrollBarVisibility}" Value="{TemplateBinding VerticalOffset}" ViewportSize="{TemplateBinding ViewportHeight}" VerticalAlignment="Stretch" Width="5" Background="Red" />
                            <ScrollBar x:Name="HorizontalScrollBar" HorizontalAlignment="Stretch" Height="5" IsHitTestVisible="False" IsTabStop="False" Maximum="{TemplateBinding ScrollableWidth}" Minimum="0" Opacity="0" Orientation="Horizontal" Visibility="{TemplateBinding ComputedHorizontalScrollBarVisibility}" Value="{TemplateBinding HorizontalOffset}" ViewportSize="{TemplateBinding ViewportWidth}" VerticalAlignment="Bottom" Width="Auto" />
                        </Grid>
                    </Border>
                </ControlTemplate>
            </Setter.Value>
        </Setter>
    </Style>
<Style x:Key="ListBoxStyleForReader" TargetType="ListBox">
        <Setter Property="Padding" Value="0"/>
        <Setter Property="Foreground" Value="Black"/>
        <Setter Property="BorderThickness" Value="0"/>
        <Setter Property="Background" Value="Transparent"/>
        <Setter Property="BorderBrush" Value="Transparent"/>
        <Setter Property="ScrollViewer.VerticalScrollBarVisibility" Value="Auto"/>
        <Setter Property="ScrollViewer.HorizontalScrollBarVisibility" Value="Disabled"/>
        <Setter Property="Template">
            <Setter.Value>
                <ControlTemplate TargetType="ListBox">
                    <ScrollViewer x:Name="ScrollViewer" BorderBrush="{TemplateBinding BorderBrush}" BorderThickness="{TemplateBinding BorderThickness}" Background="{TemplateBinding Background}" Foreground="{TemplateBinding Foreground}" Padding="{TemplateBinding Padding}"
                                  Style="{StaticResource ScrollViewerStyleForWhiteBg}">
                        <ItemsPresenter />
                    </ScrollViewer>
                </ControlTemplate>
            </Setter.Value>
        </Setter>
    </Style>
<ListBox x:Name="_myList" Margin="0,-1000,0,-1000" Style="{StaticResource ListBoxStyleForReader}">
                <ItemsControl.ItemsPanel>
                    <ItemsPanelTemplate>
                        <StackPanel Orientation="Vertical"/>
                    </ItemsPanelTemplate>
                </ItemsControl.ItemsPanel>
            <ListBox.Clip>
                <RectangleGeometry Rect="0,1000,480,10000" />
            </ListBox.Clip>
        </ListBox>
_myList.Insert(0, new ListBoxItem() { Height = 1000 });
_myList.Add(new ListBoxItem() { Height = 1000 });