How to submit events to InkCanvas in WPF manually? - wpf

How would I be able to submit events manually to be received by InkCanvas ?
What I need to do, is to set the mode of InkCanvas to ink mode, and then, send virtual events to InkCanvas so that I get a drawing behavior as if user used the real mouse.
Thanks

The following code snippet shows an example of drawing a shape in InkCanvas:
StylusPointCollection stroke1Points = new StylusPointCollection();
stroke1Points.Add(new StylusPoint(50,10));
stroke1Points.Add(new StylusPoint(90,50));
stroke1Points.Add(new StylusPoint(10,50));
stroke1Points.Add(new StylusPoint(50,10));
Stroke stroke1 = new Stroke(stroke1Points);
canvas.Strokes.Add(stroke1);
Where canvas is of type InkCanvas. The above generates a triangle in the canvas.
"And yes, you may accept the answer if it helps you."

Something like this?
private void inkSurface_MouseLeftButtonDown(object sender, MouseButtonEventArgs e)
{
inkSurface.CaptureMouse();
_inkStroke = new Stroke(
e.StylusDevice.GetStylusPoints(inkSurface));
_inkStroke.DrawingAttributes.Width = 5;
_inkStroke.DrawingAttributes.Height = 5;
_inkStroke.DrawingAttributes.Color = Colors.Black;
inkSurface.Strokes.Add(_inkStroke);
e.Handled = true;
}
private void inkSurface_MouseMove(object sender, MouseEventArgs e)
{
if (_inkStroke != null)
{
_inkStroke.StylusPoints.Add(
e.StylusDevice.GetStylusPoints(inkSurface));
}
e.Handled = true;
}
private void inkSurface_MouseLeftButtonUp(object sender, MouseButtonEventArgs e)
{
inkSurface.ReleaseMouseCapture();
e.Handled = true;
}

Related

Access to the Ok/Accept Or Cancel Button of a RepositoryItemTimeSpanEdit?

I need to know if there is a way to access to the events of the buttons inside a RepositoryItemTimeSpanEdit.
Image to see the buttons I need the events for: Click
Image
I have tried to access in the PopUp event and QueryPopUp, however I can't get the button in any way yet.
You can get this form through Form.OwnedForms property in Popup event. The type of this form is DevExpress.XtraEditors.Popup.TimeSpanEditDropDownForm, so you need just to find the form of this type. After that you can access buttons by using TimeSpanEditDropDownForm.OkButton property and TimeSpanEditDropDownForm.CloseButton property.
Here is example:
private void repositoryItemTimeSpanEdit1_Popup(object sender, EventArgs e)
{
var popupForm = (TimeSpanEditDropDownForm)OwnedForms.FirstOrDefault(item => item is TimeSpanEditDropDownForm);
if (popupForm == null)
return;
popupForm.OkButton.Click += OkButton_Click;
popupForm.CloseButton.Click += CloseButton_Click;
}
private void OkButton_Click(object sender, EventArgs e)
{
MessageBox.Show("Ok");
}
private void CloseButton_Click(object sender, EventArgs e)
{
MessageBox.Show("Cancel");
}

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;
}

WinForms - WPF like painting

We know very well how easy is too create a WPF application where user can paint a rectangle using the mouse. To do this you just create a Rectangle control and set its coordinates, you don't worry about DoubleBuffering, repainting and such stuff. Well, I'd be very happy yo use WPF for the application where user can paint different shapes, but the clients insists to be a WinForms application. So the solution here is to use the XOR or ROP operation like in old good WinAPI years and I don't really like this. This doesn't give me a nice option to move a text while in XOR mode.
So I was thinking how can I achieve same smooth painting experience in a WinForms application like I'd have in WPF. Put together such a code, where I wanted to create a separate layer where I'd paint the current shape, while leaving intact the rest of the objects. I used same technique in an iPad application and worked pretty well.
using System;
using System.ComponentModel;
using System.Drawing;
using System.Windows.Forms;
namespace TestPainting
{
public partial class Form1 : Form
{
private bool _isMouseDown;
private Graphics _bufferGraphics;
private Point _startPos;
private TransparentPanel _paintBuffer;
public Form1()
{
InitializeComponent();
}
private void Form1_Load(object sender, EventArgs e)
{
}
private void Form1_MouseDown(object sender, MouseEventArgs e)
{
_isMouseDown = true;
_paintBuffer = new TransparentPanel
{
Size = Size,
};
Controls.Add(_paintBuffer);
_paintBuffer.BringToFront();
_bufferGraphics = Graphics.FromHwnd(_paintBuffer.Handle);
_startPos = e.Location;
Capture = true;
}
private void Form1_MouseMove(object sender, MouseEventArgs e)
{
if (!_isMouseDown)
return;
_bufferGraphics.Clear(Color.Transparent);
_bufferGraphics.DrawRectangle(Pens.Green, _startPos.X, _startPos.Y, e.X - _startPos.X, e.Y - _startPos.Y);
}
private void Form1_MouseUp(object sender, MouseEventArgs e)
{
_isMouseDown = false;
Capture = false;
_bufferGraphics.Dispose();
Controls.Remove(_paintBuffer);
_paintBuffer.Dispose();
}
}
public class TransparentPanel : Panel
{
public TransparentPanel()
{
DoubleBuffered = true;
}
[Browsable(false)]
protected override CreateParams CreateParams
{
get
{
CreateParams cp = base.CreateParams;
cp.ExStyle |= 0x20;
return cp;
}
}
protected override void OnPaintBackground(PaintEventArgs e)
{
// Do Nothing
}
}
}
which if course doesn't work as needed. I'm getting a black panel when pressing the mouse instead of a transparent one. Plus the rectangle while is painted flickers a lot, even though I did set the DoubleBuffering stuff.
Can someone provide some better ideas of such an implementation or maybe there some other open source project where I can see how other people are doing. I'd need to have same experience as in Paint.NET, just too bad is not open source anymore. (I know I can use Reflector, and I did, but man, there is tons of code over there :) )
Thx for any ideas.
Try this (see FIX #1 and FIX #2):
private void Form1_MouseDown( object sender, MouseEventArgs e )
{
_isMouseDown = true;
_paintBuffer = new TransparentPanel
{
Size = Size,
};
Controls.Add( _paintBuffer );
_paintBuffer.BringToFront();
// FIX #1:
//
this.Refresh();
_bufferGraphics = Graphics.FromHwnd( _paintBuffer.Handle );
_startPos = e.Location;
Capture = true;
}
private void Form1_MouseMove( object sender, MouseEventArgs e )
{
if ( !_isMouseDown )
return;
//FIX #2:
// _bufferGraphics.Clear( Color.Transparent );
_bufferGraphics.Clear( this.BackColor );
_bufferGraphics.DrawRectangle( Pens.Green, _startPos.X, _startPos.Y, e.X - _startPos.X, e.Y - _startPos.Y );
}

Silverlight 4:How to delay Mouseenter event

i have a situation where : User moves mouse over the image .
If user keeps mouse on that image for specific time ex. 2 seconds then only i have to proceed
further in mouseenter event otherwise don't.
I have already refred to http://forums.silverlight.net/t/86671.aspx/1 but looks like mine is different case.
One option is to use a DispatchTimer to determine the length of the mouse over.
bool isMouseOverImage = false;
public void Image_MouseEnter(object sender, MouseEventArgs e)
{
this.isMouseOverImage = true;
var timer = new System.Windows.Threading.DispatcherTimer();
timer.Interval = TimeSpan.FromSeconds(2);
timer.Tick += (object timerSender, EventArgs timerArgs) =>
{
if(this.isMouseOverImage)
{
// write your code
}
// stop the timer
timer.Stop();
};
timer.Start();
}
public void Image_MouseLeave(object sender, MouseEventArgs e)
{
this.isMouseOverImage = false;
}
If you have multiple images, you should create a re-usable Behavior and attach it to each image. I can define code for that if that would help.

WPF: Button single click + double click issue

I have to handle both the single click and the double click of a button in a WPF application with different reaction.
Unfortunately, on a doubleclick, WPF fires two click event and a double click event, so it's hard to handle this situation.
It tried to solve it using a timer but without success...I hope you can help me.
Lets see the code:
private void delayedBtnClick(object statInfo)
{
if (doubleClickTimer != null)
doubleClickTimer.Dispose();
doubleClickTimer = null;
this.Dispatcher.Invoke(System.Windows.Threading.DispatcherPriority.Normal, new VoidDelegate(delegate()
{
// ... DO THE SINGLE CLICK ACTION
}));
}
private void btn_Click(object sender, RoutedEventArgs e)
{
if (doubleClickTimer == null)
doubleClickTimer = new Timer(delayedBtnClick, null, System.Windows.Forms.SystemInformation.DoubleClickTime, Timeout.Infinite);
}
}
}
private void btnNext_MouseDoubleClick(object sender, MouseButtonEventArgs e)
{
if (doubleClickTimer != null)
doubleClickTimer.Change(Timeout.Infinite, Timeout.Infinite); // disable it - I've tried it with and without this line
doubleClickTimer.Dispose();
doubleClickTimer = null;
//.... DO THE DOUBLE CLICK ACTION
}
The problem is that the 'SINGLE CLICK ACTION' called after the 'DOUBLE CLICK ACTION' on doubleclick. It's strange that I set thedoubleClickTimer to null on double click but in the delayedBtnClick it's true :O
I've already tried to use longer time, a bool flag and lock...
Do you have any ideas?
Best!
If you set the RoutedEvent's e.Handled to true after handling the MouseDoubleClick event then it will not call the Click Event the second time after the MouseDoubleClick.
There's a recent post which touches on having different behaviors for SingleClick and DoubleClick which may be useful.
However, if you are sure you want separate behaviors and want/need to block the first Click as well as the second Click, you can use the DispatcherTimer like you were.
private static DispatcherTimer myClickWaitTimer =
new DispatcherTimer(
new TimeSpan(0, 0, 0, 1),
DispatcherPriority.Background,
mouseWaitTimer_Tick,
Dispatcher.CurrentDispatcher);
private void Button_MouseDoubleClick(object sender, MouseButtonEventArgs e)
{
// Stop the timer from ticking.
myClickWaitTimer.Stop();
Trace.WriteLine("Double Click");
e.Handled = true;
}
private void Button_Click(object sender, RoutedEventArgs e)
{
myClickWaitTimer.Start();
}
private static void mouseWaitTimer_Tick(object sender, EventArgs e)
{
myClickWaitTimer.Stop();
// Handle Single Click Actions
Trace.WriteLine("Single Click");
}
You could try this:
Button.MouseLeftButtonDown += Button_MouseLeftButtonDown;
private void Button_MouseLeftButtonDown(object sender, MouseButtonEventArgs e)
{
e.Handled = true;
if (e.ClickCount > 1)
{
// Do double-click code
}
else
{
// Do single-click code
}
}
If neccessary, you could require mouse click and wait until mouse up to perform the action.

Resources