ListBox Scrollviewer Weird behavior

I have ScrollViewer in the ControlTemplate of my ListBox and I am using .Net 4.0 I am facing two issues on different values of CanContentScroll.

  1. when CanContentScroll is True.

    In this case, when I scroll through ListBox with a mouse, ScrollViewer seems to skip 1 or 2 items randomly out of the view. But SelectedItem's selection works properly.

  2. when CanContentScroll is False.

    In this case, scrolling with mouse works fine. but now SelectedItem's selection does not select the actual SelectedItem, but selects the item above or below of it. or continues to display previously SelectedItem.

please help me out.

<Style TargetType="ListBox" x:Key="ListBoxStyle">
        <Setter Property="ItemContainerStyle" Value="{StaticResource ItemContainerStyle}"/>
        <Setter Property="Template">
            <Setter.Value>
                <ControlTemplate TargetType="ListBox">
                    <ScrollViewer CanContentScroll="True">
                        <ItemsPresenter/>
                    </ScrollViewer>
                </ControlTemplate>
            </Setter.Value>
        </Setter>
    </Style>

ItemContainerSTyle:

<Style x:Key="ItemContainerStyle" BasedOn="{StaticResource listBoxItemStyle}" TargetType="ListBoxItem">
        <Setter Property="helper:FluidSelectionAttachedPropertyHelper.IgnoreRightClick" Value="True"/>
        <Style.Triggers>
            <Trigger Property="IsSelected" Value="True">
                <Setter Property="Visibility" Value="Collapsed" />
            </Trigger >
        </Style.Triggers>
    </Style>

ItemTemplate:

<Style TargetType="ListBoxItem" x:Key="listBoxItemStyle">
        <Setter Property="Template">
            <Setter.Value>
                <ControlTemplate TargetType="ListBoxItem">
                    <ContentPresenter Margin="2"/>
                </ControlTemplate>
            </Setter.Value>
        </Setter>
    </Style>

Answers


The weird behaviour that you describe is exactly what you asked for using your bizarre ItemContainerStyle:

<Style x:Key="ItemContainerStyle" BasedOn="{StaticResource listBoxItemStyle}" 
    TargetType="ListBoxItem">
    <Style.Triggers>
        <Trigger Property="IsSelected" Value="True">
            <Setter Property="Visibility" Value="Collapsed" />
        </Trigger >
    </Style.Triggers>
</Style>

Here, you set the items to disappear when they are selected.

For your other, scrolling problem, I would advise you to read the ScrollViewer.CanContentScroll Property page on MSDN as it seems to be working just fine in my opinion:

The default behavior of the ScrollViewer is to use physical units to scroll its content. However, in cases where the CanContentScroll is set to true, the content could use logical units to scroll.

It should be noted that it can be difficult to spot the difference between these two settings if the items are just string based.


Thanks for all responses. I found out the solution to alter scroll viewer's vertical scroll speed keeping CanContentScroll is True.

I used attached property to my scroll viewer listbox template and override its PreviewMouseWheel event with following handler method:

static void scrollViewer_MouseWheel(object sender, System.Windows.Input.MouseWheelEventArgs e)
        {
            var scrollViewer = sender as ScrollViewer;
            if (scrollViewer != null)
            {
                var newOffset = scrollViewer.VerticalOffset;
                if (newOffset < 0 || scrollViewer.ViewportHeight >= scrollViewer.ExtentHeight)
                {
                    newOffset = 0;
                    scrollViewer.ScrollToVerticalOffset(newOffset);
                }
                else if (newOffset + scrollViewer.ViewportHeight >= scrollViewer.ExtentHeight)
                {
                    newOffset = scrollViewer.ExtentHeight - scrollViewer.ViewportHeight;
                    if (e.Delta > 0)
                    {
                        scrollViewer.ScrollToVerticalOffset(newOffset - 1);
                    }
                }
                else
                {
                    if (e.Delta > 0)
                    {
                        scrollViewer.ScrollToVerticalOffset(newOffset - 1);
                    }
                    else
                    {
                        scrollViewer.ScrollToVerticalOffset(newOffset + 1);
                    }

                }
                e.Handled = true;
            }
        }

Need Your Help

Checking the referrer

javascript referrer

I'm using this to check if someone came from Reddit, however it doesn't work.

Parse json and choose items\keys upon condition

json rest parsing if-statement condition

I'm trying to parse a json file that I get from a certain REST API.