Jump to content
LaunchBox Community Forums

ListBox Scroll Center for BigBox 1.0.0

   (1 review)

1 Screenshot

About This File

This control will make the selected item in the list views stay in the center of the list as the user scrolls if the list is indeed scrollable according to the IScrollInfo.

Please read the included docs and view the example pictures for each step! If you are inserting this into a theme where the author has modified any of the required views, make sure to only replace whats outlined in the docs.

Any troubles implementing it let me know and I will make the modifications when I have time.

Major thanks to @Jason Carr for holding my hand on this one :)

  • Like 11
  • Thanks 3

User Feedback

Recommended Comments

2 minutes ago, spektor56 said:

nice, you have a github link for all your custom controls in one package?

I will soon, I actually just started putting them all in one solution last week. Shouldn't take me much longer to get it done.

Link to comment
Share on other sites

yea, it would be nice if jason made a central github repo for BB that all the theme makers could fork and contribute to for custom controls.  Pretty sure some other people made some custom controls on here as well?   Would make it a lot easier for new theme makers to get started when they have access to all the communities work.  No point in reinventing the wheel.  I know you already have quite a few useful controls like the XInput controllers one.

Edited by spektor56
Link to comment
Share on other sites

I could, but it's easier to just point the other few views at a new style. It takes 5 seconds where I would have to make changes, re-compile, re-package, re-upload to site etc. etc.

I will try to get to it at some point down the line, but I can't say when.

  • Thanks 1
Link to comment
Share on other sites

@Jason Carr @wallmachine The control is set to use the ListBoxStyle (Style="{DynamicResource ListBoxStyle}"). Must have gotten broken with the recent changes regarding the styles.

I did it that way on all my plugins so they could just be dropped in to a theme and use the existing theme style.

Here's a shot of the code...

1107719036_ListBoxScrollCenter-MicrosoftVisualStudio2_22_20194_59_04AM.thumb.png.6f7cc3fb231c63c28560c1656b496f09.png

  • Like 1
Link to comment
Share on other sites

Hey @Grila, do you know why this might be happening? I am trying to add your plugin to the OptionsView.xaml and OptionsPage.xaml but I get the error below. It is accepting the FontSize and also stays centred in the OptionsView.xaml however it throws the error when I press up or down also not sure how to add it to OptionsPage.xaml.

Object reference not set to an instance of an object.

App:     Big Box
Version: 9.10-beta-5
Type:    System.NullReferenceException
Site:    Int32 (System.Windows.Controls.ListBox)
Source:  Unbroken.LaunchBox.Wpf

   at (ListBox )
   at Unbroken.LaunchBox.Wpf.ListBoxHelper.GetNumberOfVerticalVisibleItems(ListBox listBox)
   at (<>c__DisplayClass15_0 )
   at Unbroken.LaunchBox.Wpf.BigBox.ViewModels.OptionsViewModel.<>c__DisplayClass15_0.<set_SelectedMenuItem>b__0()
   at System.Windows.Threading.DispatcherOperation.InvokeDelegateCore()
   at System.Windows.Threading.DispatcherOperation.InvokeImpl()
--- End of stack trace from previous location where exception was thrown ---
   at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw()
   at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
   at System.Windows.Threading.DispatcherOperation.Wait(TimeSpan timeout)
   at System.Windows.Threading.Dispatcher.InvokeImpl(DispatcherOperation operation, CancellationToken cancellationToken, TimeSpan timeout)
   at System.Windows.Threading.Dispatcher.Invoke(Action callback, DispatcherPriority priority, CancellationToken cancellationToken, TimeSpan timeout)
   at System.Windows.Threading.Dispatcher.Invoke(Action callback, DispatcherPriority priority)
   at (Action , DispatcherPriority )
   at Unbroken.LaunchBox.Wpf.Threading.Invoke(Action callback, DispatcherPriority priority)
   at Unbroken.LaunchBox.Wpf.BigBox.ViewModels.OptionsViewModel.set_SelectedMenuItem(MenuItemViewModel value)
   at (OptionsViewModel , Boolean , Boolean )
   at Unbroken.LaunchBox.Wpf.BigBox.ViewModels.OptionsViewModel.OnDown(Boolean held, Boolean onlyDownPressed)
   at (MainViewModel , Boolean )
   at Unbroken.LaunchBox.Wpf.BigBox.ViewModels.MainViewModel.OnDown(Boolean onlyDownPressed)
   at (MainViewModel , KeyEventArgs )
   at Unbroken.LaunchBox.Wpf.BigBox.ViewModels.MainViewModel.HandleKeyDown(KeyEventArgs e)
   at (MainView , Object , KeyEventArgs )
   at Unbroken.LaunchBox.Wpf.BigBox.Views.MainView.MainView_OnPreviewKeyDown(Object sender, KeyEventArgs e)
   at System.Windows.RoutedEventArgs.InvokeHandler(Delegate handler, Object target)
   at System.Windows.RoutedEventHandlerInfo.InvokeHandler(Object target, RoutedEventArgs routedEventArgs)
   at System.Windows.EventRoute.InvokeHandlersImpl(Object source, RoutedEventArgs args, Boolean reRaised)
   at System.Windows.UIElement.RaiseEventImpl(DependencyObject sender, RoutedEventArgs args)
   at System.Windows.UIElement.RaiseTrustedEvent(RoutedEventArgs args)
   at System.Windows.Input.InputManager.ProcessStagingArea()
   at System.Windows.Input.InputManager.ProcessInput(InputEventArgs input)
   at System.Windows.Input.InputProviderSite.ReportInput(InputReport inputReport)
   at System.Windows.Interop.HwndKeyboardInputProvider.ReportInput(IntPtr hwnd, InputMode mode, Int32 timestamp, RawKeyboardActions actions, Int32 scanCode, Boolean isExtendedKey, Boolean isSystemKey, Int32 virtualKey)
   at System.Windows.Interop.HwndKeyboardInputProvider.ProcessKeyAction(MSG& msg, Boolean& handled)
   at System.Windows.Interop.HwndSource.CriticalTranslateAccelerator(MSG& msg, ModifierKeys modifiers)
   at System.Windows.Interop.HwndSource.OnPreprocessMessage(Object param)
   at System.Windows.Threading.ExceptionWrapper.InternalRealCall(Delegate callback, Object args, Int32 numArgs)
   at System.Windows.Threading.ExceptionWrapper.TryCatchWhen(Object source, Delegate callback, Object args, Int32 numArgs, Delegate catchHandler)

Recent Log:

   7:38:25 AM Music.Pause Start
   7:38:25 AM Music.Resume Start
   7:38:25 AM Music.Resume Start
   7:38:28 AM Music.Pause Start
   7:38:29 AM Music.Resume Start
   7:38:29 AM Music.StopAndResumeBackground Start
   7:38:30 AM Music.Initialize Start
   7:38:30 AM Music.Kill Start
   7:38:30 AM Music.Kill Finished
   7:38:34 AM Music.Kill Start
   7:38:34 AM Music.Kill Finished
   7:38:35 AM Exception

 

I edited the project as follows.

OptionsView.xaml

xmlns:lbsc="clr-namespace:ListBoxScrollCenter;assembly=ListBoxScrollCenter"

<lbsc:OptionsList Name="MenuItems" FontSize="45">
			<i:Interaction.Triggers>
				<i:EventTrigger EventName="MouseDoubleClick">
					<cal:ActionMessage MethodName="OnEnter" />
				</i:EventTrigger>
			</i:Interaction.Triggers>
</lbsc:OptionsList>

 

OptionsList.xaml

<UserControl x:Class="ListBoxScrollCenter.OptionsList"
             xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
             xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
             xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" 
             xmlns:d="http://schemas.microsoft.com/expression/blend/2008" 
             xmlns:local="clr-namespace:ListBoxScrollCenter"
             mc:Ignorable="d" 
             d:DesignHeight="400" d:DesignWidth="600">
    <local:DPIFix>
        <ListBox Name="CenteredLB" SelectionChanged="ScrollIntoView" Style="{DynamicResource ListBoxStyle}" ItemsSource="{Binding MenuItems}" SelectedItem="{Binding Path=SelectedMenuItem}">
            <ListBox.ItemsPanel>
                <ItemsPanelTemplate>
                    <VirtualizingStackPanel IsItemsHost="True" Orientation="Vertical" VirtualizingPanel.VirtualizationMode="Recycling"/>
                </ItemsPanelTemplate>
            </ListBox.ItemsPanel>
            <ListBox.ItemTemplate>
                <DataTemplate>
                    <Border Name="Border" Width="{Binding ActualWidth, RelativeSource={RelativeSource AncestorType={x:Type ListBox}}}">
                        <DockPanel>
                            <TextBlock Name="Text" DockPanel.Dock="Left" Text="{Binding Text}" TextTrimming="CharacterEllipsis" TextWrapping="NoWrap"/>
                        </DockPanel>
                    </Border>
                </DataTemplate>
            </ListBox.ItemTemplate>
        </ListBox>
    </local:DPIFix>
</UserControl>

 

OptionsList.xaml.cs

using System.Windows.Controls;

namespace ListBoxScrollCenter
{
    public partial class OptionsList : UserControl
    {
        public OptionsList()
        {
            InitializeComponent();
        }

        private void ScrollIntoView(object sender, SelectionChangedEventArgs e)
        {
            CenteredLB.ScrollToCenterOfView(CenteredLB.SelectedItem);
        }
    }
}
Edited by wallmachine
Link to comment
Share on other sites

1 hour ago, wallmachine said:

Hey @Grila, do you know why this might be happening? I am trying to add your plugin to the OptionsView.xaml and OptionsPage.xaml but I get the error below. It is accepting the FontSize and also stays centred in the OptionsView.xaml however it throws the error when I press up or down also not sure how to add it to OptionsPage.xaml.


Object reference not set to an instance of an object.

App:     Big Box
Version: 9.10-beta-5
Type:    System.NullReferenceException
Site:    Int32 (System.Windows.Controls.ListBox)
Source:  Unbroken.LaunchBox.Wpf

   at (ListBox )
   at Unbroken.LaunchBox.Wpf.ListBoxHelper.GetNumberOfVerticalVisibleItems(ListBox listBox)
   at (<>c__DisplayClass15_0 )
   at Unbroken.LaunchBox.Wpf.BigBox.ViewModels.OptionsViewModel.<>c__DisplayClass15_0.<set_SelectedMenuItem>b__0()
   at System.Windows.Threading.DispatcherOperation.InvokeDelegateCore()
   at System.Windows.Threading.DispatcherOperation.InvokeImpl()
--- End of stack trace from previous location where exception was thrown ---
   at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw()
   at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
   at System.Windows.Threading.DispatcherOperation.Wait(TimeSpan timeout)
   at System.Windows.Threading.Dispatcher.InvokeImpl(DispatcherOperation operation, CancellationToken cancellationToken, TimeSpan timeout)
   at System.Windows.Threading.Dispatcher.Invoke(Action callback, DispatcherPriority priority, CancellationToken cancellationToken, TimeSpan timeout)
   at System.Windows.Threading.Dispatcher.Invoke(Action callback, DispatcherPriority priority)
   at (Action , DispatcherPriority )
   at Unbroken.LaunchBox.Wpf.Threading.Invoke(Action callback, DispatcherPriority priority)
   at Unbroken.LaunchBox.Wpf.BigBox.ViewModels.OptionsViewModel.set_SelectedMenuItem(MenuItemViewModel value)
   at (OptionsViewModel , Boolean , Boolean )
   at Unbroken.LaunchBox.Wpf.BigBox.ViewModels.OptionsViewModel.OnDown(Boolean held, Boolean onlyDownPressed)
   at (MainViewModel , Boolean )
   at Unbroken.LaunchBox.Wpf.BigBox.ViewModels.MainViewModel.OnDown(Boolean onlyDownPressed)
   at (MainViewModel , KeyEventArgs )
   at Unbroken.LaunchBox.Wpf.BigBox.ViewModels.MainViewModel.HandleKeyDown(KeyEventArgs e)
   at (MainView , Object , KeyEventArgs )
   at Unbroken.LaunchBox.Wpf.BigBox.Views.MainView.MainView_OnPreviewKeyDown(Object sender, KeyEventArgs e)
   at System.Windows.RoutedEventArgs.InvokeHandler(Delegate handler, Object target)
   at System.Windows.RoutedEventHandlerInfo.InvokeHandler(Object target, RoutedEventArgs routedEventArgs)
   at System.Windows.EventRoute.InvokeHandlersImpl(Object source, RoutedEventArgs args, Boolean reRaised)
   at System.Windows.UIElement.RaiseEventImpl(DependencyObject sender, RoutedEventArgs args)
   at System.Windows.UIElement.RaiseTrustedEvent(RoutedEventArgs args)
   at System.Windows.Input.InputManager.ProcessStagingArea()
   at System.Windows.Input.InputManager.ProcessInput(InputEventArgs input)
   at System.Windows.Input.InputProviderSite.ReportInput(InputReport inputReport)
   at System.Windows.Interop.HwndKeyboardInputProvider.ReportInput(IntPtr hwnd, InputMode mode, Int32 timestamp, RawKeyboardActions actions, Int32 scanCode, Boolean isExtendedKey, Boolean isSystemKey, Int32 virtualKey)
   at System.Windows.Interop.HwndKeyboardInputProvider.ProcessKeyAction(MSG& msg, Boolean& handled)
   at System.Windows.Interop.HwndSource.CriticalTranslateAccelerator(MSG& msg, ModifierKeys modifiers)
   at System.Windows.Interop.HwndSource.OnPreprocessMessage(Object param)
   at System.Windows.Threading.ExceptionWrapper.InternalRealCall(Delegate callback, Object args, Int32 numArgs)
   at System.Windows.Threading.ExceptionWrapper.TryCatchWhen(Object source, Delegate callback, Object args, Int32 numArgs, Delegate catchHandler)

Recent Log:

   7:38:25 AM Music.Pause Start
   7:38:25 AM Music.Resume Start
   7:38:25 AM Music.Resume Start
   7:38:28 AM Music.Pause Start
   7:38:29 AM Music.Resume Start
   7:38:29 AM Music.StopAndResumeBackground Start
   7:38:30 AM Music.Initialize Start
   7:38:30 AM Music.Kill Start
   7:38:30 AM Music.Kill Finished
   7:38:34 AM Music.Kill Start
   7:38:34 AM Music.Kill Finished
   7:38:35 AM Exception

 

I edited the project as follows.

OptionsView.xaml


xmlns:lbsc="clr-namespace:ListBoxScrollCenter;assembly=ListBoxScrollCenter"

<lbsc:OptionsList Name="MenuItems" FontSize="45">
			<i:Interaction.Triggers>
				<i:EventTrigger EventName="MouseDoubleClick">
					<cal:ActionMessage MethodName="OnEnter" />
				</i:EventTrigger>
			</i:Interaction.Triggers>
</lbsc:OptionsList>

 

OptionsList.xaml


<UserControl x:Class="ListBoxScrollCenter.OptionsList"
             xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
             xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
             xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" 
             xmlns:d="http://schemas.microsoft.com/expression/blend/2008" 
             xmlns:local="clr-namespace:ListBoxScrollCenter"
             mc:Ignorable="d" 
             d:DesignHeight="400" d:DesignWidth="600">
    <local:DPIFix>
        <ListBox Name="CenteredLB" SelectionChanged="ScrollIntoView" Style="{DynamicResource ListBoxStyle}" ItemsSource="{Binding MenuItems}" SelectedItem="{Binding Path=SelectedMenuItem}">
            <ListBox.ItemsPanel>
                <ItemsPanelTemplate>
                    <VirtualizingStackPanel IsItemsHost="True" Orientation="Vertical" VirtualizingPanel.VirtualizationMode="Recycling"/>
                </ItemsPanelTemplate>
            </ListBox.ItemsPanel>
            <ListBox.ItemTemplate>
                <DataTemplate>
                    <Border Name="Border" Width="{Binding ActualWidth, RelativeSource={RelativeSource AncestorType={x:Type ListBox}}}">
                        <DockPanel>
                            <TextBlock Name="Text" DockPanel.Dock="Left" Text="{Binding Text}" TextTrimming="CharacterEllipsis" TextWrapping="NoWrap"/>
                        </DockPanel>
                    </Border>
                </DataTemplate>
            </ListBox.ItemTemplate>
        </ListBox>
    </local:DPIFix>
</UserControl>

 

OptionsList.xaml.cs


using System.Windows.Controls;

namespace ListBoxScrollCenter
{
    public partial class OptionsList : UserControl
    {
        public OptionsList()
        {
            InitializeComponent();
        }

        private void ScrollIntoView(object sender, SelectionChangedEventArgs e)
        {
            CenteredLB.ScrollToCenterOfView(CenteredLB.SelectedItem);
        }
    }
}

It never worked in the Options view because Jason is doing some magic to calculate how many items are shown and adjusting the text size (I presume) or spacing based on the number of items. I remember telling him about it when I wrote the plug-in but never figured out a fix for it. 

  • Thanks 1
Link to comment
Share on other sites

14 hours ago, faeran said:

Yes, I think this is a long standing issue with the center text list plugin. From my understanding it happens when you switch to a new theme that utilizes it within the platform filter list, the first item doesn't load quite right, and you would need to change to another item for Big Box to fully load. With only ScummVM in your library, you can't switch to another platform, and therefore you are stuck. If you crash Big Box and come back into it, you should be fine. You could also add some more platforms as well :)

Either way, the center text list plugin is definitely something that should be looked into at some point in the future, as many themes use it.

Please see above. Thanks!

Link to comment
Share on other sites

@faeran Really sorry to revive this old thread, but (I think) I recall that you designed the latest default theme for BigBox, which I find to be one of the best of them all. I'm trying to center the scrolling in the TextListView.xaml without any success. I tried to add grila's code and use this plugin but wasn't able to get it working. Coincidentally, I noticed that the same plugin was already there in the folder for this theme, which I'm assuming had some sort of similar purpose? If you can offer any help that would be really appreciated!

Link to comment
Share on other sites

1 hour ago, bundangdon said:

@faeran Really sorry to revive this old thread, but (I think) I recall that you designed the latest default theme for BigBox, which I find to be one of the best of them all. I'm trying to center the scrolling in the TextListView.xaml without any success. I tried to add grila's code and use this plugin but wasn't able to get it working. Coincidentally, I noticed that the same plugin was already there in the folder for this theme, which I'm assuming had some sort of similar purpose? If you can offer any help that would be really appreciated!

Not at the computer right now, but there's a behavior that's built into BigBox that you can use to accomplish this. It should be in the documentation.

Link to comment
Share on other sites

1 hour ago, faeran said:

Not at the computer right now, but there's a behavior that's built into BigBox that you can use to accomplish this. It should be in the documentation.

Good to know that! If you can point me in the direction of that information in the documentation I'd definitely appreciate it.

Link to comment
Share on other sites

16 hours ago, faeran said:

Not at the computer right now, but there's a behavior that's built into BigBox that you can use to accomplish this. It should be in the documentation.

Another update: After trying what was mentioned in the documentation for about 2 hours with no success, I'll have to give up on this idea for now. Hopefully the games-list in the default theme will be centered someday in the future.

Link to comment
Share on other sites

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.

Guest
Unfortunately, your content contains terms that we do not allow. Please edit your content to remove the highlighted words below.
Add a comment...

×   Pasted as rich text.   Paste as plain text instead

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

×
×
  • Create New...