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.
Related
My UWP application contains a map with several POI. I am trying to change the mouse cursor from an arrow to a hand when hovering over specific poi to indicate its clickable.
This would change the cursor as soon as it enters the map still, as a simple test, I added a PointerEntered event for the mapcontrol and within it I have the following to change the cursor:
Window.Current.CoreWindow.PointerCursor = new Windows.UI.Core.CoreCursor(Windows.UI.Core.CoreCursorType.Hand, 0);
It appears though the cursor does change however immediately gets overridden back to the pointer cursor.
Edit: Just realised When a poi is clicked (i.e. is selected) the cursor changes to a hand even when not over the map control until the poi is unselected. No good as I would like the cursor to change dynamically when hovering over a poi and revert back to cursor when moved away.
Change pointer cursor when hovering over map elements
I'm afraid you can't edit the default cursor for map element, Because it has handled internally, it will not fired, even you has listen PointerEntered event, it consumed by the control and not passed up the control chain. If you do want this feature, the better way is post this feature with windows feed backhub app.
I don't know if it works just like WinForms, I had to do something like this to click on labels (couldn't use link-labels), what I used was in the Mouse_Move event of the label and it was basically
if (Cursor.Current == Cursors.Default)
{
Cursor.Current = Cursors.Hand;
}
and similar changes and behaviors due to the various conditions. This however got me a small issue: this statement changes the mouse graphic anytime you move on the control, but personally on Windows settings I use the trail graphic function for the mouse (leaving a trail of pointers whenever I move the mouse on the screen), what I suggested you disables this function, or better, it conceals it, since it "recreates" the mouse graphic for every move you do onto the control, and thus it "undoes" the graphic for the mouse and recreates it as a Hand (in my instance). If it doesn't concern you though, it works just fine.
Just I repeat myself: I use this on WinForms, but since it's C# I suppose it just will work(?)
There is a problem i created a button and text which is display correct on android resolution but when i change the resolution to free aspect it change the position of button and text like this
I tick the button component Image (Script) preserve aspect and changing the anchors of both object like this
but nothing happen i want to display these two on same position where it is when changing any resolution.
First of all, do not use Free Aspect to test different resolutions. Free aspect isn't really a resolution and often you can see bugs that you will not ever see on real devices.
For your problem anyway you have what's called Anchors in each UI element. An anchor defines where you want to "attach" your UI element and especially to what element or corner of the screen you want to attach it. For your example, on the Rect Transform, click on the square drawing (representing the anchors) and choose Bottom Left.
Your element will be moved, you can move it where you want to and it will always be attached to the bottom left corner of your screen:
If you want to know more about UI for multiple resolutions, you can go here: http://docs.unity3d.com/Manual/HOWTO-UIMultiResolution.html
Good luck!
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.
I try to explain my problem:
I got many customcontrols of same type on a panel.
At runtime I'm free to move any custumcontrol ( mousedown and mousemove events) in the form with mouse over any others customcontrols using bringtofront() to have it over all.
Now I need to know when the control I'm moving is over any other control and which control is under.
So far I've tryed to use drag-n-drop events but without success, there's some other way to do this or I've to re elaborate it with drag events?
thank you all for help
and sorry for my English.
EDIT:
The controls are cards game and my final goal is to use cards to create logical sequence following rules based on card value and/or color.
You can't solve the problem with drag-and-drop because you're not actually dropping one control onto the other control. You're merely moving them around in the form.
You need to become familiar with Z order, which is the front-to-back arrangement of objects in a virtual 3D space. To adjust the Z order, you can call the BringToFront and SendToBack methods of any object that derives from System.Windows.Forms.Control.
The Z order is also exposed by the parent (container) control's Controls collection. Using the GetChildIndex method, you can determine the position of any control within the Z order.
So now, all you need to do is figure out which control the control you're dragging is over. Do that by comparing the Location properties of the two controls. When you know that the locations of two controls overlap, check their respective Z order indices to see which one is on top.
There are certainly some advantages in having a selection rectangle highlighting the currently selected element which also has the focus. However an element with padding can cause the rectangle to be drawn on a totally unwanted position and therefore is hindering and not helpful. So without further ado my question is: Is there a way to hide this rectangle OR adjust its position?
Switching over to ownerdrawing the whole element should be only the last resort
Setting the "TabStop" property to false is not working
In the objects onfocus event, set focus to the next item in the tab stop?
That will keep the control from ever getting focus, which will prevent the "system carat" from showing.