You have to use ScrollBar
instead of ScrollViewer
because ScrollViewer
can't tell when it reaches the end of its content. (or at least I haven't seen a reliable method for doing so). On the other hand ScrollBar
is more suitable for these kinds of operations.
I used a ListBox with several items to test this behavior. you can change it to whatever you need.
Xaml :
<Grid>
<ListBox ScrollBar.Scroll="ListBox_Scroll">
<!-- add many items here -->
<TextBlock Text="something"/>
</ListBox>
<Image Source="Shadow.png" VerticalAlignment="Top">
<Image.Style>
<Style TargetType="Image">
<Style.Triggers>
<DataTrigger Binding="{Binding ScrollerState}"
Value="{x:Static enum:ScrollState.AtTheTop}">
<Setter Property="Visibility" Value="Collapsed" />
</DataTrigger>
</Style.Triggers>
</Style>
</Image.Style>
</Image>
<Image Source="Shadow.png" VerticalAlignment="Bottom">
<Image.Style>
<Style TargetType="Image">
<Style.Triggers>
<DataTrigger Binding="{Binding ScrollerState}"
Value="{x:Static enum:ScrollState.AtTheBottom}">
<Setter Property="Visibility" Value="Collapsed" />
</DataTrigger>
</Style.Triggers>
</Style>
</Image.Style>
</Image>
</Grid>
As you can see I changed the trigger to DataTrigger
and used a bindable property in DataContext (named ScrollerState
with type of ScrollState
which is a simple enum) to bind to.
enum:
public enum ScrollState
{
AtTheTop, AtTheBottom, InBetween
}
Now in Code behind we implement the Scroll event from where we change the value of ScrollerState
:
public MainWindow()
{
InitializeComponent();
DataContext = new VM();
}
private void ListBox_Scroll(object sender, ScrollEventArgs e)
{
ScrollBar sb = e.OriginalSource as ScrollBar;
if (sb.Orientation == Orientation.Horizontal)
return;
if (sb.Value == 0)
(DataContext as VM).ScrollerState = ScrollState.AtTheTop;
else if (sb.Value == sb.Maximum)
(DataContext as VM).ScrollerState = ScrollState.AtTheBottom;
else
(DataContext as VM).ScrollerState = ScrollState.InBetween;
}
VM (an instance of this is set as DataContext of the window):
public class VM : DependencyObject
{
public ScrollState ScrollerState
{
get { return (ScrollState)GetValue(ScrollerStateProperty); }
set { SetValue(ScrollerStateProperty, value); }
}
public static readonly DependencyProperty ScrollerStateProperty =
DependencyProperty.Register("ScrollerState", typeof(ScrollState), typeof(VM),
new PropertyMetadata(ScrollState.AtTheTop));
}