Am having a problem in scrollviewer.
Scenario:
am having a stack panel inside which having a content, from mouse move of that content am showing a popup to rearrange those content.
issue: when am trying to handle mouse move of that content popup shows and also scrolling happening.
expected behavior: scrolling should not happen while handling mouse move.
i have tried "HorizontalScrollBarVisibility = ScrollBarVisibility.Disabled" it works fine but it sets the scrollviewer to its initial position, means horizontal offset sets to Zero("0")
thanks in advance.
As per our discussion, I think the best route would be to store a class level boolean which will determine whether or not to enable scrolling. You'd have to set this according to your needs (Probably the same place you were modifying the visibility before).
The next step would be to set up some events and properties on your scrollviewer so that you can control whether it scrolls or not. You really only need to modify the constructor of the page holding the scrollviewer, and create a handler for the ManipulationStarted event. The following assumes your control is named Scroll, and that the variable locked is set to true when the control should not scroll:
public MainWindow()
{
InitializeComponent();
Scroller.ManipulationStarted += new EventHandler<ManipulationStartedEventArgs>(scroller_ManipulationStarted);
Scroller.ManipulationMode = ManipulationMode.Control; // Required
}
void scroller_ManipulationStarted(object sender, ManipulationStartedEventArgs e)
{
if (locked)
{
e.Handled = true;
e.Complete();
}
}
Related
I have written a custom Control, based on other code, which includes a call to SetStyle(ControlStyles.Selectable, false);
This prevents the following code from being called (which works if I remove the above line and click on the Control first to 'focus' it):
protected override void OnMouseWheel(MouseEventArgs e)
{
ScrollBar.Value = Math.Min(ScrollBar.Value - e.Delta, ScrollBar.Maximum - ScrollBar.LargeChange);
LayoutChanged();
}
My control does not need focus so Selectable=false is correct.
What do I need to do so that I can run this code whenever the mouse is over my control and the MouseWheel is moved regardless of where the focus is?
Thanks for the comments. A additional info:-
I am running Windows 7 but any solution must work on any OS.
The Control is inherited via Control/ControlBase/BaseControl/BaseStyleControl where the latter 3 are DevExpress controls.
The real focus should not be changed just because the cursor hovers over my control
There are no child controls other than a scrollbar (an inherited DevExpress one) which is normally invisible and shows itself when the mouse hovers over where it would be when visible.
The control does nothing but draw itself (imagine a number of bookshelves one under the other with book covers drawn on them - the number of shelves increases to accommodate all the books and the scrollbar allows all to be scrolled into view.
Since this is a use-anywhere Control, getting MouseWheel events from a Parent that knows about its requirements isn't a good idea.
Maybe there is a way of registering for a first-look (is that a MessagePreview?) to pinch MouseWheel events before normal processing happens.
I've implemented a grid splitter based on a few blog sources that basically allows expand/collapse based on a double click event.
The splitter is in between two columns of a grid that represent a screen layout with a NavigationPanel on the left and a MainContentPanel on the right, with the splitter allowing the NavigationPanel to be collapsed to a minimum width where only icons are displayed.
Is there a way to disable the default behaviour of the grid splitter when it comes to allowing dragging of the splitter and keyboard adjustments?
My current workaround is as follows
Disable keyboard adjustments by setting Focusable to False
Prevent the user "grabbing" the splitter by placing a ToggleButton control overtop of the same as the GridSplitter, thereby having the button intercepting all mouse clicks.
I've got a version where I don't use a ToggleButton at all and just handle the double click event on the GridSplitter but the problem with that is I can't find a way to disable the mouse dragging functionality.
Honestly don't understand why you'd want to do this, but if you really want to disable mouse AND keyboard input, just set IsEnabled to false. As you already discovered, if you only want to disable keyboard input, set Focusable to false- this is what brought me here, trying to figure that out :)
One alternative I've found is to add a handler for the DragDeltaEvent and then mark it as handled.
public class ExtendedGridSplitter : GridSplitter
{
...
public ExtendedGridSplitter()
{
EventManager.RegisterClassHandler(typeof(ExtendedGridSplitter), Thumb.DragDeltaEvent,
new DragDeltaEventHandler(OnDragDelta));
}
...
private void OnDragDelta(object sender, DragDeltaEventArgs e)
{
e.Handled = true;
}
}
And for the keyboard events overriding the handler works similarly
protected override void OnKeyDown(KeyEventArgs e)
{
e.Handled = true;
}
A simple solution which works for me (though not very pretty) is setting the MaxWidth and MinWidth to the same value. In my case I wanted to turn off the use of the splitter when the user selected to close the window and show a "re-appear" icon it in the sidebar.
Unfortunately the MouseWE grippers still light up but they can do nothing.
Is there a way to resize a Winform window just in Resize End?
This means that as long as the mouse is clicked I see lines and only when I leave the mouse (Resize end) window will resize on the screen.
You will need to use DrawReversibleFrame. Default resizing will need to be disabled (FormBorderStyle = FixedSingle).
Basic Logic is -
MouseDown - Begin tracking
MouseMove - Draw Reversible Frame
MouseUp - Stop Drawing Reversible Frame. Resize Form.
Luckily this MSDN post had working code for this. I have a made a working sample for you.
http://www.mediafire.com/download/427g2h2ajm5z62m/ResizeFrame.zip
You will need to tweak this so Form resize only happens when user 'MouseDown' near the border.
If it's fine to only have the contained controls resize then (and the Form itself - immediately) - use the Form's ResizeEnd event.
(I'm assuming this is the case, because usually there is no reason to delay the Form's resize itself, rather the contained controls', because their resize might be 'expensive'.)
Note: "The ResizeEnd event is also generated after the user moves a form".
Try this.
protected override void OnResizeBegin(EventArgs e) {
SuspendLayout();
base.OnResizeBegin(e);
}
protected override void OnResizeEnd(EventArgs e) {
ResumeLayout();
base.OnResizeEnd(e);
}
I have a project that is using WPF Drag and Drop built in functionality. I'm using the OnGiveFeedback event override to change the cursor when the draggable item is inside a droppable item.
My issue is that the control I'm trying to isolate the drag and drop to is embedded in an area that also contains HTML on the sides. When I drag over the HTML area, my cursor changes like it is over a drop area.
I'm trying to remedy this by getting the mouse position when my DragDropEffect = DragDropEffect.Move inside my OnGiveFeedback override, and making sure the mouse is still within the bounds of my control.
I can't seem to find a way to get the mouse position from inside this override. Mouse.Position is returning the point where my Drag started so I'd assume the mouse events get blocked once a drag operation starts.
Any insight would be greatly appreciated.
Code Snippet:
protected override void OnGiveFeedback(GiveFeedbackEventArgs e)
{
// These Effects values are set in the drop target's
// DragOver event handler.
if (e.Effects.HasFlag(DragDropEffects.Move) || e.Effects.HasFlag(DragDropEffects.Copy))
{
Mouse.SetCursor(Cursors.Cross);
}
else
{
Mouse.SetCursor(Cursors.Arrow);
}
e.Handled = true;
}
why don't you override OnDragEnter and OnDragLeave and change the cruser from there.
I have some screens with a lot of stuff on them, and the redrawing performance is pretty poor. It is possible to set a form into a resizing mode where a rectangle is shown on the screen that denotes the new window dimensions as the user resizes it, but the actual form doesn't resize until they let go of the mouse button?
Thanks!
Yes; this behavior is defined by one of the window styles, which you can turn on/off using the Control.SetStyles method. In particular, I think you want this:
myForm.SetStyle(ControlStyles.ResizeRedraw, false);
You could then hook the mousedown/resize/mouseup events and force the redraw to happen when you wanted.
You can also try turning on the double buffering style:
myForm.SetStyle(ControlStyles.DoubleBuffer, true);
See this article for details: http://msdn.microsoft.com/en-us/library/fkf25009(v=vs.100).aspx
Completely suppressing all drawing is not practical, the window frame painting is out of your direct control. Nor is it necessary, all you have to do is make your drawing fast when the form is being resized. Like this:
private bool fastRender;
protected override void OnResizeBegin(EventArgs e) {
fastRender = true;
base.OnResizeBegin(e);
}
protected override void OnResizeEnd(EventArgs e) {
base.OnResizeEnd(e);
fastRender = false;
this.Invalidate();
}
And check the fastRender variable in your Paint event handler, drawing only the minimum. Or nothing at all. If the actual delay is caused by a large number of controls then tackle that by making them invisible in ResizeBegin and visible again in ResizeEnd. Easy to do with a Panel. If it is caused by a controls that are docked or have the Anchor set so that they'll resize or move whenever the user resizes the window then you'll find Suspend/ResumeLayout useful.
Have you tried using the DoubleBuffer feature of a winform/control?
How about using ResizeEnd instead of Resize.
Open the window that is abnormally sized; then hold down the control key, hit the + key until you return to your required size. Good luck.