Skip to content

UIMouseEventArgs doesn't provide reference to the element clicked #12259

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
VR-Architect opened this issue Jul 16, 2019 · 4 comments
Open

UIMouseEventArgs doesn't provide reference to the element clicked #12259

VR-Architect opened this issue Jul 16, 2019 · 4 comments
Labels
affected-few This issue impacts only small number of customers area-blazor Includes: Blazor, Razor Components enhancement This issue represents an ask for new feature or an enhancement to an existing one feature-blazor-component-model Any feature that affects the component model for Blazor (Parameters, Rendering, Lifecycle, etc) severity-major This label is used by an internal tool
Milestone

Comments

@VR-Architect
Copy link

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 :)

@mkArtakMSFT mkArtakMSFT added the area-blazor Includes: Blazor, Razor Components label Jul 17, 2019
@mkArtakMSFT
Copy link
Contributor

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.

@mkArtakMSFT mkArtakMSFT added Docs This issue tracks updating documentation PRI: 2 - Preferred labels Jul 17, 2019
@mkArtakMSFT mkArtakMSFT added this to the 3.1.0 milestone Jul 17, 2019
@VR-Architect
Copy link
Author

VR-Architect commented Jul 17, 2019

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; }
    }
}

@mkArtakMSFT mkArtakMSFT modified the milestones: 3.1.0, 3.1.0-preview1 Aug 5, 2019
@danroth27 danroth27 changed the title [Blazor] UIMouseEventArgs doesn't provide reference to the element clicked UIMouseEventArgs doesn't provide reference to the element clicked Sep 7, 2019
@danroth27 danroth27 mentioned this issue Sep 7, 2019
10 tasks
@mkArtakMSFT mkArtakMSFT added enhancement This issue represents an ask for new feature or an enhancement to an existing one and removed Docs This issue tracks updating documentation labels Sep 9, 2019
@mkArtakMSFT mkArtakMSFT modified the milestones: 5.0.0-preview1, Backlog Sep 9, 2019
@mkArtakMSFT
Copy link
Contributor

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.

@LukasWillin
Copy link

LukasWillin commented Nov 11, 2019

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

@SteveSandersonMS SteveSandersonMS added affected-few This issue impacts only small number of customers severity-major This label is used by an internal tool labels Oct 14, 2020 — with ASP.NET Core Issue Ranking
@javiercn javiercn added the feature-blazor-component-model Any feature that affects the component model for Blazor (Parameters, Rendering, Lifecycle, etc) label Apr 19, 2021
@mkArtakMSFT mkArtakMSFT modified the milestones: Backlog, BlazorPlanning Nov 5, 2023
@mkArtakMSFT mkArtakMSFT modified the milestones: Planning: WebUI, Backlog Nov 20, 2023
@dotnet dotnet deleted a comment Nov 20, 2023
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
affected-few This issue impacts only small number of customers area-blazor Includes: Blazor, Razor Components enhancement This issue represents an ask for new feature or an enhancement to an existing one feature-blazor-component-model Any feature that affects the component model for Blazor (Parameters, Rendering, Lifecycle, etc) severity-major This label is used by an internal tool
Projects
None yet
Development

No branches or pull requests

6 participants