How to Make a Button Do Another Action When Pressed Again Vbnet

It's straightforward to wire upwardly event handlers to HTML events like onClick in your Blazor components, just how tin y'all pass additional information and unlike types of arguments?

Let'south say you desire to perform an activity when a button is clicked in Blazor.

This is straightforward to do using Blazor's event handling syntax.

Y'all can wire upwardly a method to an HTML chemical element event and Blazor will invoke that method every bit an upshot handler for said result.

          @page "/sayHello"                                          <button              @onclick                              =                "GreetMe"                            >            Click me!                              </button              >                        @Message  @lawmaking {       string Message { get; set; }      void GreetMe()     {         Message = "Hullo";     }     }                  

Blazor volition invoke GreetMe when the button is clicked, and the user will come across a friendly (if somewhat unimaginative) greeting.

Your onclick event handler can optionally take a MouseEventArgs parameter which Blazor volition automatically include when information technology invokes the handler.

          @code            {            string            Message            {            get            ;            prepare            ;            }            void            GreetMe            (MouseEventArgs args)            {            if            (args.AltKey)            Message            =            "Greetings"            ;            else            Message            =            "Hullo"            ;            }            }                  

Now we can easily access extra details near the button click, for instance whether the user held downward the ALT key when they clicked, in this case displaying a different greeting if and so.

Different events will include different types of issue args—bank check out official docs for a complete list.

Passing Additional Information to your Event Handlers

Then far and so good, but what if y'all need to pass boosted data to your upshot handlers?

For instance, you might need to loop through a collection and render buttons for each item.

          @page "/todoList" @using System.Diagnostics  @foreach (var todo in Todos) {                                          <p              >            @todo.Text                              </p              >                        <!-- delete button goes here -->            }  @lawmaking {     Listing                              <Todo              >                        Todos { go; prepare; } = new List                              <Todo              >                        {         new Todo {Id = 1, Text = "Exercise this"},         new Todo {Id = 2, Text = "And this"}     };      void Delete(Todo todo)     {         Debug.WriteLine($"Deleting {todo.Id}");     }      private class Todo     {         public int Id { go; set; }         public string Text { get; set; }     } }                  

This instance iterates over a list of Todos and shows text for each one.

Just what if nosotros desire to delete a Todo? We need a style to bespeak which Todo should be removed when we click a button for that specific Todo.

The standard way of calling an EventHandler won't work because we can't pass boosted arguments.

                                                    <button              @onclick                              =                "Delete"                            >            10                              </push              >                              

Delete would have no idea which Todo to delete!

The answer is to utilize a lambda which will so consul to our Event Handler.

          @foreach (var todo in Todos) {                                          <p              >            @todo.Text                              </p              >                                                      <button              @onclick                              =                "() => Delete(todo)"                            >            X                              </button              >                        }                  

We've told Blazor to invoke an anonymous expression (represented here using the lambda syntax) which in turn calls Delete, passing the electric current Todo instance along for the ride.

Our Delete method will receive the relevant instance of Todo and can have whatever activity it deems necessary.

                      void            Delete            (Todo todo)            {            Debug.            WriteLine            ($"Deleting {todo.Id}"            )            ;            // hit the database and delete the todo            }                  

What if You Need the Original EventArgs besides?

What if you need both the original event args (such equally MouseEventArgs) and your own arguments (such as which Todo to delete).

For this, you can reference the original consequence args in your lambda and forward them forth.

                                                    <button              @onclick                              =                "args => Delete(todo, args)"                            >            10                              </button              >                              

This finer frontward the arguments from the original event to your event handler, where you can do with them as you please.

                      void            Delete            (Todo todo,            MouseEventArgs args)            {            Debug.            WriteLine            ($"Alt Key pressed: {args.AltKey} whilst deleting {todo.Id}"            )            ;            }                  

Gotcha—Loops and Lambdas

Using lambdas inside forEach loops in your Blazor components volition more often than not work every bit you lot'd expect, but watch out if you decide to use a regular for loop with a loop variable instead.

          @page "/loops" @using Organization.Diagnostics  @for (int i = 0; i < five; i++) {                                          <button              @onclick                              =                "()=>Log(i)"                            >            @i                              </button              >                        }  @code {     void Log(int i)     {         Debug.WriteLine($"Logging: {i}");     } }                  

In this example we're merely looping from 0 to 5 and rendering a push button each time.

When you lot click the push you'll see the value of the loop variable i logged out in the debug console (in your IDE when you debug your app).

Now, interruption for a moment and consider what yous'd look to see when you run this code and click whatever of the buttons…

You'd exist forgiven for expecting to run into different numbers when you click different buttons.

Merely in reality you'll see…

Console output showing results of using loop variable directly

…a whole load of 5s!

Whichever button y'all click, the debug output tells you i is always 5.

Foreign huh?!

This isn't a Blazor affair, only really the way bearding expressions and loops work in C#.

If y'all simply want to solve this and move on with your day, capturing i in a local variable inside the loop will do the trick.

          @page "/loops" @using System.Diagnostics  @for (int i = 0; i < 5; i++) {     var j = i;                                          <push              @onclick                              =                "()=>Log(j)"                            >            @i                              </button              >                        }  @code {     void Log(int i)     {         Debug.WriteLine($"Logging: {i}");     } }                  

Here we capture the value of i in j, then employ j in our lambda expression.

To empathise why this happens requires a detour into the secret world of your C# compiler!

Understanding C# Loops and Lambdas

Here's a pseudo-code representation of the compiled C# code that volition be executed for our Blazor component. Typically nosotros don't demand to pay much attending to this, but in this example it'due south useful to see what's actually going on "under the hood".

                      [            Route            (            "/loops"            )            ]            public            class            Loops            :            ComponentBase            {            void            BuildRenderTree            (RenderTreeBuilder _builder)            {            Loops.DisplayClass displayClass            =            new            Loops.DisplayClass            (            )            ;            displayClass.            this            =            this            ;            for            (displayClass.i            =            0            ;            displayClass.i            <            5            ;            displayClass.i++            )            {            _builder.            openElement            (            'button'            )            ;            _builder.            AddAttribute<MouseEventArgs>                        (            "onclick"            ,            new            Action            (displayClass.handle)            )            ;            _builder.            closeElement            (            'button'            )            ;            }            }            private            void            Log            (            int            i)            {            Debug.            WriteLine            (            string            .            Format            (            "Logging: {0}"            ,            (            object            )            i)            )            ;            }            [CompilerGenerated]            private            sealed            course            DisplayClass            {            public            int            i;            public            Loops            this            ;            internal            void            handle            (            )            {            this            .            Log            (i)            ;            }            }            }                  

I've removed some particular and simplified the bodily lawmaking to keep this readable, but the gist is as follows.

The compiler generates a BuildRenderTree method for your component.

When this component is rendered, this method creates a single instance of something chosen DisplayClass.

Notation how BuildRenderTree just creates i case of this form (outside the loop), then references this single instance inside the loop.

Every time it goes round the loop, information technology will add a push to the RenderTreeBuilder and add together an onclick aspect for this button pointing to an Action.

Crucially, each action points to the same single instance of DisplayClass.

DisplayClass.i is and then incremented and we go around the loop again.

Past the time nosotros've been effectually the loop 5 times, the final number stored in i in the brandish class will be 5.

At present, when you run the app and click any of the buttons, all the deportment are pointing to the single instance of DisplayClass containing the value i (5 in this example).

So it'southward not surprising you see a lot of 5s for every push button click!

The pull a fast one on to overcome this is to capture the value of i into a local variable inside the for loop.

          @page "/loops" @using Arrangement.Diagnostics  @for (int i = 0; i < five; i++) {     var j = i;                                          <push              @onclick                              =                "()=>Log(j)"                            >            @i                              </button              >                        }                  

In the resulting compiled code, a new instance of DisplayClass will now be created every time round the loop.

                      void            BuildRenderTree            (RenderTreeBuilder _builder)            {            for            (            int            index            =            0            ;            alphabetize            <            5            ;            ++index)            {            Loops.DisplayClass displayClass            =            new            Loops.DisplayClass            (            )            ;            displayClass.            this            =            this            ;            displayClass.j            =            alphabetize;            _builder.            openElement            (            'button'            )            ;            _builder.            AddAttribute<MouseEventArgs>                        (            "onclick"            ,            new            Action            (displayClass.handle)            )            ;            _builder.            closeElement            (            'push'            )            ;            }            }            [CompilerGenerated]            individual            sealed            class            DisplayClass            {            public            int            j;            public            Loops            this            ;            internal            void            handle            (            )            {            this            .            Log            (j)            ;            }            }                  

This avoids the shared i value problem, and clicking the buttons works as yous would expect.

In Summary

Blazor enables you to handle HTML events such every bit onClick events via event handlers.

Yous can use lambdas to capture values (for case in a loop) and pass them on to your result handlers.

Dissimilar events pass different types of event args and then bank check out the official docs for details.

Scout out for those pesky for loops; if you employ the loop variable without capturing it to a local variable inside the loop yous'll fall foul of the C# compiler and see behavior you probably don't want or expect!

hardwickprehopecon.blogspot.com

Source: https://www.telerik.com/blogs/how-to-pass-arguments-to-your-onclick-functions-blazor

0 Response to "How to Make a Button Do Another Action When Pressed Again Vbnet"

Postar um comentário

Iklan Atas Artikel

Iklan Tengah Artikel 1

Iklan Tengah Artikel 2

Iklan Bawah Artikel