1

I'm currently writing a project using Blazor Server (.net 7.0).

So If I have a model with multiple datetime? properties on it, I wish to create a button next to quite a number of datetime field to insert the current date and time which calls a method and updates the property with the current date and time.

Rather than creating a method for every button eg

<button @Onclick="@UpdateNowOn_DateReceived"></Button>
<button @Onclick="@UpdateNowOn_InitialContact"></Button>

        protected void UpdateNowOn_DateReceived()
        {
            Model.Details.DateReceived = DateTime.Now;
            StateHasChanged();
        }

        protected void UpdateNowOn_InitialContact()
        {
            Model.Details.InitialContact = DateTime.Now;
            StateHasChanged();
        }

I was hoping I could write a method that I could simply pass the property into an update its value. I'm very new to Blazor and C# so this is all quite new to me (learning as I go).

So I was hoping its possible to do it more like this

<button @Onclick="@UpdateNowOn(Model.Details.DateReceived)"></Button>
<button @Onclick="@UpdateNowOn(Model.Details.InitialContact)"></Button>

        protected void UpdateNowOn(DateTime property?) <-- what to pass here
        {
            Property = DateTime.Now;
            StateHasChanged();
        }

Any help is appreciated

I've tried to read and use the following but I'm not sure its what I'm after:

Pass property itself to function as parameter in C#

byevjzts
  • 11
  • 4
  • Hi Thank you for your response, I've tried that however I get an error of, "CS0206 A property or indexer may not be passed as an out or ref parameter" – byevjzts Feb 10 '23 at 14:41
  • Whilst I'm sure there's a simpler way (that's evading me right now), you could do this with reflection. Add a second parameter to the method that takes the property name (which you can pass in from the markup using `nameof`), and then use reflection to get a handle on that property. Bit messy, but would work. – Avrohom Yisroel Feb 10 '23 at 14:57
  • Hi, Thank you for your answer. Going to be honest though, this is where my lack of fundamentals may come into it, I've heard reflection thrown about before but I have no idea how to take advantage of it. I'll do some googling then on 'nameof' to see if I can find an answer but I'm currently unsure on how to build/code your answer – byevjzts Feb 10 '23 at 15:20
  • Depending on the reason you need to do this, you may be able to do: `` – thewallrus Feb 10 '23 at 15:43

2 Answers2

0

You don't need to pass a property into anything. You are thinking button not input control.

Create a component that implements the standard Blazor bind framework.

Here's an example that I think fits your requirements.

<button disabled="@_isSet" @attributes=this.AdditionalAttributes @onclick=this.OnChange>@this.Text</button>

@code {
    [Parameter] public DateTime? Value { get; set; }
    [Parameter] public EventCallback<DateTime?> ValueChanged { get; set; }
    [Parameter(CaptureUnmatchedValues = true)] public IReadOnlyDictionary<string, object>? AdditionalAttributes { get; set; }
    [Parameter, EditorRequired] public string? Text { get; set; } = "Not Set";
    [Parameter] public bool DisableIfSet { get; set; } = false;

    private bool _isSet => this.DisableIfSet && this.Value is not null;

    private async Task OnChange()
        => await this.ValueChanged.InvokeAsync(DateTime.Now);
}

And then in use:

@page "/"

<PageTitle>Index</PageTitle>


<ButtonComponent class="btn btn-primary" Text="Log Received" @bind-Value=_selectedValue1 DisableIfSet=true />

<div class="alert alert-info m-3 p-2">@(_selectedValue1.ToString() ?? "Not Set")</div>

<ButtonComponent class="btn btn-success" Text="Set Initial Contact Date" @bind-Value=_selectedValue2 />

<div class="alert alert-info m-3 p-2">@(_selectedValue2.ToString() ?? "Not Set")</div>

@code {
    private DateTime? _selectedValue1;
    private DateTime? _selectedValue2;
}
MrC aka Shaun Curtis
  • 19,075
  • 3
  • 13
  • 31
0

Thank you all for your responses. I was seriously over thinking it and placing an inline function worked in this instance as suggested by thewallrus

I simply added an onclick event to the button as follows

<button @onclick="() => {@Model.Details.DateReceived = DateTime.Now;}
byevjzts
  • 11
  • 4