-
Notifications
You must be signed in to change notification settings - Fork 1.4k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Middle click scrolling #2040
Middle click scrolling #2040
Conversation
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This and a couple of your other PRs need to be updated to the latest master as well.
... | ||
</ListView> | ||
<ListView Name="listView" | ||
extensions:ScrollViewerEx.VerticalScrollBarMargin="{Binding MinHeight, ElementName=MyHeaderGrid, Converter={StaticResource DoubleTopThicknessConverter}}"> |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Class is still ScrollViewerExtensions
(as it should be), if you want to abbreviate, I usually make the namespace ex:
now. So it'd be ex:ScrollViewerExtensions.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
My bad. But why ex:ScrollViewerExtensions
? We are using extensions:ScrollViewerExtensions
in the master branch.
- Cursor number 102, 103, 104, 105, 106, 107, 108, 109 must be the NorthArror, NorthEastArror, EastArror, SouthEastArror, SouthArror, SouthWestArror, WestArror, NorthWestArror respectively | ||
- Every cursor will be automatically attached to the corresponding direction of scrolling | ||
|
||
### Attached Properties |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Do we want one Attached Properties section?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This section is already many docs. It will resolve confusion between Attached Properties and Properties in Properties
section
### Changing Cursor Type | ||
|
||
> [!IMPORTANT] | ||
Resource file must be manually added to change the cursor type when middle click scrolling. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'm not sure if I follow what this means to the developer. Is it required to do these steps to use the extension?
- You need 9 cursor resource in your resource file | ||
- Your cursor number should be 101 to 109 | ||
- Cursor number 101 must be the centre cursor | ||
- Cursor number 102, 103, 104, 105, 106, 107, 108, 109 must be the NorthArror, NorthEastArror, EastArror, SouthEastArror, SouthArror, SouthWestArror, WestArror, NorthWestArror respectively |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Typos Arrow not Arror
|
||
if (_oldCursorID != cursorID) | ||
{ | ||
RunInUIThread(() => |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Use the DispatcherHelper?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
RunInUIThread
is way smaller than DispatcherHelper
. Also, It increases readability.
/// </summary> | ||
public static partial class ScrollViewerExtensions | ||
{ | ||
private static double _threshold = 50; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Have you tested with multiple scrollviewers?
All these static properties and variables means it's tied to a single instance of a scroll viewer. If a page has multiple scrollviewers trying to use this property it could breakdown. It'd be better to make state variables private attached properties to actually store state attached to the scrollviewer that's being manipulated.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yes. I have a SubscribeMiddleClickScrolling()
. This will we resetting every value depend open the currently active ScrolViewer
.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I don't think the static variables are the problem here, but actually the events. They need to be static, so they'll never dispose, and the deregistration of the events is only happening when the EnableMiddleClickScrolling is set to false, which is... never. So this is leaking a reference to the scrollviewer.
{ | ||
cursorID = 101; | ||
} | ||
else |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Can these all be collapsed in the else if, there's only going to be one cursorid in the end, eh?
Not sure if the compiler would optimize, but you could split out the Abs calculation above as you use it in multiple places.
@michael-hawker ping |
Was able to grab my mouse with a wheel finally. I noticed if I middle-click (vs hold) to enter scroll mode, sometimes the mouse cursor won't change to the cross. Also, the cursors should be white with the black outline by default for better contrast in more scenarios. |
I think I have fixed it. @michael-hawker Could you check that again? |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Setting the value to False after setting it to True throws an exception
@@ -13,7 +13,8 @@ | |||
|
|||
<Grid Background="{ThemeResource ApplicationPageBackgroundThemeBrush}"> | |||
<ListView Name="listView" | |||
extensions:ScrollViewerExtensions.VerticalScrollBarMargin="{Binding MinHeight, ElementName=MyHeaderGrid, Converter={StaticResource DoubleTopThicknessConverter}}"> | |||
extensions:ScrollViewerExtensions.VerticalScrollBarMargin="{Binding MinHeight, ElementName=MyHeaderGrid, Converter={StaticResource DoubleTopThicknessConverter}}" | |||
extensions:ScrollViewerExtensions.EnableMiddleClickScrolling="True"> |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This should be using the sample bind syntax @[EnableMiddleClickScrolling:Bool:True]
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Done
} | ||
|
||
/// <summary> | ||
/// This function will be called for every small intervel by <see cref="Timer"/> |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
typo: interval
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Done
_currentPosition = default(Point); | ||
_isDeferredMovingStarted = false; | ||
_oldCursorID = 100; | ||
_timer.Dispose(); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
_timer could be null here if SubscribeMiddleClickScrolling is not called before
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Done
|
||
// Event to stop deferred scrolling if pointer pressed | ||
Window.Current.CoreWindow.PointerPressed -= CoreWindow_PointerPressed; | ||
Window.Current.CoreWindow.PointerPressed += CoreWindow_PointerPressed; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Why subscribe to both CoreWindow and scrollviewer events?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
ScrollViewer.PointerPressed
is for SubscribeMiddleClickScrolling
. CoreWindow.PointerPressed
is to stop deferred scrolling. I can't use ScrollViewer.PointerPressed
because I should stop scrolling in PointerPressed
in the whole app.
### Changing Cursor Type | ||
|
||
> [!IMPORTANT] | ||
Resource file must be manually added to change the cursor type when middle click scrolling. If you didn't add then the cursor won't change when middle click scrolling but funcanilaty won't be affected. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
typo: functionality
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Done
1. Download [MiddleClickScrolling-CursorType.res](https://github.com/Microsoft/UWPCommunityToolkit/tree/master/Microsoft.Toolkit.Uwp.UI/Extensions/ScrollViewer/MiddleClickScrolling-CursorType.res) file | ||
2. Move this file into your project's folder | ||
2. Open .csproj file of your project in [Visual Studio Code](https://code.visualstudio.com/) or in any other code editor | ||
3. Added `<Win32Resource>MiddleClickScrolling-CursorType.res</Win32Resource>` in the first `<PropertyGroup>` |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Typo: add
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Done
|
||
### Using Your Own Resource File | ||
|
||
- You need 9 cursor resource in your resource file |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Typo: 9 cursor resources
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Changed the whole section
2. Open .csproj file of your project in [Visual Studio Code](https://code.visualstudio.com/) or in any other code editor | ||
3. Added `<Win32Resource>MiddleClickScrolling-CursorType.res</Win32Resource>` in the first `<PropertyGroup>` | ||
|
||
### Using Your Own Resource File |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Is there documentation that we can link to for creating custom resource files?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
There is an old doc for Windows 8 but it is not necessary. We can just edit the existing resource file in Visual Studio.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Changed the whole section
|
||
The HorizontalScrollBarMargin works exactly as VerticalScrollBarMargin. | ||
[ScrollViewerExtensions sample page Source](https://github.com/Microsoft/UWPCommunityToolkit/tree/master/Microsoft.Toolkit.Uwp.SampleApp/SamplePages/ScrollViewerExtensions). You can see this in action in [UWP Community Toolkit Sample App](https://www.microsoft.com/store/apps/9NBLGGH4TLCQ). |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
change to Windows Community Toolkit Sample App
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I will change it
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Done
/// </summary> | ||
public static partial class ScrollViewerExtensions | ||
{ | ||
private static double _threshold = 50; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I don't think the static variables are the problem here, but actually the events. They need to be static, so they'll never dispose, and the deregistration of the events is only happening when the EnableMiddleClickScrolling is set to false, which is... never. So this is leaking a reference to the scrollviewer.
_currentPosition = default(Point); | ||
_isDeferredMovingStarted = false; | ||
_oldCursorID = 100; | ||
_timer = new Timer(Scroll, null, 5, 5); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Just to be extra safe, I would do a _timer?.Dispose() before this line.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
OK
This is reply is for above comment. For some reason, I have no replay section 😄
EnableMiddleClickScrolling is set to false, which is... never
Why? Since this is an attached property. Devs can set any value at any time
but actually the events. They need to be static, so they'll never dispose, and the deregistration of the events is only happening when the EnableMiddleClickScrolling is set to false
Deregistration also haves when the user changes the focused ScrollViewer
(in multiple ScrollViewer
scenario).
Issue: #1795
PR Type
What kind of change does this PR introduce?
What is the current behavior?
Middle click scrolling is not available
What is the new behavior?
Added an attached property for ScrollViewer (or any ancestor of ScrollViewer) for middle click scrolling
PR Checklist
Please check if your PR fulfills the following requirements:
Other information
I will add a separate sample for MiddleClickScrolling when multisample for a sample page is available.