I'm using adorner to draw line on canvas which works but the issue I'm facing is that it is not clickable so I have to keep clicking ten times to select it using mouse.
Is there any property setting that I have missed here?
thanks.
amit
If you use the pixels (default hittest) to determine whether or not the user clicked a line, the user has to click the line exactly. When a line is very thin this is very hard.
Another way of handling this is by calculation. When the users clicks calculate the distance between the mouse location and the lines and select the line that is closest.
You could even make an ordered list of the lines that are within a specified radius and select the next line from this list when the user clicks again.
Related
I am placing a line (lets call it line 1) on a canvas and attaching a mouse enter, mouse leave, mouse up and mouse down event to it. Another line (line 2) is then created with the same events attached. All events work perfectly when any of the lines are selected.
For some reason when the first line that was created is dragged and released over the second line created the line does not get released on the canvas, however it remains glued to the mouse pointer until another click is made away from the second line. This problem occurs when the earliest lines created are dragged over the newer lines and not vice versa ( problem occurs when line 1 is dragged and released on line 2 but not vice versa, or line 1 over 2 and 3, and line 2 over line 3 etc.
I do not know what code might help regarding the solving of this issue, would anyone have any suggestions or maybe have encountered a similar problem?
The reason for the observed behavior is quite easily deduced:
All elements in a Panel do have an implicit z-order that will take effect when no ZIndex property is specified for en element. Earlier added elements have a lower z-order than later added elements (xaml markup is parse from top to bottom and elements that occur earlier are added earlier).
Now if you start moving elements around and two elements overlap the z-order is still effective. so your earlier added line will be treated as if it is physically beneath the other line, and all mouse events will go to the top-most line in the z-order. therefore the MouseUp event is not received by your moved element and it is still glued to the mouse pointer until you move your mouse away from the overlapping area and release the mouse again.
I can think of several ways to solve it:
Probably the easiest thing will be to just set an explicit ZIndex on the element as soon as you select it, when you move it around it will always be on top of all other elements, and when you release it anywhere you can clear the ZIndex again. Some example code to give you an idea:
private void OnElementSelected()
{
// todo: maybe we need to store the previous zindex value and re-assign it later
// to prevent it from getting lost
Canvas.SetZIndex(this, Int32.MaxValue);
}
private void OnElementReleased()
{
this.ClearValue(Canvas.ZIndexProperty);
// todo: maybe re-assign stored z-index value
}
An alternative solution would be to have a transparent MouseEventObserver placed over your whole Canvas that gets activated as soon as you select an element, then the order of your elements doesn't matter.
Edit
A nice fact (many devs probably are unaware of) about the Canvas.ZIndex attached property: it works for every panel type, not only for Canvas. So you can even specify the z-order of elements inside a Grid with Canvas.ZIndex.
This question already exists:
Closed 10 years ago.
Possible Duplicate:
Click and drag image to image grid?
I have a few image boxes in my form and I was wondering how can I would place a grid across the form that have a bunch of lines so the whole grid is a bunch of 64 x 64 squares. I need it so I can select an image and place it onto a specific square using the mouse and be able to go through the whole grid and check for example how many of one specific image is on the grid. To give you a better idea of what I'm doing is that I have a few image boxs which contain different 64 x 64 images. There is another image box that shows the image I clicked on last, which is like a brush because whenever you left click a box in the grid it pastes it into that specific box in the grid. I also need it so I can right click the box and delete the image in the box the mouse is over. Finally I need to be able to read all the images in the box and output it into a file that I can later open. I'm using it to create land in a game, which the program will output the needed texture and and where ground level is for the boxs which make up the whole terrain. What I need to know is what kind of thing should I do to be able to do this? I've been trying the past few hours on how I make the boxs and how to know where the mouse is and stuff and I'm completely stuck. A simple idea would be helpful. I actually don't know what control(s) I should use for this so an idea that doesn't involve any grid controls is still very helpful.
I don't know if it's the best possible idea, but you could use FlowLayoutPanel with WrapContent set to true and FlowDirection = LeftToRight. I dont know about Drag&Drop operation though (never done it with FlowLayoutPanel, buth there are some nice tutorials out there).
You can track your mouse position using mouse events. If you don't want to do that:
You can get absolute position at any time using:
Point currentPos = System.Windows.Forms.Cursor.Position;
Then, to get relative position on your (current) control:
Point relativeLoc = this.PointToClient(currentPos)
... and then, to get control over which your mouse is on FlowLaoutPanel:
Control c = flowLayoutPanel1.GetChildAtPoint(relativeLoc);
In Winform, i have a ComboBox at the bottom of the form.
when i run the application, ComboBox draws dropdown list in downward direction which goes out of the form borders.
how can i make ComboBox Dropdown list to draw in Upward direction ?
Thanks in advance.
It's not immediate but you can do it, I'll just outline the steps you need:
Attach an event handler to ComboBox.DropDown.
Convert the Left/Bottom location of the ComboBox to screen cordinates and add them an offset (+1 for example to both values).
Use use WindowFromPoint() to get the handle of the dropped down window (it's below the control, that's why +1).
Get the bounds of the dropped window (you can use CB_GETDROPPEDCONTROLRECT or GetWindowRect(), as you prefer).
Move the window to the new location (ComboBox top - dropped down window height) using MoveWindow().
That's all
EDIT
Note that you may merge point 2 and 4, with a single SendMessage with CB_GETDROPPEDCONTROLRECT you can get the bounds of that window and the location to use as parameter for WindowFromPoint(). In this way you do not assert that the dropped down window is always downward (it's not sure when the window touches the screen bounds and it may even change in future versions).
I'm planning to create a number-line control similar to the image below (only one of them):
I'm creating a program where the children can detect where's the position's number. I mean, instruct them to write the number 4 (and the boy writes a vertical line).
The idea is when the cursor is on the control, it shows a vertical line. And when the user presses OK, returns with an event the X position and hold it the line.
Do you know if there's a similar control on the web?
Just use a Slider with a new template.
How to Create/Apply a Slider Template
When my mouse moves to the bottom of Combobox popup list, the list automaticly start to scroll down. But when I'm the bottom and goes to the top, there is no autoscrolling effect so I want to disable this behaviour, couse it only work in one way, down..
I cannot find any property, so I try to get mousemove event on that dropdown-list to cancel it, or make it handled, but it is triggered only on combobox itself, not on the list.
I also try to create something on top of that list, such as invisible panel which gets mouse move events instead of that dropdown-list, but I cannot find anything useful, couse that list is always at the top of everything.
Another idea was to find an event which is executed when items which are shown in popup list are changed and stop it when the mouse didn't grab the scrollbar, or click it, but this is also immposible. No events triggered. there is only selectedchanged event, but this is trigger on select not on the scrool.
Is there any solution to do this?
Finally I found the answer!!!
I had about 26 lines in my Combobox List, that was liitle to big so I wanted to show only 7 of them per time.
I found DropDownHeight property, and set it: Property ItemHeight was set to 13, couse the Font.Size was 8,25 (default). 7*13 = 91. And set it.
.
And it works almost perfectly, but there was a problem with autoscrooling. (which I asked above)
Finally I realised that last line (here is NNN) is not fully shown. And when mouse Enters this line, the ComboBox Control want to show me whole line and scrolls it UP.
I started to change size and find out, that the line is being shown totally when it is set to 93 (= 7*13 + 2). Why 2? Probably because a bottom and top border. And now there is no autoscrolling...
I also find, that another possibility is to set:
ComboBox1.IntegralHeight = False;
ComboBox1.MaxDropDownItems = 7;
And this works only when there was no changes in DropDownHeight, default value in my case was 106 ( = 8*13 + 2) couse the default value of MaxDropDownItems is 8.