Binding values using @bind-XXX binding syntax does not work if nested.

Steps to reproduce the behavior:
@bind-Value syntax in the Shared folderEditForm in the Index.razor page and a model to bind toInputText component, bind using @bind-Value to one model property@bind-ValueExpected the binding to work with nested controls, so both properties of the model are updated when the input control is changed.
A direct binding with InputText works but the custom control binding does not bind to the model. It binds when initially created but updates to the control do not get passed back the to page model.
Example repo created at https://github.com/conficient/BlazorBug04
MyControl.razor
<div class="form-control">
<label>@Label</label>
<InputText @bind-Value="@Value" />
</div>
@code {
// binding parameters
[Parameter] public string Value { get; private set; }
[Parameter] public EventCallback<string> ValueChanged { get; private set; }
[Parameter] public string Label { get; private set; }
}
Index.razor
@page "/"
<h1>Hello, world!</h1>
Welcome to your new app.
<EditForm Model="@model">
A: <InputText @bind-Value="@model.A" /><br />
<MyControl @bind-Value="@model.B" Label="B" />
</EditForm>
<b>Binding check:</b>
<p>A = @model.A</p>
<p>B = @model.B</p>
@code
{
/// <summary>
/// Data class
/// </summary>
public class Model
{
public string A { get; set; }
public string B { get; set; }
}
private Model model = new Model()
{
A = "initial A",
B = "intial B"
};
}
Previously reported on Blazor repo: #1490
Also reported in aspnetcore repo: #5504
Related: #6351 was supposed to fix?
__Include the output of dotnet --info__
.NET Core SDK (reflecting any global.json):
Version: 3.0.100-preview6-012264
Commit: be3f0c1a03
Runtime Environment:
OS Name: Windows
OS Version: 10.0.17763
OS Platform: Windows
RID: win10-x64
Base Path: C:\Program Files\dotnet\sdk\3.0.100-preview6-012264\
Host (useful for support):
Version: 3.0.0-preview6-27804-01
Commit: fdf81c6faf
.NET Core SDKs installed:
2.1.202 [C:\Program Files\dotnet\sdk]
2.1.401 [C:\Program Files\dotnet\sdk]
2.1.505 [C:\Program Files\dotnet\sdk]
2.1.604 [C:\Program Files\dotnet\sdk]
2.1.700-preview-009618 [C:\Program Files\dotnet\sdk]
2.1.700 [C:\Program Files\dotnet\sdk]
2.1.800-preview-009677 [C:\Program Files\dotnet\sdk]
2.1.800-preview-009696 [C:\Program Files\dotnet\sdk]
2.2.103 [C:\Program Files\dotnet\sdk]
3.0.100-preview6-012264 [C:\Program Files\dotnet\sdk]
.NET Core runtimes installed:
Microsoft.AspNetCore.All 2.1.0 [C:\Program Files\dotnet\shared\Microsoft.AspNetCore.All]
Microsoft.AspNetCore.All 2.1.1 [C:\Program Files\dotnet\shared\Microsoft.AspNetCore.All]
Microsoft.AspNetCore.All 2.1.2 [C:\Program Files\dotnet\shared\Microsoft.AspNetCore.All]
Microsoft.AspNetCore.All 2.1.9 [C:\Program Files\dotnet\shared\Microsoft.AspNetCore.All]
Microsoft.AspNetCore.All 2.1.11 [C:\Program Files\dotnet\shared\Microsoft.AspNetCore.All]
Microsoft.AspNetCore.All 2.2.1 [C:\Program Files\dotnet\shared\Microsoft.AspNetCore.All]
Microsoft.AspNetCore.App 2.1.0 [C:\Program Files\dotnet\shared\Microsoft.AspNetCore.App]
Microsoft.AspNetCore.App 2.1.1 [C:\Program Files\dotnet\shared\Microsoft.AspNetCore.App]
Microsoft.AspNetCore.App 2.1.2 [C:\Program Files\dotnet\shared\Microsoft.AspNetCore.App]
Microsoft.AspNetCore.App 2.1.9 [C:\Program Files\dotnet\shared\Microsoft.AspNetCore.App]
Microsoft.AspNetCore.App 2.1.11 [C:\Program Files\dotnet\shared\Microsoft.AspNetCore.App]
Microsoft.AspNetCore.App 2.2.1 [C:\Program Files\dotnet\shared\Microsoft.AspNetCore.App]
Microsoft.AspNetCore.App 3.0.0-preview6.19307.2 [C:\Program Files\dotnet\shared\Microsoft.AspNetCore.App]
Microsoft.NETCore.App 2.0.9 [C:\Program Files\dotnet\shared\Microsoft.NETCore.App]
Microsoft.NETCore.App 2.1.9 [C:\Program Files\dotnet\shared\Microsoft.NETCore.App]
Microsoft.NETCore.App 2.1.11 [C:\Program Files\dotnet\shared\Microsoft.NETCore.App]
Microsoft.NETCore.App 2.2.1 [C:\Program Files\dotnet\shared\Microsoft.NETCore.App]
Microsoft.NETCore.App 3.0.0-preview6-27804-01 [C:\Program Files\dotnet\shared\Microsoft.NETCore.App]
Microsoft.WindowsDesktop.App 3.0.0-preview6-27804-01 [C:\Program Files\dotnet\shared\Microsoft.WindowsDesktop.App]
To install additional .NET Core runtimes or SDKs:
https://aka.ms/dotnet-download
Thanks for contacting us, @conficient .
You can write it this way, and the changes would propagate.
<InputText Value="@Value" ValueChanged="@ValueChanged" />
Alternatively, you can simply subclass from the InputText component.
I tried the approach you suggested but this results in a WASM error:
WASM: System.InvalidOperationException: Microsoft.AspNetCore.Components.Forms.InputText requires a value for the 'ValueExpression' parameter. Normally this is provided automatically when using 'bind-Value'
I think this is because the ValueChanged event handler isn't set?
I resolved my issue anyway once I realised (thanks to @joshlang ) that I needed to invoke the ValueChanged from the Value property setter.
I will push the updated version on this code to my repo. This issue can remain closed though.
If your goal is to wrap up an InputText in some bootstrap styling, I would suggest subclassing. The form types are designed for this use case.
If you're really determined to compose, then accept an Expression<Func<string>> ValueExpression as a parameter as well and pass that through also.
Thanks @rynowak - yes I wanted to get rid of boilerplate <div class="form-group"><label>.... around each input control so my forms are simpler. I'll try what you suggest.
I started to see the following error after upgrading from preview5 to preview6
WASM: System.InvalidOperationException: Microsoft.AspNetCore.Components.Forms.InputText requires a value for the 'ValueExpression' parameter. Normally this is provided automatically when using 'bind-Value'
this is my custom component
_the razor file_
@inherits CcInputTextComponent
@using Microsoft.AspNetCore.Components
<input type="@Type"
class="@CssClass"
id="@Id"
value="@BindMethods.GetValue(CurrentValue)"
onchange="@BindMethods.SetValueHandler(__value => CurrentValue = __value, CurrentValue)"
placeholder="@PlaceHolder"
/>
_the "code behind" - I prefer not to use the @ code{} I like the idea of having the csharp completely separated from the razor_
using Microsoft.AspNetCore.Components;
using Microsoft.AspNetCore.Components.Forms;
using Microsoft.AspNetCore.Components.RenderTree;
namespace BzTest.Shared.CcInputText
{
public class CcInputTextComponent: InputText
{
[Parameter] public string Type { get; set; } = "text";
[Parameter] public string PlaceHolder { get; set; }
}
}
_the use of the component_
<CcInputText id="Password" Type="password" bind-Value="@loginRequest.Password" Class="form-control input_pass" PlaceHolder="Password"></CcInputText>
use @bind-Value instead of bind-Value. See the preview6 upgrade notes for more details
Yep, that seems to work. I get a red squiggle but might be Resharper's fault.

I don't know looks weird, not the squiggle, the syntax. The @ before the attribute name, I don't know it's different from the rest of the Razor syntax, maybe just have to get used to.
For those that end up here like me, it appears as though "@bind-Value" became case sensitive at some point.
Yes it did. Which now allows us to create components like