Draw line on run time WPF - wpf

I want to draw line on run time using mouse.I have tried in below way
private void Image_MouseLeftButtonDown(object sender, MouseButtonEventArgs e)
{
FrameworkElement f = e.Source as FrameworkElement;
FrameworkElement pr = f.Parent as FrameworkElement;
Rect feRect = f.TransformToAncestor(pr).TransformBounds(
new Rect(0.0, 0.0, f.ActualWidth, f.ActualHeight));
Image image = sender as Image;
Point textLocation = e.GetPosition(image);
textLocation.Offset(-4, -4);
var Top = feRect.Height - textLocation.Y;
var Bottom = textLocation.Y - 1;
var Left = textLocation.X - 1;
var Right = feRect.Width-textLocation.X;
// Create an annotation where the mouse cursor is located.and add control using adorner layer
_currentAnnotations = ImageAnnotation.Create(
image,
textLocation,
feRect
);
}
private void Image_MouseMove(object sender, MouseEventArgs e)
{
if (e.LeftButton == MouseButtonState.Pressed)
{
Image image = sender as Image;
EndPosition = e.MouseDevice.GetPosition(image);
// Draw next line and...
l.X1 = StartPosition.X;
l.X2 = EndPosition.X;
l.Y1 = StartPosition.Y;
l.Y2 = EndPosition.Y;
l.Stroke = Brushes.Red;
l.StrokeThickness = 5;
StartPosition = EndPosition;
}
if(_currentAnnotations!=null && l!=null)
_currentAnnotations.Lines = l;
}
But it doesn't give the result as expected. the line that am getting is different from the mouse location. my output should be like a pen tool. 1.what's wrong with my way?
2. Is inkCanvas the only way to draw line in wpf?if yes why so?
3.

1.what's wrong with my way?
You could try to set the StartPosition property in the Image_MouseLeftButtonDown event handler:
private void Image_MouseLeftButtonDown(object sender, MouseButtonEventArgs e)
{
FrameworkElement f = e.Source as FrameworkElement;
FrameworkElement pr = f.Parent as FrameworkElement;
Rect feRect = f.TransformToAncestor(pr).TransformBounds(
new Rect(0.0, 0.0, f.ActualWidth, f.ActualHeight));
Image image = sender as Image;
...
StartPosition = e.MouseDevice.GetPosition(image);
}
InkCanvas is the only built-in WPF control that receives and displays ink strokes. But you could for example add lines to a Canvas or perform any other kind of custom drawing action yourself.
Here is a basic sample that should give you the idea.
public partial class MainWindow : Window
{
public MainWindow ()
{
InitializeComponent();
}
Point EndPosition;
Point StartPosition;
private void canvas_MouseMove(object sender, MouseEventArgs e)
{
if (e.LeftButton == MouseButtonState.Pressed)
{
FrameworkElement fe = sender as FrameworkElement;
EndPosition = e.MouseDevice.GetPosition(fe);
Line l = new Line();
l.X1 = StartPosition.X;
l.X2 = EndPosition.X;
l.Y1 = StartPosition.Y;
l.Y2 = EndPosition.Y;
l.Stroke = Brushes.Red;
l.StrokeThickness = 5;
StartPosition = EndPosition;
canvas.Children.Add(l);
}
}
private void canvas_MouseLeftButtonDown(object sender, MouseButtonEventArgs e)
{
FrameworkElement fe = sender as FrameworkElement;
StartPosition = e.MouseDevice.GetPosition(fe);
}
}
<Canvas x:Name="canvas" Width="500" Height="500" Background="Yellow"
MouseLeftButtonDown="canvas_MouseLeftButtonDown" MouseMove="canvas_MouseMove" />

Related

ScrollViewer inside ScrollViewer WPF

In my WPF page I need to scroll vertically and inside (this ScrollViewer) I need several horizontal scrolls. At the beginning i had the problem was that when I pointed with my mouse on the inside ScrollViewer area I cant scroll the page (vertically).I found a post:
https://serialseb.com/blog/2007/09/03/wpf-tips-6-preventing-scrollviewer-from/
it resolved my mouse problem, but now I have the same problem on Touch display. I can't use my finger to vertically scroll on the inside scrollviewer. Anyone has any idea to change the below code to let it work for touch display? Thanks
public class ScrollViewerCorrector
{
public static bool GetFixScrolling(DependencyObject obj)
{
return (bool)obj.GetValue(FixScrollingProperty);
}
public static void SetFixScrolling(DependencyObject obj, bool value)
{
obj.SetValue(FixScrollingProperty, value);
}
public static readonly DependencyProperty FixScrollingProperty =
DependencyProperty.RegisterAttached("FixScrolling", typeof(bool), typeof(ScrollViewerCorrector), new FrameworkPropertyMetadata(false, ScrollViewerCorrector.OnFixScrollingPropertyChanged));
public static void OnFixScrollingPropertyChanged(object sender, DependencyPropertyChangedEventArgs e)
{
ScrollViewer viewer = sender as ScrollViewer;
if (viewer == null)
throw new ArgumentException("The dependency property can only be attached to a ScrollViewer", "sender");
if ((bool)e.NewValue == true)
viewer.PreviewMouseWheel += HandlePreviewMouseWheel;
else if ((bool)e.NewValue == false)
viewer.PreviewMouseWheel -= HandlePreviewMouseWheel;
}
private static List<MouseWheelEventArgs> _reentrantList = new List<MouseWheelEventArgs>();
private static void HandlePreviewMouseWheel(object sender, MouseWheelEventArgs e)
{
var scrollControl = sender as ScrollViewer;
if (!e.Handled && sender != null && !_reentrantList.Contains(e))
{
var previewEventArg = new MouseWheelEventArgs(e.MouseDevice, e.Timestamp, e.Delta)
{
RoutedEvent = UIElement.PreviewMouseWheelEvent,
Source = sender
};
var originalSource = e.OriginalSource as UIElement;
_reentrantList.Add(previewEventArg);
originalSource.RaiseEvent(previewEventArg);
_reentrantList.Remove(previewEventArg);
// at this point if no one else handled the event in our children, we do our job
if (!previewEventArg.Handled && ((e.Delta > 0 && scrollControl.VerticalOffset == 0)
|| (e.Delta <= 0 && scrollControl.VerticalOffset >= scrollControl.ExtentHeight - scrollControl.ViewportHeight)))
{
e.Handled = true;
var eventArg = new MouseWheelEventArgs(e.MouseDevice, e.Timestamp, e.Delta);
eventArg.RoutedEvent = UIElement.MouseWheelEvent;
eventArg.Source = sender;
var parent = (UIElement)((FrameworkElement)sender).Parent;
parent.RaiseEvent(eventArg);
}
}
}
}

Simulating a Drag/Drop event in WPF

I want to simulate a drag/drop event in WPF.
For this I'll need to gain access to the data stored in the "Drag/Drop buffer" and also I'll need to create a DragEventArgs.
I noticed that the DragEventArgs is sealed and has no public ctor.
So my questions are:
1. how can I create an instance of DragEventArgs?
2. How can I gain access to the drag/drop buffer?
i recently do this! i simulated drag/drop with MouseDown, MouseMove and MouseUp events. for example for my application, i have some canvases that i want to drag and drop them. every canvas has an id. in MouseDown event, i buffer its id and use it in MouseMove and MouseUp event. Desktop_Canvas is my main Canvas that contains some canvases. these canvases are in my dictionary (dic).
here is my code:
private Dictionary<int, Win> dic = new Dictionary<int, Win>();
private Point downPoint_Drag = new Point(-1, -1);
private int id_Drag = -1;
private bool flag_Drag = false;
public class Win
{
public Canvas canvas = new Canvas();
public Point downpoint = new Point();
public Win()
{
canvas.Background = new SolidColorBrush(Colors.Gray);
}
}
private void Desktop_Canvas_MouseMove(object sender, MouseEventArgs e)
{
try
{
Point movePoint = e.GetPosition(Desktop_Canvas);
if (flag_Drag && downPoint_Drag != new Point(-1, -1))
{
double dy1 = movePoint.Y - downPoint_Drag.Y, x = -1, dx1 = movePoint.X - downPoint_Drag.X, y = -1;
downPoint_Drag = movePoint;
if (x == -1)
x = Canvas.GetLeft(dic[id_Drag].canvas) + dx1;
if (y == -1)
y = Canvas.GetTop(dic[id_Drag].canvas) + dy1;
Canvas.SetLeft(dic[id_Drag].canvas, x);
Canvas.SetTop(dic[id_Drag].canvas, y);
}
}
catch
{
MouseEventArgs ee = new MouseEventArgs((MouseDevice)e.Device, 10);
Desktop_Canvas_MouseLeave(null, ee);
}
}
private void Desktop_Canvas_MouseLeftButtonUp(object sender, MouseButtonEventArgs e)
{
try
{
downPoint_Drag = new Point(-1, -1);
id_Drag =-1;
flag_Drag = false;
}
catch
{
MouseEventArgs ee = new MouseEventArgs((MouseDevice)e.Device, 10);
Desktop_Canvas_MouseLeave(null, ee);
}
}
private void Desktop_Canvas_MouseLeave(object sender, MouseEventArgs e)
{
MouseButtonEventArgs ee = new MouseButtonEventArgs((MouseDevice)e.Device, 10, MouseButton.Left);
Desktop_Canvas_MouseLeftButtonUp(null, ee);
}
void canvas_MouseLeftButtonDown(object sender, MouseButtonEventArgs e)
{
downPoint_Drag = e.GetPosition(Desktop_Canvas);
int hoverId = HoverWin(downPoint_Drag);
flag_Drag = true;
id_Drag = hoverId;
dic[id_Drag].downpoint = new Point(downPoint_Drag.X, downPoint_Drag.Y);
}
private int HoverWin(Point p)
{
foreach (int i in dic.Keys)
{
if (dic[i].canvas.IsMouseOver)
return i;
}
return -1;
}

Change the location of the window form in c#?

In window application, using c# i created one form and put visible false minimize, maximize button and formborder to none, i place one panel at top of the form, in that panel i place close, minimize buttons. Now how can i drag the window form. Any reference please. my code is
this.ControlBox = false;
this.MaximizeBox = false;
this.MinimizeBox = false;
this.FormBorderStyle = FormBorderStyle.None;
Thank you.
Simply register the MouseDown, MouseMove and MoueUp events for your Panel
bool MouseDownFlag = false;
Point start = new Point(0, 0);
private void panel1_MouseDown(object sender, MouseEventArgs e)
{
start = new Point(e.X, e.Y);
MouseDownFlag = true;
}
private void panel1_MouseMove(object sender, MouseEventArgs e)
{
if (MouseDownFlag)
{
Point newPoint = new Point();
newPoint.X = this.Location.X - (start.X - e.X);
newPoint.Y = this.Location.Y - (start.Y - e.Y);
this.Location = newPoint;
}
}
private void panel1_MouseUp(object sender, MouseEventArgs e)
{
MouseDownFlag = false;
}

Polygon Mouse Left Button Down Not Firing and Polygon child possible or not?

I have a polygon which has a MouseLeftButtonDown event. When I click near its edges (say 10 pixes inside from the borders) the event is not called. What could be the problem of this?
Secondly, can we add child of a polygon?
private void Window_Loaded(object sender, RoutedEventArgs e)
{
Polygon p = new Polygon() {
Stroke = Brushes.Black,
StrokeThickness = 2,
Points = new PointCollection() {new Point(10,10), new Point(50,10),
new Point(56, 45) }};
p.MouseLeftButtonDown += new MouseButtonEventHandler(p_MouseLeftButtonDown);
mygrd.Children.Add(p);
}
void p_MouseLeftButtonDown(object sender, MouseButtonEventArgs e)
{
MessageBox.Show("Entered");
}
give the polygon a fill brush and your mouse event fires
private void Window_Loaded(object sender, RoutedEventArgs e)
{
Polygon p = new Polygon() {
Stroke = Brushes.Black,
StrokeThickness = 2,
Fill = Brushes.Transparent, // or something else
Points = new PointCollection() {new Point(10,10), new Point(50,10), new Point(56, 45) }};
p.MouseLeftButtonDown += new MouseButtonEventHandler(p_MouseLeftButtonDown);
mygrd.Children.Add(p);
}

How to know the position of the Silverlight ChildWindow when you close it

Please, help me.
public myChildWindow()
{
InitializeComponent();
// set left and top from saved values
Margin = new Thickness(70, 50, 0, 0);
}
private void ChildWindow_Closed(object sender, EventArgs e)
{
// How to know the position of the ChildWindow when you close it ?
// get left and top for save values
...
}
Oops you are right, try this:
Wire up the window to the following events (I did this via simple button click)
var childWindow = new ChildWindow();
childWindow.Closing += new EventHandler<CancelEventArgs>(OnChildWindowClosing);
childWindow.Show();
Now what you need to do is walk the ChildWindow PARTS DOM and find the ContentRoot which will give you the position.
static void OnChildWindowClosing(object sender, CancelEventArgs e)
{
var childWindow = (ChildWindow)sender;
var chrome = VisualTreeHelper.GetChild(childWindow, 0) as FrameworkElement;
if (chrome == null) return;
var contentRoot = chrome.FindName("ContentRoot") as FrameworkElement;
if (contentRoot == null || Application.Current == null || Application.Current.RootVisual == null) return;
var gt = contentRoot.TransformToVisual(Application.Current.RootVisual);
if (gt == null) return;
var windowPosition = gt.Transform(new Point(0, 0));
MessageBox.Show("X:" + windowPosition.X + " Y:" + windowPosition.Y);
}
HTH.
You can find out the Left/Top values from the Window provided you are subscribing to the Closing event and not Closed
ie:
private void Button_Click(object sender, RoutedEventArgs e)
{
LoginWindow loginWnd = new LoginWindow();
loginWnd.Closing += new EventHandler(loginWnd_Closing);
}
Then to get the position values use:
double x = GetValue(ChildWindow.LeftProperty) as double;
double y = GetValue(ChildWindow.TopProperty) as double;

Resources