3

I've build a class which has a dynamic list of properties (such as color, size, weight etc etc), the contents of this aren't known at compile time so I used a ExpandoObject

Where I'm struggling is to get Blazor to bind to the value properties of the object for example

@foreach (var option in (IDictionary<string, object>)selectedProduct.Properties)
{
    <div class="col-sm">
        <input type="text" placeholder="@option.Key" @bind="option.Value"/>
    </div>
}

However when this is compiled the autogen code results in an error :- 'KeyValuePair<string, object>.Value' cannot be assigned to

Has anyone had any success binding to a ExpandoObject (and children properties?)

John Mitchell
  • 9,653
  • 9
  • 57
  • 91

2 Answers2

4

This is not directly related to the ExpandoObject.

When you iterate over a Dictionary you get back immutable KeyValuePair items.

You get an error because @bind="option.Value" compiles to code that wants to assign to option.Value.

And as tuples and anonymous types are all immutable I think you will have to write a <Label, Value> class for this.

H H
  • 263,252
  • 30
  • 330
  • 514
  • 2
    Derp! Apparently I just need some coffee and aren't thinking straight. Thanks for point that out, I managed to fix it with `@onchange="@((ChangeEventArgs __e) => ((IDictionary)selectedProduct.Properties)[option.Key] = (object)__e.Value.ToString())"` – John Mitchell Jun 22 '20 at 06:59
0

Thanks to Henk's answer I was able to modify my code to support the ExpandoObject

@foreach (var option in (IDictionary<string, object>)selectedProduct.Properties)
{
    <div class="col-sm">
        <input type="text" placeholder="@option.Key" @onchange="@((ChangeEventArgs __e) => ((IDictionary<string, object>)selectedProduct.Properties)[option.Key] = (object)__e.Value.ToString())"/>
    </div>
}

Its uglier to look at but does the job

John Mitchell
  • 9,653
  • 9
  • 57
  • 91