In Winforms, I have implemented a custom object with a draw method, which is called by Form_Paint. I now want to be able to get the coordinates of this object after being drawn to the form, for the sake of a Move procedure in the works. I have tried using object.Location, object.Left, and object.Top, but these just give 0,0. I then tried object.Size to test, and it gave me the size of the form.
How can I get the location of my runtime object on the form? Thanks
Try using
Point objLocation= cusObject.FindForm().PointToClient(
cusObject.Parent.PointToScreen(cusObject.Location));
Related
Im using System.Drawing.Graphics graphicsObj for drawing objects on System.Windows.Forms.Panel. What is wise method to store informations about old drawings? To remove last drawing during MouseMove event?
Do i have to remember Pen settings and cords?
Thanks :)
// edit. I think my question is not clear. I have a Panel. I treat it like a container for drawing.
I can draw multiple lines, circles, rectangles.
Every time i press the mouse (MouseDown), im want to start drawing new object. When i move mouse (MouseMove), object currently drawed has to change (for example line, like in paint). When i release the mouse (MouseUp), i want object i drawed to became constant.
Now, i tried to invoke graphicsObj.Clear(); method on MouseMove event, but it clears all drawed objects.
So i deduced, that i have to store informations about old drawed objects. And now, i have to make lists (vectors or so) and store informations about that objects? Or there is a method to avoid it?
You should handle all painting in the Panel's Paint event, that is exactly what it's there for.
The Paint event gives you in its PaintEventArgs the Graphics object you should use. This will make sure your instructions are painted on every refresh, not just once.
If you are deriving from Panel, override the OnPaint method instead.
Edit after original question has been expanded:
You should separate the logic of storing the data from the logic of displaying your data. The Graphics object's purpose is to display existing data, not to store data.
I think making Lists or other collection of the objects you are drawing is the best solution.
You will also need flags to handle all the logic of what is a "live" object, etc.
I think you can store your last x,y into an array of Points objects as history.
Not sure I get what you are after here, but if you want some sort of memory about what paint drew.
Draw to a collections of bitmaps, then have your paint routine draw one of the bitmaps on to the control.
I have a window that has a menu, a toolbar at the top, and various other controls. I then have my own control that derives from ContentControl that I want to have use up all remaining space. I can't leave it to its own devices unfortunately, because the control is a Win32 control that's sort of... put inside this WPF control, and I need to use SetWindowPos.
At the moment what I am doing is using ArrangeOverride, getting the MainWindow.Content control and looking at the Height and Width. I then use Size I get in as a parameter and call the SetWindowPos function. It's written in C++/CLI, and here's the code:
Size WebView::ArrangeOverride(Size finalSize)
{
Application::Current->MainWindow->Measure(finalSize);
UIElement^ obj = dynamic_cast<UIElement^>(Application::Current->MainWindow->Content);
double objHei = obj->RenderSize.Height;
double objWid = obj->RenderSize.Width;
SetWindowPos(hWnd, NULL, objWid-finalSize.Width, objHei-finalSize.Height, finalSize.Width, finalSize.Height, NULL);
So in my head I thought this would then set the position of the control to within the remaining available space. And it does sort of work, but it seems as if the MainWindow.Content control is not being measured until afterwards? What am I doing wrong here?
edit: most of the problems seem to be when full-screening the window and then un-fullscreening it.
I have managed to fix this by using the answer to this question here
I simply put my control into a Frame, so it'd be the parent.
Then using the Point I set the window position to that, along with the size that is passed through as a parameter to the ArrangeOverride method.
I am trying to write a simple program that lets me overlay a dot on top of an image when the image is clicked. I can save the X and Y data back to my database but then I will want to be able to call that information back at a later date and overlay the dots again via code unlike the first time when the user had to click the image.
I got as far as capturing the X and Y of the click no problem but I am having trouble finding examples specifically for what I am trying to do. All of the examples online seem to be for saving the image with the added graphic but I do not need to do that as it will be the same image every time.
Once I can do this, I also need to work out a way that I can detect what area of the image has been clicked. The areas I need to mark out vary in shape and size so I need to try and work out a way to 'map' these areas and then cross reference with the co-ordinates of the users click (I assume that I may need to do some clever geometry stuff for that?)
If anyone has any suggestions of what subjects/classes/methods etc. to research for either of my queries, I would very grateful.
Thanks in advance
You can use the System.Drawing namespace to achieve this.
Create a control and override OnPaint and OnPaintBackground. Store your clicks in a List
In OnPaintBackground, draw the image using DrawImageUnscaled using the graphics object which is passed to you as a parameter.
In OnPaint, loop through your points array and call graphics.FillElipse or similar to draw a little dot.
Because this isnt a retained mode graphics system, you need to keep drawing these items so this may not suit a large number of dots. In that case, you can create an in memory bitmap and get a graphics drawing object using graphics.FromImage.
The thing is I have some graphics shown in a form, rectangle for example, and I want to capture when the point gets over thees fields. So I Thoght I try to find the corrrdinates for thees rectangles, but as thay are the coords in the form it dose not match the ones with the mouse location.
So I wonder is there a way to find what coord on the screen a Point has on the screen and not in the form or controller?
Each control hs PointToFoo methods for conversion. Note that you should call this from the parent of the object who's location you want:
Point scrPos = this.PointToScreen(panel1.Location);
Alternatively, you can get the panel's screen coordinates with:
Point scrPos = panel1.PointToScreen(new Point(0,0));
Note that the above two examples could gve different result due to the border-size of the panel.
If you are using the graphics object for the form by calling this.CreateGraphics() within the form, then the coordinates used when you draw the rectangle should be exactly the same as those returned by the click event on the form.
Do you know what coordinates your pointer is in? You can get the coordinates for your window with a call to GetWindowRect() and subtract the top/left from your mouse cursor to get client coordinates.
I seem to remember there being a function to do that for you in fact, but it's been some time since I dabbled in custom GUI controls.
In normal C# it is easy to draw to a bitmap using the Grpahics.DrawString() method. Silverlight seems to have done away with Bitmap objects and Graphics is no longer available either. So...How am I meant to manipulate/create a bitmap when using Silverlight? If it helps, I am using Silverlight 3.
Let me tell you what I am doing. I am being given a template, basically a pre-rendered image. The user is then able to select from multiple images and enter the deisred text. I then render it to the image, adjusting size etc... within bounds and centering it in the pre-defined area of the image. If I can calculate the size (as in the MeasureString method) and then draw the string (as in the Graphics.DrawString method) that would be fine. The real question, no matter why I want to be able to do this, is can it be done?
The question is: why do you want to? Why not just use a TextBlock?
If you are trying to dynamically generate an image, use standard Silverlight/WPF controls (including TextBlock) and render them to a WritableBitmap.
Edit:
Ok, you've updated and expanded, which gives me more to go on. Unfortunately, you're not going to like the answer. First, keep in mind that Silverlight and WPF in general are vector based, and intended to be used as such. Although the Canvas allows you to do pseudo-pixel manipulations, you cannot be nearly as pixel-accurate as old-school GDI. This is a factor of your medium. If you absolutely have to measure things the way you want to measure them, I suggest you build your images on a remote server and transmit them to your Silverlight app.
You can calculate the size on-screen of the text rendered via a TextBlock using the ActualWidth and ActualHeight properties. But it only works on an already rendered control. Something like MeasureString is simply not available in Silverlight. Based on your description of your app, some user interaction could accomplish what you want. The user selects the image, enters the text, and is shown a preview. The user can then adjust the width and height of the various text areas until satisfied, at which point you can take a snapshot using the render method I liked to above.
The following may work, its a bit nebulous because I haven't tried yet myself.
The object you are looking for is the WritableBitmap.
You create a Visual tree, for example create your self a Grid or Canvas (you're not adding this to the UI). Add to it the selected image and a TextBlock positioned and sized as you prefer.
Create a new WritableBitmap either of a specific size or using the selected image to initialize it.
Use the WritableBitmap Render method passing the above root Grid or Canvas to it.
Now you have a bitmap which you should able to use to do whatever its you needed to do that required all this hoop jumping in the first place.