Resolved What am I doing wrong with StateHasChanged

JohnF

New member
Joined
Jan 10, 2025
Messages
4
Programming Experience
10+
Folks:

I am gearing up for a project now in Proof of Concept stage. My specific issue is I have a component. It is simply a box. It is three deep from page so Page -> Major Component -> The Status Box in question. This is going to be a monitoring app. So - little to no user interaction. Changes come from the outside. (Like a fantasy football scoreboard.) UI change needs to occur based on events outside the application - identified by non-UI server side code.

My current task is simply to get the component to work. So I have put a button on the page component - and I kick the code from there. What I want to change is simply the css style background-color. The color is contained in a bind variable. After I change the color - I call StatusHasChanged(). The code seems to be working. I can breakpoint on the property get and observe is is executed after the button is pushed. Further - I can breakpoint on the StatusHasChanged and observe the color has indeed changed - as I expected. But the color never makes it to the UI. The background color of the box on the web client never changes.

Note - this is razor - not blazor. What I want to accomplish is very simple. I simply want the color of the box to change.

My .razor is:
HTML:
@inherits ForkStatusBoxBase


<style>
    .box {
        width: 25px;
        height: 25px;
        vertical-align: middle;
        background-color: @BackgroundColor;
        border: 2px solid black;
        padding: 5px;
        margin: 5px;
    }
</style>



<div class="box" @bind="BackgroundColor" />



My .razor.cs code behind is
C#:
public class ForkStatusBoxBase : ComponentBase
{
    string backgroundColor = "lightblue";




    public string BackgroundColor
    {
        get { return backgroundColor; }
        set { backgroundColor = value; }
    }

    public void GrantedFork()
    {

        backgroundColor = "green";
        StateHasChanged();

    }

}
Any help would be appreciated.
 
Last edited by a moderator:
I guess I'm learning something new. I didn't know that changing a backend value in Razor would cause the web client to re-download and re-render the web page. I always thought that was a Blazor thing rather than a Razor thing.

Have you watched the network traffic to see if the web browser gets an update from the server? Does the updated HTML have the new values?
 
I guess I'm learning something new. I didn't know that changing a backend value in Razor would cause the web client to re-download and re-render the web page. I always thought that was a Blazor thing rather than a Razor thing.

Have you watched the network traffic to see if the web browser gets an update from the server? Does the updated HTML have the new values?

Hi Skydiver:
I'm the one learning something new here. I have experience in WinFroms development. I'm trying to add to that skill set. I have come to understand that Razor and Blazor are practically synonymous. I'm focusing just on Razor following the principle - you learn c# before .Net. :)

I did look at network traffic. Nothing flows to the browser. To be clear I am calling Microsoft.AspNetCore.Components.ComponentBase.StateHasChanged. My expectation is only the component will be rerendered - not the entire page.
 
Hi Skydiver:
I'm the one learning something new here. I have experience in WinFroms development. I'm trying to add to that skill set. I have come to understand that Razor and Blazor are practically synonymous. I'm focusing just on Razor following the principle - you learn c# before .Net. :)

I did look at network traffic. Nothing flows to the browser. To be clear I am calling Microsoft.AspNetCore.Components.ComponentBase.StateHasChanged. My expectation is only the component will be rerendered - not the entire page.

One more observation. I put a Break Point on StateHasChanged in my .razor.cs file. On the break - I then F7. I find myself in the .razor file and the style has changed - the color has been updated as I expected. But the box (<div>) is not picking up the change in style and rerendering.
 
When I learned to use Razor, it was still in the early beta stages. It was MVC with Razor at that time. For any updates on the web browser to happen, there had to be some manually written JavaScript that would do an AJAX call back to the server and have it serve up some partial content -- basically something like what the WebForms Update panel does. I don't know what the current state of the art is for Razor.

As for your debugging steps, recall that the debugger does a dynamic request for the data when inspect values or use the immediate window. I think that you also need the web browser to request that same updated data.
 
Last edited:
The problem with this was the "Bind" statement in the razor file. Typical "newbe" trying to learn something, you pick something up, install it, test it, it does not work, then you leave it behind. I appreciate skydivers suggestion of looking at browser traffic. I have added that to my bag of tricks. Also, I see a very minimal network flow when I want to change the style.

The below works. What I like about it is it is the minimal - as simple as I can get it - solution. Many examples I came upon address very grandiose goals. I have always been a fan of Proof of Concept coding before a project. Get a skeleton that works, then flesh it out with business rules, error checking etc. That's worked for me!

Anyway - a minimal example of changing an attribute of style (it changes the background of a box) is:

.razor
HTML:
@inherits ForkStatusBoxBase


<style>
    .box {
        width: 25px;
        height: 25px;
        vertical-align: middle;
        background-color: @BackgroundColor;
        border: 2px solid black;
        padding: 5px;
        margin: 5px;
    }
</style>


<div class="box" style="background-color: @BackgroundColor" />




.razor.cs - the code behind
C#:
using System;
using System.Threading.Tasks;
using Microsoft.AspNetCore.Components;


namespace xxxxxxxxxxxxxxxxx;


public class ForkStatusBoxBase  : ComponentBase
{
    string backgroundColor = "lightblue";


    public string BackgroundColor
    {
        get { return backgroundColor; }
        set { backgroundColor = value; }
    }

    public void GrantedFork()
    {

        backgroundColor = "green";
        StateHasChanged();

    }
}
 
Last edited by a moderator:
Ah, I see. So somehow a re-render happens when the style attribute is updated with the new value.
 
Back
Top Bottom