I'm attempting to create something of a software zoom for an image in my Winforms application. I noticed an answer to a similar issue stating that it could be achieved with the mousewheel by using
private void image_MouseWheel(object sender, MouseWheelEventArgs e)
{
var st = (ScaleTransform)image.RenderTransform;
double zoom = e.Delta > 0 ? .2 : -.2;
st.ScaleX += zoom;
st.ScaleY += zoom;
}
That solution is exactly what I need, but it appears to be part of System.Windows.Media, which doesn't seem to be part of the Winforms architecture.
Does anyone know of a similar option for Winforms that would end up resembling this functionality? My google searches haven't turned up much :(
Thanks!
You might want to look into Graphics.ScaleTransform. The idea of arbitrary transformations as part of the rendering process isn't as all-pervasive in Windows Forms, but you could transform one image to another image via Graphics, I believe.
Related
I am interested in making a custom gui in C#, and I would like some advice as how to best go about that. The attached picture is generally what I would like to create - namely drawing text, boxes/backgrounds, pictures, lines, circles, and other gui elements (Like text input fields and the like).
I don't really know where to start, what I have been able to gleam from google searches is that GDI+ and using the paint event might be able to do what I am looking for - but I don't know if that is the way to go about making such a thing, or if it is the wrong tool for the job (aka it is slow/ineffective compared to something else).
//something along the lines of this:
private void Form1_Paint(object sender, PaintEventArgs e)
{
System.Drawing.Graphics graphicsObj;
graphicsObj = this.CreateGraphics();
Pen myPen = new Pen(System.Drawing.Color.Red, 5);
Rectangle myRectangle = new Rectangle(20, 20, 250, 200);
graphicsObj.DrawRectangle(myPen, myRectangle);
}
Thank you for your time, and forgive me if I said anything incorrectly; I am having a hard time even describing to google what I am looking to do--- so your help is really appreciated!!!!
Is WPF an option for you? I would recommend it based on the screenshot you provided. This desktop GUI technology is much better suited than WinForms as your code sample suggests you are using.
Learn the basic of WPF and XAML via the link I provided.
Then learn about the Canvas panel
Then I suggest you learn about Templates
Well, this should get you going. If you have any specific questions I'm sure we' ll be happy to help here at SO.
Update Example of Canvas panel in Items control: https://dannyvanderkraan.wordpress.com/2015/02/12/wpf-listbox-with-arbitrary-positioning-and-custom-shaped-items/
You may use WPF or you can search for Windows Forms themes. You can do amazing custom gui by customising windows forms. If you are to create a new project I would suggest you WPF because it is easier to implement custom guy (especially transparency)
I'm using an ScrollViewer in the MVVM enviroment to navigate around an map of europe. But when I use the ScrollViewer the deltaScale for the manipulationDeltaEventArgs.Pinchmanipulation doesn't work. The DeltaScale stays at one, no matter what. I tried to take a look at the Current and Original of the Pinchmanipulation and they are the same. So can anyone help me with making it possible to zoom while having an scrollViewer?
The manipulationDelta is:
public void Zoom(ManipulationDeltaEventArgs e)
{
if (e.PinchManipulation == null)
{
return;
}
}
I don't think scrollviewer supports zooming in Windows Phone 8. Only Windows Store apps can do this right now.
I would like to use the kinect hand cursor as 'normal' mouse cursor. In the specific I want to be able to interact with the Awesomium browser object.
The problem is that no Awesomium Browser event is raised when the kinect hand cursor is (for example) over a link, or I do a click, or any other typical mouse event.
I modified the Control Basics-WPF example program that you can find in the example directory of the Kinect SDK
I am using c# visual studio 2012, Kinect SDK 1.7, Awesomium 1.7.1.
It's been a month since this question's been asked, so perhaps you've already found your own solution.
In any case, I found myself in this scenario as well, and here was my solution:
Inside MainWindow.xaml, you'll need the Awesomium control inside a KinectRegion (from the SDK).
You'll have to somehow tell the SDK that you want a control to also handle hand events. You can do this by adding this inside MainWindow.xaml.cs on the Window_Loaded handler:
KinectRegion.AddHandPointerMoveHandler(webControl1, OnHandleHandMove);
KinectRegion.AddHandPointerLeaveHandler(webControl1, OnHandleHandLeave);
Elsewhere in MainWindow.xaml.cs, you can define the hand handler events. Incidentally, I did it like this:
private void OnHandleHandLeave(object source, HandPointerEventArgs args)
{
// This just moves the cursor to the top left corner of the screen.
// You can handle it differently, but this is just one way.
System.Drawing.Point mousePt = new System.Drawing.Point(0, 0);
System.Windows.Forms.Cursor.Position = mousePt;
}
private void OnHandleHandMove(object source, HandPointerEventArgs args)
{
// The meat of the hand handle method.
HandPointer ptr = args.HandPointer;
Point newPoint = kinectRegion.PointToScreen(ptr.GetPosition(kinectRegion));
clickIfHandIsStable(newPoint); // basically handle a click, not showing code here
changeMouseCursorPosition(newPoint); // this is where you make the hand and mouse positions the same!
}
private void changeMouseCursorPosition(Point newPoint)
{
cursorPoint = newPoint;
System.Drawing.Point mousePt = new System.Drawing.Point((int)cursorPoint.X, (int)cursorPoint.Y);
System.Windows.Forms.Cursor.Position = mousePt;
}
For me, the tricky parts were:
1. Diving into the SDK and figuring out which handlers to add. Documentation wasn't terribly helpful on this.
2. Mapping the mouse cursor to the kinect hand. As you can see, it involves dealing with System.Drawing.Point (separate from another library's Point) and System.Windows.Forms.Cursor (separate from another library's Cursor).
I have an application where the user draws some shapes.
When I click over a shape and I drag it, the CPU goes 100% because of Invalidate() inside MouseMove.
If I a use a timer and call Invalidate() from tick event the moving is not so smooth.
Is there any other approach to minimize CPU and have smooth moving?
` Point startDragMousePoint;
Point startShapeLocation;
private void Canvas_MouseMove(object sender, MouseEventArgs e)
{
if(isMouseDown)
{
Point deltaPoint = Point.Subtract(e.Location, new Size(startDragMousePoint));
shape.Location = Point.Add(startShapeLocation, new Size(deltaPoint));
Invalidate();
}
}
private void Canvas_Paint(object sender, PaintEventArgs e)
{
shape.Render(e.Graphics);
}`
There are three general solutions.
1) Don't draw while your moving, this was the solution in windows for a long time, when you dragged a window, it just disapeard and you saw the outline of a window.
2) Create a bitmap object and only move that. Note you will have to redraw the area under it.
3) Don't invalidate the hole window, just the area you are changing. Drawing to a buffer (a bitmap) can help you reuse areas.
Also, if GDI isn't the fastest drawing functions in the world. If your shape is very complex, you might want to consider using OpenGL, DirectX or SDL.
Instead of invalidating the entire area you could invalidate the portion of the control that has changed by using:
Rectangle changedArea = new Rectangle(cX, cY, cW, cH);
this.Invalidate(changedArea);
Also make sure your control is set to use DoubleBuffering
this.DoubleBuffered = true;
From the limited code that you have put up, I think the invalidate will not cause any problem. Most probably the problem may be inside the real rendering code of yours shape.Render(). In the past I have written similar application where I have called Invalidate in the mouse move and the applications has worked fine. Only there were some flickering which is gone on enabling double buffering.
I have a C# WinForms application and when I give the executable to different users the application displays in different sizes (based on their screen resolution). Some of the parts of the application can't be seen.
Is there anyway to auto-size the window based on the screen resolution, or is there another approach?
EDIT : furthermore it appears in different styles under different Operating systems, is there away to standardize its design ?
It sounds like you have specified your controls with absolute positioning and other layout defaults. In order to make a WinForms application that looks and feels the same and behaves correctly in various resizing scenarios, you need to utilize the Anchor and Dock properties. Arranging controls in WinForms can be a tiring process, but MSDN includes some nice How To's on the subject.
I would also suggest following along with this TechRepublic article, which covers the difference between Anchoring and Docking, and shows you visually what each property accomplishes:
You can use Control.ScaleControl and Control.Scale
private void MainForm_Load( object sender, EventArgs e )
{
float width_ratio = (Screen.PrimaryScreen.Bounds.Width / 1280);
float heigh_ratio = (Screen.PrimaryScreen.Bounds.Height / 800f);
SizeF scale = new SizeF(width_ratio, heigh_ratio);
this.Scale(scale);
//And for font size
foreach (Control control in this.Controls)
{
control.Font = new Font("Microsoft Sans Serif", c.Font.SizeInPoints * heigh_ratio * width_ratio);
}
}
In the case when the development platform resolution is 1280x800
According to #sixlettervariables 's answer Docking and anchoring will help of course.
Try this
private void MainForm_Load( object sender, EventArgs e )
{
this.Size = Screen.PrimaryScreen.WorkingArea.Size
}