I'm trying to move the Button inside my application, It's working fine but the ButtonClick event is not firing now.
Code :
XAML
<Button Content="Button" Height="23" HorizontalAlignment="Left"
Margin="190,108,0,0" Name="button1" VerticalAlignment="Top"
Width="75" MouseLeftButtonUp="button1_MouseLeftButtonUp"
MouseMove="button1_MouseMove" MouseUp="button1_MouseUp" Click="button1_Click"/>
C#
public MainWindow()
{
InitializeComponent();
button1.PreviewMouseUp += new MouseButtonEventHandler(button1_MouseUp);
button1.PreviewMouseLeftButtonDown += new MouseButtonEventHandler
(button1_MouseLeftButtonUp);
button1.PreviewMouseMove += new MouseEventHandler(button1_MouseMove);
}
double m_MouseX;
double m_MouseY;
public MainWindow()
{
InitializeComponent();
button1.PreviewMouseUp += new MouseButtonEventHandler(button1_MouseUp);
button1.PreviewMouseLeftButtonDown += new MouseButtonEventHandler(button1_MouseLeftButtonUp);
button1.PreviewMouseMove += new MouseEventHandler(button1_MouseMove);
}
private void button1_MouseLeftButtonUp(object sender, System.Windows.Input.MouseButtonEventArgs e)
{
// Get the Position of Window so that it will set margin from this window
m_MouseX = e.GetPosition(this).X;
m_MouseY = e.GetPosition(this).Y;
}
private void button1_MouseMove(object sender, System.Windows.Input.MouseEventArgs e)
{
if (e.LeftButton == MouseButtonState.Pressed)
{
// Capture the mouse for border
e.MouseDevice.Capture(button1);
System.Windows.Thickness _margin = new System.Windows.Thickness();
int _tempX = Convert.ToInt32(e.GetPosition(this).X);
int _tempY = Convert.ToInt32(e.GetPosition(this).Y);
_margin = mainGrd.Margin;
// when While moving _tempX get greater than m_MouseX relative to usercontrol
if (m_MouseX > _tempX)
{
// add the difference of both to Left
_margin.Left += (_tempX - m_MouseX);
// subtract the difference of both to Left
_margin.Right -= (_tempX - m_MouseX);
}
else
{
_margin.Left -= (m_MouseX - _tempX);
_margin.Right -= (_tempX - m_MouseX);
}
if (m_MouseY > _tempY)
{
_margin.Top += (_tempY - m_MouseY);
_margin.Bottom -= (_tempY - m_MouseY);
}
else
{
_margin.Top -= (m_MouseY - _tempY);
_margin.Bottom -= (_tempY - m_MouseY);
}
mainGrd.Margin = _margin;
m_MouseX = _tempX;
m_MouseY = _tempY;
}
}
private void button1_MouseUp(object sender, System.Windows.Input.MouseButtonEventArgs e)
{
e.MouseDevice.Capture(null);
}
private void button1_Click(object sender, RoutedEventArgs e)
{
MessageBox.Show("HI");
}
button1_Click never fires, any suggestions.
Is I'm doing something wrong or there is a better way to do it?
This prevents your button1_Click from firing:
e.MouseDevice.Capture(null);
I assume that you want the messagebox to show only when you click the button without dragging it.
I would remove the MouseUp event and instead use:
XAML
PreviewMouseDown="Button1_OnPreviewMouseDown"
C#
double m_MouseX;
double m_MouseY;
double m_ClickedX;
double m_ClickedY;
[...]
private void Button1_OnPreviewMouseDown(object sender, MouseButtonEventArgs e)
{
m_ClickedX = m_MouseX;
m_ClickedY = m_MouseY;
}
private void button1_Click(object sender, RoutedEventArgs e)
{
if (m_ClickedX == m_MouseX && m_ClickedY == m_MouseY)
{
MessageBox.Show("HI");
}
}
The if statement checks if you have moved the button or not and only shows the MessageBox if the button has not been moved.
Related
I want to open an app or do something with a bottom swipe, so what can I do to get the event? It's like this: https://www.microsoft.com/zh-cn/videoplayer/embed/fc016fcc-2bb1-4294-b236-343e1a533401?autoCaptions=en-us
I tried using the EdgeGesture class in UWP apps, which provides events for Starting, Completed, and Canceled. But when I swiped at the edge of the screen, no event was triggered.
In MainPage.xaml.cs:
public MainPage()
{
this.InitializeComponent();
//ApplicationView.GetForCurrentView().TryEnterFullScreenMode();
EdgeGesture gesture = EdgeGesture.GetForCurrentView();
gesture.Starting += Gesture_Starting;
gesture.Completed += Gesture_Completed;
gesture.Canceled += Gesture_Canceled;
}
private void Gesture_Canceled(EdgeGesture sender, EdgeGestureEventArgs args)
{
throw new NotImplementedException();
}
private void Gesture_Completed(EdgeGesture sender, EdgeGestureEventArgs args)
{
throw new NotImplementedException();
}
private void Gesture_Starting(EdgeGesture sender, EdgeGestureEventArgs args)
{
throw new NotImplementedException();
}
Don't know if I did something wrong, can help me? Or is there another way to do this?
In desktop mode, the UWP application is a window application that makes it difficult to capture screen edge slip events, and EdgeGesture may work in tablet mode.
In order to adapt to the sliding needs of different situations, you can consider using GestureRecognizer.
Here I will give you a simple page for reference.
<Page ...>
<Grid Background="White">
</Grid>
</Page>
private GestureRecognizer _GestureRecognizer;
PointerEventHandler PointerPressedEventHandler;
PointerEventHandler PointerMovedEventHandler;
PointerEventHandler PointerReleasedEventHandler;
PointerEventHandler PointerCanceledEventHandler;
private double startY = 0;
private double moveY = 0;
public GesturePage()
{
this.InitializeComponent();
_GestureRecognizer = new GestureRecognizer();
_GestureRecognizer.GestureSettings = GestureSettings.ManipulationTranslateY;
_GestureRecognizer.ManipulationStarted += _GestureRecognizer_ManipulationStarted;
_GestureRecognizer.ManipulationUpdated += _GestureRecognizer_ManipulationUpdated;
_GestureRecognizer.ManipulationCompleted += _GestureRecognizer_ManipulationCompleted;
PointerPressedEventHandler = new PointerEventHandler(_PointerPressed);
PointerMovedEventHandler = new PointerEventHandler(_PointerMoved);
PointerReleasedEventHandler = new PointerEventHandler(_PointerReleased);
PointerCanceledEventHandler = new PointerEventHandler(_PointerCanceled);
this.AddHandler(UIElement.PointerPressedEvent, PointerPressedEventHandler, true);
this.AddHandler(UIElement.PointerMovedEvent, PointerMovedEventHandler, true);
this.AddHandler(UIElement.PointerReleasedEvent, PointerReleasedEventHandler, true);
this.AddHandler(UIElement.PointerCanceledEvent, PointerCanceledEventHandler, true);
}
private void _GestureRecognizer_ManipulationStarted(GestureRecognizer sender, ManipulationStartedEventArgs args)
{
startY = args.Position.Y;
}
private void _GestureRecognizer_ManipulationUpdated(GestureRecognizer sender, ManipulationUpdatedEventArgs args)
{
moveY += Math.Abs(args.Delta.Translation.Y);
}
private void _GestureRecognizer_ManipulationCompleted(GestureRecognizer sender, ManipulationCompletedEventArgs args)
{
if (moveY >= 50)
{
// Can be understood as sliding a distance
if (startY <= 10)
{
// head to foot
}
else if (startY >= Window.Current.Bounds.Height - 10)
{
// foot to head
}
startY = 0;
MoveY = 0;
}
}
private void _PointerPressed(object sender, PointerRoutedEventArgs e)
{
var pointer = e.GetCurrentPoint(this);
_GestureRecognizer.ProcessDownEvent(pointer);
}
private void _PointerMoved(object sender, PointerRoutedEventArgs e)
{
var pointers = e.GetIntermediatePoints(this);
_GestureRecognizer.ProcessMoveEvents(pointers);
}
private void _PointerCanceled(object sender, PointerRoutedEventArgs e)
{
var pointer = e.GetCurrentPoint(this);
_GestureRecognizer.CompleteGesture();
}
private void _PointerReleased(object sender, PointerRoutedEventArgs e)
{
var pointer = e.GetCurrentPoint(this);
_GestureRecognizer.ProcessUpEvent(pointer);
}
Fingers, mouse, and pens trigger Pointer related events when they tap the screen. The purpose of the above code is to capture the Pointer event and pass it to GestureRecognizer for processing.
Here is the document
Best regards.
I want to move the label by using the Mouse_Move/Mouse_Down events.
I tried to do it like this:
private void control_MouseDown(object sender, MouseButtonEventArgs e)
{
Label l = e.Source as Label;
if (l != null)
{
l.CaptureMouse();
moving = true;
PositionInLabel = e.GetPosition(l);
}
}
private void control_MouseMove(object sender, MouseEventArgs e)
{
if (moving)
{
Point p = e.GetPosition(null);
DeltaX = p.X - BasePoint.X - PositionInLabel.X;
DeltaY = p.Y - BasePoint.Y - PositionInLabel.Y;
RaisePropertyChanged("XPosition");
RaisePropertyChanged("YPosition");
}
}
Suppose your label is on a Canvas:
public MainWindow()
{
InitializeComponent();
this.label.MouseLeftButtonDown += control_MouseLeftButtonDown;
this.label.MouseMove += control_MouseMove;
this.label.MouseLeftButtonUp += control_MouseLeftButtonUp;
}
// Keep track of the Canvas where this element is placed.
private Canvas canvas;
// Keep track of when the element is being dragged.
private bool isDragging = false;
// When the element is clicked, record the exact position
// where the click is made.
private Point mouseOffset;
private void control_MouseLeftButtonDown(object sender, MouseButtonEventArgs e)
{
Label l = e.Source as Label;
if (l == null)
return;
// Find the Canvas.
if (canvas == null)
canvas = (Canvas)VisualTreeHelper.GetParent(l);
// Dragging mode begins.
isDragging = true;
// Get the position of the click relative to the element
// (so the top-left corner of the element is (0,0).
mouseOffset = e.GetPosition(l);
// Capture the mouse. This way you'll keep receiving
// the MouseMove event even if the user jerks the mouse
// off the element.
l.CaptureMouse();
}
private void control_MouseMove(object sender, MouseEventArgs e)
{
Label l = e.Source as Label;
if (l == null)
return;
if (isDragging)
{
// Get the position of the element relative to the Canvas.
Point point = e.GetPosition(canvas);
// Move the element.
l.SetValue(Canvas.TopProperty, point.Y - mouseOffset.Y);
l.SetValue(Canvas.LeftProperty, point.X - mouseOffset.X);
}
}
private void control_MouseLeftButtonUp(object sender, MouseButtonEventArgs e)
{
Label l = e.Source as Label;
if (l == null)
return;
if (isDragging)
{
l.ReleaseMouseCapture();
isDragging = false;
}
}
Let containerCanvas be a Canvas which contains the Label; then you can utilize the _MouseMove(object sender, MouseEventArgs e) to move the label along with your mouse pointer:
Xaml code:
<Canvas Name="containerCanvas" MouseMove="containerCanvas_MouseMove" Background="Aqua" Width="525" Height="350" >
<Label Name="floatingLabel" Height="28" Width="161" Background="AliceBlue"></Label>
</Canvas>
C# code:
private void containerCanvas_MouseMove(object sender, MouseEventArgs e)
{
Point p = Mouse.GetPosition(Application.Current.MainWindow);
floatingLabel.Margin = new Thickness(p.X, p.Y, 0, 0);
}
I have done a sample code. Check this. It should work.
XAML :
<UserControl HorizontalAlignment="Left" x:Class="WPFDiagramDesignerControl.Components.TestApp"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Height="100" Width="100" IsEnabled="True">
<Grid >
<Canvas x:Name="MyDesigner">
<TextBox x:Name="txtBox" IsEnabled="True" Background="AntiqueWhite" Margin="10,10,10,10" TextWrapping="Wrap"> </TextBox>
</Canvas>
</Grid>
Code Behind :
public TestApp()
{
InitializeComponent();
txtBox.MouseDoubleClick+=new MouseButtonEventHandler(control_MouseDoubleClick);
txtBox.MouseMove+=new MouseEventHandler(control_MouseMove);
txtBox.PreviewMouseDown+=new MouseButtonEventHandler(control_PreviewMouseDown);
txtBox.PreviewMouseUp+=new MouseButtonEventHandler(control_PreviewMouseUp);
txtBox.Cursor = Cursors.SizeAll;
}
private void control_MouseMove(object sender, RoutedEventArgs e)
{
if (isClicked)
{
Point mousePos = Mouse.GetPosition(parentCanvas);
parentItem = this.Parent as DesignerItem;
parentCanvas = parentItem.Parent as DesignerCanvas;
Point relativePosition = Mouse.GetPosition(parentCanvas);
DesignerCanvas.SetLeft(this, DesignerCanvas.GetLeft(this) - (startPoint.X - mousePos.X));
DesignerCanvas.SetTop(this, DesignerCanvas.GetTop(this) - (startPoint.Y - mousePos.Y));
}
}
private void control_PreviewMouseDown(object sender, RoutedEventArgs e)
{
if (!isClicked)
{
isClicked = true;
parentItem = this.Parent as DesignerItem;
parentCanvas = parentItem.Parent as DesignerCanvas;
startPoint = Mouse.GetPosition(parentCanvas);
}
}
private void control_PreviewMouseUp(object sender, RoutedEventArgs e)
{
isClicked = false;
}
I'm having a bit of trouble making drag and drop a button in a panel and panel to recognize it and display Message with buttons name
So far I managed the part of dragging and dropping and recognizing however I'm missing the visual style of dragging, when I press with mouse it will just sit on the same place, it won't follow cursor. How do I make it follow the mouse?
public Form1()
{
InitializeComponent();
panel1.AllowDrop = true;
panel1.DragEnter += panel_DragEnter;
panel1.DragDrop += panel_DragDrop;
button1.MouseDown += button1_MouseDown;
}
private void button1_MouseDown(object sender, System.Windows.Forms.MouseEventArgs e)
{
button1.DoDragDrop(button1.Text, DragDropEffects.Copy | DragDropEffects.Move);
button1.Location= new Point(e.X, e.Y);
}
private void panel_DragEnter(object sender, System.Windows.Forms.DragEventArgs e)
{
e.Effect = DragDropEffects.Move;
if (e.Data.GetDataPresent(DataFormats.Text))
e.Effect = DragDropEffects.Copy;
else
e.Effect = DragDropEffects.None;
}
private void panel_DragDrop(object sender, System.Windows.Forms.DragEventArgs e)
{
MessageBox.Show(e.Data.GetData(DataFormats.Text).ToString());
}
You'll have to keep in mind that the DoDragDrop method doesn't return the Position you dropped the object. The DragDrop event handles that.
To move the control while you're dragging you use the DragOver event of the panel. In the implementation you need to compensate for the fact that the X and Y coordinates in the EventArgs are Screen based while you need Clientbased coordinates to correctly position the control. The PointToClient is instrumental in that:
private void panel_DragOver(object sender, DragEventArgs e)
{
if (e.Data.GetDataPresent(typeof(Button).FullName))
{
var draggedButton = (Button)e.Data.GetData(typeof(Button).FullName);
var screenpos = new Point(e.X, e.Y);
var clientPos = panel1.PointToClient(screenpos);
// calc offset
draggedButton.Location = new Point(
clientPos.X + panel1.Left,
clientPos.Y + panel1.Top);
}
}
Notice that your Data now contains the actual Button, instead of only the text. This makes that you can dragdrop multiple buttons, not only button1.
Your DragDrop event should now look like this:
private void panel_DragDrop(object sender, System.Windows.Forms.DragEventArgs e)
{
if (e.Data.GetDataPresent(typeof(Button).FullName))
{
var draggedButton = (Button)e.Data.GetData(typeof(Button).FullName);
MessageBox.Show(draggedButton.Text);
var screenpos = new Point(e.X, e.Y);
var clientPos = panel1.PointToClient(screenpos);
draggedButton.Location = new Point(
clientPos.X + panel1.Left,
clientPos.Y + panel1.Top);
}
}
And DragEnter only slightly changed so it could handle the Button control instead of the text:
private void panel_DragEnter(object sender, System.Windows.Forms.DragEventArgs e)
{
e.Effect = DragDropEffects.Move;
if (e.Data.GetDataPresent(typeof(Button).FullName)) // button
e.Effect = DragDropEffects.Copy;
else
e.Effect = DragDropEffects.None;
}
And finally to get it all started and wired up the constructor code and the MouseDown implementation of the button:
public Form1()
{
InitializeComponent();
panel1.AllowDrop = true;
panel1.DragEnter += panel_DragEnter;
panel1.DragDrop += panel_DragDrop;
panel1.DragOver += panel_DragOver;
button1.MouseDown += button1_MouseDown;
}
private void button1_MouseDown(object sender, System.Windows.Forms.MouseEventArgs e)
{
button1.DoDragDrop(button1, DragDropEffects.Copy | DragDropEffects.Move);
}
Well ,I'm trying to make my button location as same as cursor position when the mouse left button is down so i write this :
private void button1_MouseDown(object sender, MouseEventArgs e)
{
button1.Location = Cursor.Position;
}
But the button moves so far than the position of cursor, also it occurs only once and I can't move button freely with the mouse.
What is the problem?
illustrate my comment:
private bool _isAllowMove = false;
...
button1.MouseMove += new MouseEventHandler((object sender, MouseEventArgs e) =>
{
if(!_isAllowMove) {
return;
}
button1.Location = this.PointToClient(Cursor.Position);
});
button1.MouseDown += new MouseEventHandler((object sender, MouseEventArgs e) =>
{
_isAllowMove = true;
});
button1.MouseUp += new MouseEventHandler((object sender, MouseEventArgs e) =>
{
_isAllowMove = false;
});
// other full example for new comment
Dynamically set events for all buttons:
public partial class Form1: Form
{
public Form1()
{
InitializeComponent();
//...
setHandler(button1);
setHandler(button2);
//...
}
protected void setHandler(Button btn)
{
// TODO: synchronise thread & remove old handler
/**
* e.g.:
* lock(_eLock){
* btn.MouseMove -= new MouseEventHandler(..)
* btn.MouseMove += new MouseEventHandler(..)
* }
*
*/
// NOTE: the 'AllowDrop' property only for example -
// you can replace this with your custom components - e.g. ButtonCustom()
/**
* public class ButtonCustom: Button
* {
* ...
* bool AllowMove { get; set; }
* ...
* }
*
*/
btn.AllowDrop = false;
btn.MouseMove += new MouseEventHandler((object sender, MouseEventArgs e) => {
if(!btn.AllowDrop) {
return;
}
btn.Location = this.PointToClient(Cursor.Position);
});
btn.MouseDown += new MouseEventHandler((object sender, MouseEventArgs e) => {
btn.AllowDrop = true;
});
btn.MouseUp += new MouseEventHandler((object sender, MouseEventArgs e) => {
btn.AllowDrop = false;
});
}
}
Having trouble with something here which I'm hoping is actually simple.
I have a custom UserControl in WPF which allows me to display an image. When the program is running a user can add this UserControl as many times as they like to a canvas. In effect a simple image viewer where they can add and move images about.
I would like to be able to right click these images open a contextMenu and then choose send backward of bring forward and the images would then change z order depending which menu choice was clicked.
I have the user control set up with the contextMenu so I just need to know the code for changing the z order of this userControl...
Any help is much appreciated :)
namespace StoryboardTool
{
/// <summary>
/// Interaction logic for CustomImage.xaml
/// </summary>
public partial class CustomImage : UserControl
{
private Point mouseClick;
private double canvasLeft;
private double canvasTop;
public CustomImage()
{
InitializeComponent();
cusImageControl.SetValue(Canvas.LeftProperty, 0.0);
cusImageControl.SetValue(Canvas.TopProperty, 0.0);
}
public void chooseImage()
{
OpenFileDialog ofd = new OpenFileDialog();
ofd.Title = "Choose Image to Add";
if (ofd.ShowDialog() == true)
{
BitmapImage bImage = new BitmapImage();
bImage.BeginInit();
bImage.UriSource = new Uri(ofd.FileName);
bImage.EndInit();
image.Width = bImage.Width;
image.Height = bImage.Height;
image.Source = bImage;
image.Stretch = Stretch.Fill;
}
}
private void cusImageControl_LostMouseCapture(object sender, MouseEventArgs e)
{
((CustomImage)sender).ReleaseMouseCapture();
}
private void cusImageControl_MouseUp(object sender, MouseButtonEventArgs e)
{
((CustomImage)sender).ReleaseMouseCapture();
cusImageControl.Cursor = Cursors.Arrow;
}
private void cusImageControl_MouseMove(object sender, MouseEventArgs e)
{
if ((((CustomImage)sender).IsMouseCaptured) && (cusImageControl.Cursor == Cursors.SizeAll))
{
Point mouseCurrent = e.GetPosition(null);
double Left = mouseCurrent.X - mouseClick.X;
double Top = mouseCurrent.Y - mouseClick.Y;
mouseClick = e.GetPosition(null);
((CustomImage)sender).SetValue(Canvas.LeftProperty, canvasLeft + Left);
((CustomImage)sender).SetValue(Canvas.TopProperty, canvasTop + Top);
canvasLeft = Canvas.GetLeft(((CustomImage)sender));
canvasTop = Canvas.GetTop(((CustomImage)sender));
}
else if ((((CustomImage)sender).IsMouseCaptured) && (cusImageControl.Cursor == Cursors.SizeNWSE))
{
/*Point mouseCurrent = e.GetPosition(null);
cusImageControl.Height = cusImageControl.canvasTop + mouseClick.Y;
cusImageControl.Width = cusImageControl.canvasLeft + mouseClick.X;
mouseClick = e.GetPosition(null);*/
}
}
private void cusImageControl_MouseDown(object sender, MouseButtonEventArgs e)
{
mouseClick = e.GetPosition(null);
canvasLeft = Canvas.GetLeft(((CustomImage)sender));
canvasTop = Canvas.GetTop(((CustomImage)sender));
((CustomImage)sender).CaptureMouse();
}
private void ContextMenuBringForward_Click(object sender, RoutedEventArgs e)
{
MessageBox.Show("Bring Forward");
}
private void ContextMenuSendBackward_Click(object sender, RoutedEventArgs e)
{
MessageBox.Show("Send Backward");
}
private void ContextMenuMove_Click(object sender, RoutedEventArgs e)
{
cusImageControl.Cursor = Cursors.SizeAll;
}
private void ContextMenuResize_Click(object sender, RoutedEventArgs e)
{
cusImageControl.Cursor = Cursors.SizeNWSE;
}
}
}
See Panel attached property Canvas.SetZIndex. Change z-Index of all elements to 0, and z-Index of your right-clicked control to 1.
void mouseUp(object sender, MouseButtonEventArgs e)
{
foreach (var child in yourCanvas.Children) Canvas.SetZIndex(child, 0);
Canvas.SetZIndex((UIElement)sender, 1);
}
The following code works where selected is defined as my UserControl and set in the mouseDown event.
private void ContextMenuSendBackward_Click(object sender, RoutedEventArgs e)
{
Canvas parent = (Canvas)LogicalTreeHelper.GetParent(this);
foreach (var child in parent.Children)
{
Canvas.SetZIndex((UIElement)child, 0);
}
Canvas.SetZIndex(selected, 1);
}
Thanks to voo for all his help.