Click here to Skip to main content
15,881,882 members
Please Sign up or sign in to vote.
0.00/5 (No votes)
I am trying to translate a forms app, to a wpf app, and I have to admit it is a real pain. Up to the point that I'm almost giving up.

One of my many problems is a basic one:

I hide the scrollbars for my listboxes and have an UP-Button and a DOWN-button next to the listbox.

With .NET FORMS, scrolling by clicking the button was easy by just setting the topindex of a listbox to the desired position.

How do I accomplish this same behaviour with WPF?
Posted

1 solution

I'm not familiar with VB, so I have a solution in C#.
Shouldn't be hard to translate in VB.

In the example some items are added to the listbox.
When the ListBox is Loaded, one listboxItem is measured.
The height of that listboxItem is then used to scroll up and down.

A better solution is to add a loaded event to one of the listboxItems and take the actualHeight of the Item.
If your Items are not the same height, measure every ListBoxItem and put those values in a list. Scroll according to the offsets in that list.

It's also possible to measure the position of the listboxItem relative to the ListBox.
Point relativePoint = ListBoxItem.TransformToAncestor(ListBoxTest) .Transform(new Point(0, 0));


XML
<Window x:Class="WpfApplication1.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        Title="MainWindow" Height="350" Width="525">
    <Grid>
        <Grid.ColumnDefinitions>
            <ColumnDefinition Width="auto"></ColumnDefinition>
            <ColumnDefinition></ColumnDefinition>
        </Grid.ColumnDefinitions>
        <StackPanel Orientation="Vertical">
            <Button MinWidth="100" Padding="5" Margin="5" Name="ButtonUp" Click="ButtonUp_Click">Up</Button>
            <Button MinWidth="100" Padding="5" Margin="5,0,5,5" Name="ButtonDown" Click="ButtonDown_Click">Down</Button>
        </StackPanel>
        <ScrollViewer Name="ScrollViewerTest" Grid.Column="1" VerticalScrollBarVisibility="Hidden" HorizontalScrollBarVisibility="Hidden">
            <ListBox Name="ListBoxTest" ScrollViewer.HorizontalScrollBarVisibility="Disabled" ScrollViewer.VerticalScrollBarVisibility="Disabled" Loaded="ListBoxTest_Loaded"/>
        </ScrollViewer>
    </Grid>
</Window>



C#
public partial class MainWindow : Window
    {
        public MainWindow()
        {
            InitializeComponent();
            PopulateListBox();
        }

        private void PopulateListBox()
        {
            ListBoxTest.Items.Clear();
            for (int i=0;i<100;i++)
                ListBoxTest.Items.Add(new ListBoxItem() { Content = "Item " + i.ToString() });
        }

        double ItemOffset=0;
        private void ButtonUp_Click(object sender, RoutedEventArgs e)
        {
            ScrollViewerTest.ScrollToVerticalOffset(ScrollViewerTest.VerticalOffset - ItemOffset);
        }
        
        private void ButtonDown_Click(object sender, RoutedEventArgs e)
        {
            ScrollViewerTest.ScrollToVerticalOffset(ScrollViewerTest.VerticalOffset + ItemOffset);
        }

        private void ListBoxTest_Loaded(object sender, RoutedEventArgs e)
        {
            if (ListBoxTest.Items.Count == 0) return;

            if (ItemOffset == 0)
            {
                ((ListBoxItem)ListBoxTest.Items[0]).Measure(new Size(double.PositiveInfinity, double.PositiveInfinity));
                ItemOffset = ((ListBoxItem)ListBoxTest.Items[0]).DesiredSize.Height;
            }
        }
    }
 
Share this answer
 
v4

This content, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)



CodeProject, 20 Bay Street, 11th Floor Toronto, Ontario, Canada M5J 2N8 +1 (416) 849-8900