How to detect when a ScrollViewer finishes scrolling? - c#

BTW I'm using UWP in case it matters.
So I am using a ListView and all ListViews have a ScrollViewer attached to them (in default template) by default. The problem is that I cannot find an event (on the ListView itself or on its ScrollViewer) that triggers when the ListView finishes scrolling.
I used the scrollViewer.ChangeView() method to automatically scroll to the beginning of the ListView and it uses an animation to scroll to the top, so I think that has something to do with it because the ViewChanged event fires before the animation completes. If I am correct about that then there would have to be a way to determine if the animation is complete because I need to be alerted when the ListView is completely idle again, which is only when the scroll animation completes. Thanks.

You can wire up the scrollViewer's ViewChanged event, and check the IsIntermediate of the event argument.
private void ScrollViewer_ViewChanged(object sender, ScrollViewerViewChangedEventArgs e)
{
if (e.IsIntermediate)
{
System.Diagnostics.Debug.WriteLine("scroll ongoing");
}
else
{
System.Diagnostics.Debug.WriteLine("scroll finish");
}
}
This event is fired multiple times. When the scroll finishes, IsIntermediate is false.

Related

WP8.1 AppBar size change

How do I monitor AppBar's size changes? Specifically, I want to know when it gets opened(to show secondary commands and labels underneath icons).
There is a SizeChanged event, but it fires only before AppBar is shown on the screen.
CommandBar has Opened and Closed events. They are fired when SecondayCommands are shown/hidden.
Note that those events will be fired only if you have SecondayCommands in your AppBar.
As I've checked - Opening/Closing your AppBar doesn't change its ActualHeight. If you want to see its size changing you can play with ClosedDisplayMode - for example put this code in your AppBarButton.Click:
private void AppBarToggleButton_Click(object sender, RoutedEventArgs e)
{
Debug.WriteLine(BottomAppBar.ActualHeight.ToString());
if (BottomAppBar.ClosedDisplayMode == AppBarClosedDisplayMode.Compact)
BottomAppBar.ClosedDisplayMode = AppBarClosedDisplayMode.Minimal;
else BottomAppBar.ClosedDisplayMode = AppBarClosedDisplayMode.Compact;
}
The code above changes ActualHeight and thus SizeChanged event is being fired.

How can I make MouseWheel work without first having to focus the form?

I have a form with only a ReportViewer control on it. When the form is displayed, if you click on the report you can then use the mouse wheel to scroll vertically.
I'd like to be able to scroll as soon as the form appears.
I've tried the following, but no dice...
private void ReportViewer_Load(object sender, EventArgs e)
{
rptViewer.Focus();
}
private void ReportViewer_Activated(object sender, EventArgs e)
{
rptViewer.Focus();
}
Put your code in the form's constructor, right after InitializeComponent();:
rptViewer.Select();
After set rptViewer.Focus call SendKeys.Send(Chr(Keys.Tab)) to move focus from menu to preview area.
Did you try calling rptView.Activate()?
Also it may be that your form is getting focus after the load event completes (I think I've had problems with that before). One solution is, although it is definitely not elegant, to create a single-use Timer that starts when your Load method runs, and fires after 1 ms, and then stops. When the Timer fires, it will activate/focus your ReportViewer.
You could also try adding a MouseWheel event handler to your form. When the event is fired, send a scroll message to your ReportViewer to scroll it up or down. Then it doesn't matter whether or not your ReportViewer has focus, it (should) always scroll when the form has focus.

Windows Phone 8 ScrollViewer

I have two ScrollViewer's in my layout of windows phone app. I'm trying to synchronize both. i'm using VisualTreeHelper.GetChild to find HorizontalScrollBar and then setting ValueChanged event.
It happens that this event is not called whenever scrollviewer is scrolling, so the other scrollviewer scrolling is not smooth.
I had tried many solutions found in internet but it seems nothing is working for me.
Is there any event that i can subscribe in order to achieve this effect?
NOTE: the content of the first ScrollViewer is much longer than the second one.
Try listening to "mouseMove" event on the scrollviewer that you need to base your adjustment on.
this.MyScrollViewer.MouseMove += MyScrollViewer_MouseMove;
Handle the event in a method like this:
public void MyScrollViewer_MouseMove(object sender, System.Windows.Input.MouseEventArgs e)
{
// Write your manipulation here
}

WinForms Event Parent scroll

I have two FlowLayoutPanels on a form: PanelA and PanelB. Each will be populated at run-time with multiple controls, such that the panel will scroll (i.e AutoScroll is true).
Here's the issue: The controls that the panels are populated with each contain a ComboBox. Thus, MouseWheel events are consumed by the combo box instead of by the panel. I want MouseWheel events to be consumed by the panel.
If there's no scrollable control on the child controls, then the MouseWheel event skips the child control (which doesn't handle it) and hits the panel, which does handle it. How can I set my child control's combo box to ignore the MouseWheel event? Can I tell it to re-raise the event?
I tried just applying Focus to the Parent whenever one of the child controls ticks the 'MouseEnter' event; this fixed the scrolling issues, but also left the child controls completely un-editable.
Something else I've found from digging around involves fiddling with the Windows API directly, but I find it hard to believe that something like that is required for this.
I tested the following code and it seems like a solution to your issue. Basically you need to focus the 'FlowLayoutPanel' when you click on it, or your mouse enters it:
private void newCheckListQuestionPanel_Click(object sender, EventArgs e)
{
newCheckListQuestionPanel.Focus(); //allows the mouse wheel to work after the panel is clicked
}
private void newCheckListQuestionPanel_MouseEnter(object sender, EventArgs e)
{
newCheckListQuestionPanel.Focus(); //allows the mouse wheel to work after the panel has had the mouse move over it
}
Source

MouseUp event interrupted?

I'm making a custom control with a panel. I want to be able to drag and drop it so I've implemented that in the MouseDown event of my control. But I want the thing to react when you start drag to give a little feedback to the user. So in the MouseDown even I change the color. Then I want to change it back in the MouseUp event.
My control is not installed into VS2008 but just a class I've written that I instanciate at run time (I don't know in advance how many I need and so on). Now, my control exposes a MouseDown event so as to be able to be dragged. When I subscribe to this event from the parent application to actually perform the drag and drop my control is not repainted on its MouseUp event! In fact, the MouseUp is never invoked. If, on the other hand, I don't subscribe to the event in the parent app it works as intended.
What's going on? Is the parent interrupting the flow so that the MouseUp event never fires in my control? How do I get around this?
I'm not sure if you are using Windows Forms or WPF, but in Windows forms here is what I mean:
public class DerivedPanel : Panel
{
protected override void OnMouseDown(MouseEventArgs e)
{
base.OnMouseDown(e);
Capture = true;
}
protected override void OnMouseUp(MouseEventArgs e)
{
base.OnMouseUp(e);
Capture = false;
// Change your color or whatever here
}
}
In WPF there are two methods, CaptureMouse() and ReleaseMouseCapture() to do the same thing. When the control captures the mouse, it will received mouse events even if the cursor isn't over the control. This could be causing your problem. See MSDN Article
Do you capture the mouse in the custom control on the mousedown event? Try capturing on the mousedown and releasing the capture on the mouseup.

Categories