Change the Panning button in Mapsui Control - c#

I'm using Mapsui as a mapping control in a C# application.
By default, panning is initiated by dragging using the left mouse button.
I want to change this to the middle mouse button.
Does anyone know how to do this?
Mapsui has an object called PanMode, you can create an instance as follows, however, I believe it is just an enum for centering the map when panning:
Mapsui.UI.PanMode panMode = new PanMode();
EDIT:
Based on what 'pauldendulk's' answer (thank you for your support) I think I need to do something like this:
First, catch the middle button click and relay it to the mapsui left button method. Unfortuantly MapControlMouseLeftButtonDown() is a private method so this will not work.
MyMapControl.MouseDown += MapControlOnMouseButtonDown;
private void MapControlOnMouseButtonDown(object sender, MouseButtonEventArgs e)
{
if(e.ChangedButton == MouseButton.Middle)
{
Mapsui.UI.Wpf.MapControl.MapControlMouseLeftButtonDown(sender, e);
}
}
Secondly I need to stop the origional left button click from firing.
MyMapControl.MouseLeftButtonDown += null;
Again, this is not correct syntax as it throws an exception (cannot be null).
Does anyone know how to solve these issues?

Mapsui was not designed with this in mind. Perhaps it is possible if you assign an event handler to WPFs mouse down event, set the viewport in there. Also, you need to suppress the regular mouse event. Perhaps this is possible by setting the MouseLeftButtonDown event handler to null.
PanMode is not relevant. It is meant to limit the area where users can pan/zoom.

Related

Using a Picture Box as a button, how do I ignore/disable double-click events?

I'm having some difficulty using picture boxes as buttons. I'd like to have custom button graphics rather than using the plain-old windows forms Button control.
It works pretty well, except the buttons seem to lag when a single button is pressed rapidly. I'd like the OnClick method to be called immediately every time the Picture Box is clicked, but it seems to be registering a double-click event, even though I am not using that event.
The short version is I'd like to:
(Ideal) Disable the double-click event, since it appears this is what the Control is waiting for on every alternating click of the Picture Box and I never use it. Or,
(Acceptable) Write a generic DoubleClick event I can use for all Picture Boxes I plan to use as buttons.
I did write up a test program which shows that this is, in fact, what's happening. I wrote a MouseUp event that increments a counter by 1, and also added a OnClick even that increments a different counter by 1. When rapidly clicking the Picture Box linked to these events, the MouseUp counter is exactly double that of the OnClick counter.
I then added a DoubleClick event that calls the OnClick event. This, although not ideal, solves the problem perfectly well. If there is a way to write a generic DoubleClick event that all buttons could use, I think this would be acceptable.
Right now my DoubleClick event is just
private void pb_DoubleClick(object sender, EventArgs e)
{
pbOK_Click(sender, e); //This needs to be generic
}
I'd like to at least replace the DoubleClick line with something like
private void pb_DoubleClick(object sender, EventArgs e)
{
(Sender.ToString)_Click(sender, e); // Doesn't work quite like this.
}
I could write a special DoubleClick event for each Picture Box individually, but that is far from ideal and seems quite cumbersome, so I would prefer not to do that if it isn't necessary.
This is my first posted question, so thanks to anyone who takes the time to read this. Any advice would be greatly appreciated.
EDIT: This program is being developed for Windows CE, so the properties and events options for the objects is quite limited. I still may be missing something, but as far as I can tell the Properties list for buttons goes straight from GenerateMember to Location, with none of the Image options available. I apologize for not stating the target platform in the original post.
It is done with the Control.SetStyle() method, like this:
using System;
using System.Windows.Forms;
class MyButton : PictureBox {
public MyButton() {
this.SetStyle(ControlStyles.StandardDoubleClick, false);
}
}
Okay, my original answer was trash. My update:
Here's a link on how to get a controls Method name:
Link
In the link it has a Control c. To get your control (sender) use the following:
PictureBox picbox = (PictureBox) sender;
Next, call a method using a string(your class.Method.Name): Link
Now that should work. Hope it does.
Why don't you create your own control? This way, you don't have to do anything to get the behavior you want.
using System.Windows.Forms;
namespace WindowsFormsApplication1
{
public class ButtonPictureBox : PictureBox
{
protected override void OnDoubleClick(System.EventArgs e)
{
OnClick(e);
}
}
}
I don't know if this is possible on Windows CE though.
If you also want to hide the DoubleClick event in the form designer, you can add this to the class:
[Browsable(false)]
public new event EventHandler DoubleClick;

WPF Tunneling a Button_Click

This is my first question so please go easy :)
I am new to WPF and Desktop based applications and I am studying Event Handling. Going through Bubbling and Tunneling I can not find an example anywhere that explains how to use tunneling on a Button_Click.
Basically when I click a button I need the parent control (in this case a grid) to handle the event first and do some checks before allowing the Button_Click to take place. The problem I am having is I can use the Grid_PreviewMouseDown to capture the event but this is ambiguous! It does not tell me (at least i think it doesnt) what control caused the handler to trigger.
What can i do to determine the PreviewMouseDown was triggered by a Button Click? Or:
Is there an alternative/better was to tunnel a Button_Click?
Thanks
In your handler, you should inspect the Source of the event to get the control which initiated it. Just note that it is not readonly and could be changed so the Source refers to a different control.
You'll probably have better luck registering with the PreviewMouseLeftButtonDown event to get left clicks and not just any click.
If your handler is meant to only look for the left mouse click, you could use this code:
private void Grid_PreviewMouseLeftButtonDown(object sender, MouseButtonEventArgs e)
{
Button button = e.Source as Button;
if (button != null)
{
// button is being clicked, handle it
}
}

How to capture mouse wheel on panel?

How to capture mouse wheel on panel in C#?
I'm using WinForms
EDIT:
I try to do it on PictureBox now.
My code:
this.pictureBox1.MouseClick += new System.Windows.Forms.MouseEventHandler(this.pictureBox1_MouseClick);
this.pictureBox1.MouseWheel += new System.Windows.Forms.MouseEventHandler(this.pictureBox1_MouseClick);
private void pictureBox1_MouseClick(object sender, MouseEventArgs e)
{
MessageBox.Show("Click");
}
Clicking works. Wheelling doesn't.
Why?
If you can't see the "MouseWheel" event on a component, then you need to create it manually. Also, we need to focus that component, otherwise the "MouseWheel" event will not work for that component. I will show you how to create a "MouseWheel" event for "pictureBox1" and how it works.
INSIDE THE CONSTRUCTOR, create a mousewheel event on that component.
InitializeComponent();
this.pictureBox1.MouseWheel += pictureBox1_MouseWheel;
CREATE THE FUNCTION manually. According to my example, call it "pictureBox1_MouseWheel"
private void pictureBox1_MouseWheel(object sender, MouseEventArgs e)
{
//you can do anything here
}
CREATE a MouseHover event on that component (Go to properties in PicureBox1, select event, locate "MouseHover" and double-click the "MouseHover" event).
CALL "Focus()"; method inside that MouseHover event.
pictureBox1.Focus();
Now run the program.
Windows sends the WM_MOUSEWHEEL message to the control that has the focus. That won't be Panel, it is not a control that can get the focus. As soon as you put a control on the panel, say a button, then the button gets the focus and the message.
The button however has no use for the message, it's got nothing to scroll. Windows notices this and sends the message to the parent. That's the panel, now it will scroll.
You'll find code for a custom panel that can get the focus in this answer.
UPDATE: note that this behavior has changed in Windows 10. The new "Scroll inactive windows when I hover over them" option is turned on by default. The makes the mouse wheel behavior more consistent with the way it works in a browser or, say, an Office program. In this specific case the picturebox now will get the event. Watch out for this.
To wire it up manually...
this.panel1.MouseWheel += new System.Windows.Forms.MouseEventHandler(this.panel1_MouseWheel);
private void panel1_MouseWheel(object sender, System.Windows.Forms.MouseEventArgs e)
{
///process mouse event
}
Easier method is in visual studio click on panel, goto properties viewpanel, select events, locate and double click the "mousewheel" event.
In Winforms, this is achieved using the Control.MouseWheel event
Getting mousewheel events is tricky. The easiest way is using
this.MouseWheel += new System.Windows.Forms.MouseEventHandler(this.panel1_MouseWheel);
instead of
this.panel1.MouseWheel += new System.Windows.Forms.MouseEventHandler(this.panel1_MouseWheel);
This way the form gets the event instead of control. This way is easy but has one problem: you can use only one mousewheel event in your form.
If you have more than one control to get mousewheel event the best way is This answer by "Shehan Silva - weltZ"

Correct usage of OnClick vs. MouseClick events in Windows Forms applications using C#

I'm currently developing a custom control and realize that my code is being run twice. It is not really a huge issue (it is only a Focus method call). However, I would like to understand it.
From reading the MSDN description for click | onclick event, it states that:
Fires when the user clicks the left mouse button on the object.
So I added the OnClick event and the MouseClick events to handle both left and right clicking. But after debugging the code I found that the OnClick handles both left and right click events.
Why is OnClick handling both and do I need to keep both events in my code for some reason I'm overlooking?
protected override void OnClick(EventArgs e)
{
this.Focus();
base.OnClick(e);
}
private void CustomControl_MouseClick(object sender, MouseEventArgs e)
{
if (e.Button == MouseButtons.Right)
{
rightClickMenu(e);
}
}
According to MSDN, the Click event is called not only when the mouse is clicked, but also when the Enter button is pressed. If you only need to handle mouse clicks, I'd move all of your code in the MouseClick event. You can't do it the other way around because the Click event doesn't tell you which mouse button (if any) was clicked.
First of all, your link is incorrect, it links to HTML and DHTML Reference, not WinForms :)
Correct link is Control.MouseClick event
You need to override only one method. If you want to handle only mouse clicks - override OnMouseClick() and don't handle MouseClick event, otherwise - override OnClick() and don't override OnMouseClick().
You shouldn't need to have both events... Just keep the OnClick.
Also, I haven't done Windows Forms in quite a while, but I think there's a better way to accept focus than manually setting it on the click event, but I can't tell you specifically what it is... I think there's a property for it or something.
In Winforms, the Click event is raised when either mouse key is clicked.
If my memory serves me right, click does both mouseclick and the 'Enter' key or even setting focus on the control using the 'Tab' key and then using 'Space' or 'Enter' to "click" it.
If such behaviour is acceptable/desired, you may do the following.
I had this workaround for a DoubleClick event...
void ControlClick(object sender, EventArgs e)
{
MouseEventArgs mEvt=e as MouseEventArgs; // or (MouseEventArgs)e;
// now mEvt has the same properties as 'e' in MouseClick event
}
Hope this helps.
-Nurchi
The OnClick and CustomControl_MouseClick is the same event
You can have how many methods you want attached to an event ( this.Click += ...)

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