Open VR-Architect opened 5 years ago
Thanks for contacting us, @VR-Architect. Given there are too many ways this can work, we tend to leave this up to the developers to do the way they want - through JS Interop. If you intended to stick to a Blazor-specific approach, you can use lambdas per element, to handle the way you want it to. We'll look into providing a sample post 3.0 release showing how this can be done.
Here is an example of the way I did it without JSInterop; however, if the mouse is moved too quickly the moved element gets left behind. If the mouse moves slowly, the drag works fine. But to my original question, I was able to get a reference by using lamba with an int.
@page "/"
<div class="container">
<div id="items-container" class="base-container" @ref="itemsContainer">
<div class="header">Items</div>
@foreach (var item in dragObjects)
{
<div class="@item.css" @onmousedown="@((e) => { mouseDown(e, item.id); })" @onmousemove="@mouseMove" @onmouseup="@mouseUp" style="@item.style;">
TODO Item @item.id
</div>
}
</div>
<div id="todos-container" class="base-container" @ref="todosContainer">
<div class="header">TODO</div>
</div>
</div>
<style>
html, body {
width: 100%;
height: 100%;
overflow: hidden;
}
.container {
width: 100%;
height: 100%;
display: flex;
flex-direction: row;
justify-content: space-around;
align-items: center;
}
.base-container {
min-width: 300px;
min-height: 400px;
//border: 1px solid rgba(15, 15, 15, 0.2);
box-shadow: 0px 0px 20px 2px rgba(15, 15, 15, 0.2);
padding: 25px;
}
.header {
width: 100%;
font-family: Oxygen, sans-serif;
font-size: 22px;
text-align: center;
}
.no-todo-container {
border: 1px solid rgba(15, 15, 15, 0.2);
box-shadow: 0px 0px 5px 10px rgba(15, 15, 15, 0.2);
}
.todo-container {
border: 1px solid rgba(15, 15, 15, 0.2);
box-shadow: 0px 0px 5px 10px rgba(15, 15, 15, 0.2);
}
.todo-item {
//border-bottom: 1px solid;
width: 250px;
height: 40px;
position: absolute;
background-color: #F44336;
color: #FFFFFF;
font-family: Oxygen, sans-serif;
font-size: 20px;
padding: 7px;
margin: 10px 0 10px 0;
box-shadow: inset 1px 1px 10px 0 rgba(15, 15, 15, 0.2);
border-radius: 3px;
cursor: pointer;
}
.moving {
background-color: #E57373;
}
.snap {
width: 301px;
height: 30px;
margin-top: 30px;
margin-bottom: 5px;
}
.over {
background-color: rgba(15, 15, 15, 0.2);
border: 2px solid #F44336;
border-radius: 5px;
}
</style>
@code{
ElementRef itemsContainer;
ElementRef todosContainer;
Vector2 mouseOffset = new Vector2 { top = 0, left = 0 };
bool isMouseDown = false;
List<DraggableObject> dragObjects { get; set; }
int selectedItemId { get; set; }
protected override void OnInit()
{
dragObjects = new List<DraggableObject>();
dragObjects.Add(new DraggableObject { id = 0, css = "todo-item", top = 150, left = 400, style = "top: 150px; left: 400px;" });
dragObjects.Add(new DraggableObject { id = 1, css = "todo-item", top = 200, left = 400, style = "top: 200px; left: 400px;" });
}
void mouseDown(UIMouseEventArgs args, int id)
{
isMouseDown = true;
selectedItemId = id;
mouseOffset.left = args.ClientX - dragObjects[selectedItemId].left;
mouseOffset.top = args.ClientY - dragObjects[selectedItemId].top;
dragObjects[selectedItemId].css += " moving";
}
void mouseMove(UIMouseEventArgs args)
{
//e.preventDefault(); ///< Stops the Default Element Bahiavor
if (isMouseDown)
{
dragObjects[selectedItemId].left = args.ClientX - mouseOffset.left;
dragObjects[selectedItemId].top = args.ClientY - mouseOffset.top;
dragObjects[selectedItemId].style = "top: " + dragObjects[selectedItemId].top + "px;left: " + dragObjects[selectedItemId].left + "px;";
}
}
void mouseUp(UIMouseEventArgs args)
{
isMouseDown = false;
if (selectedItemId > -1)
{
dragObjects[selectedItemId].css = "todo-item";
selectedItemId = -1;
}
}
public class Vector2
{
public long left { get; set; }
public long top { get; set; }
}
public class DraggableObject
{
public int id { get; set; }
public string css { get; set; }
public ElementRef el { get; set; }
public long top { get; set; }
public long left { get; set; }
public string style { get; set; }
public List<DraggableObject> children { get; set; }
}
}
Moving this to Backlog after seeing no community involvement here. We'll reconsider in the future, if we see clear need for this from community.
Hi everyone
I want to add to this issue. I am currently trying to have a list of elements where each can be clicked.
However it feels quiet overkill to add a specific event handler for each element in that list.
Another concern would be what if I update the list? Then I'd need to reapply the event handlers everytime I update it. (I am aware of display: none
)
In javascript I would apply the handler to a parent element and then get the data from e.target
. Like this I only need to use one event handler.
It would be nice if there was some sort of identification of the event target. For example a number
or string
by which I can lookup the value from a List
within c#.
Cheers Lukas
I have not been able to find any sample code to do this. Without being able to know which element was clicked, it seems impossible to use UIMouseEventArgs for moving of elements on the page. I ran into this same issue with the Drag-n-Drap events args too.
If this feature is already in the product, please provide an sample. There is something like this for keydown event in the documents, but not mouse events.
If not already in the product, this is a must have for go live please :)