@@ -16,7 +16,8 @@ public class EditForm : ComponentBase
1616 {
1717 private readonly Func < Task > _handleSubmitDelegate ; // Cache to avoid per-render allocations
1818
19- private EditContext ? _fixedEditContext ;
19+ private EditContext ? _editContext ;
20+ private bool _hasSetEditContextExplicitly ;
2021
2122 /// <summary>
2223 /// Constructs an instance of <see cref="EditForm"/>.
@@ -36,7 +37,16 @@ public EditForm()
3637 /// also supply <see cref="Model"/>, since the model value will be taken
3738 /// from the <see cref="EditContext.Model"/> property.
3839 /// </summary>
39- [ Parameter ] public EditContext ? EditContext { get ; set ; }
40+ [ Parameter ]
41+ public EditContext ? EditContext
42+ {
43+ get => _editContext ;
44+ set
45+ {
46+ _editContext = value ;
47+ _hasSetEditContextExplicitly = value != null ;
48+ }
49+ }
4050
4151 /// <summary>
4252 /// Specifies the top-level model object for the form. An edit context will
@@ -73,11 +83,16 @@ public EditForm()
7383 /// <inheritdoc />
7484 protected override void OnParametersSet ( )
7585 {
76- if ( ( EditContext == null ) == ( Model == null ) )
86+ if ( _hasSetEditContextExplicitly && Model != null )
7787 {
7888 throw new InvalidOperationException ( $ "{ nameof ( EditForm ) } requires a { nameof ( Model ) } " +
7989 $ "parameter, or an { nameof ( EditContext ) } parameter, but not both.") ;
8090 }
91+ else if ( ! _hasSetEditContextExplicitly && Model == null )
92+ {
93+ throw new InvalidOperationException ( $ "{ nameof ( EditForm ) } requires either a { nameof ( Model ) } " +
94+ $ "parameter, or an { nameof ( EditContext ) } parameter, please provide one of these.") ;
95+ }
8196
8297 // If you're using OnSubmit, it becomes your responsibility to trigger validation manually
8398 // (e.g., so you can display a "pending" state in the UI). In that case you don't want the
@@ -89,31 +104,31 @@ protected override void OnParametersSet()
89104 $ "{ nameof ( EditForm ) } , do not also supply { nameof ( OnValidSubmit ) } or { nameof ( OnInvalidSubmit ) } .") ;
90105 }
91106
92- // Update _fixedEditContext if we don't have one yet, or if they are supplying a
107+ // Update _editContext if we don't have one yet, or if they are supplying a
93108 // potentially new EditContext, or if they are supplying a different Model
94- if ( _fixedEditContext == null || EditContext != null || Model != _fixedEditContext . Model )
109+ if ( Model != null && Model != _editContext ? . Model )
95110 {
96- _fixedEditContext = EditContext ?? new EditContext ( Model ! ) ;
111+ _editContext = new EditContext ( Model ! ) ;
97112 }
98113 }
99114
100115 /// <inheritdoc />
101116 protected override void BuildRenderTree ( RenderTreeBuilder builder )
102117 {
103- Debug . Assert ( _fixedEditContext != null ) ;
118+ Debug . Assert ( _editContext != null ) ;
104119
105- // If _fixedEditContext changes, tear down and recreate all descendants.
120+ // If _editContext changes, tear down and recreate all descendants.
106121 // This is so we can safely use the IsFixed optimization on CascadingValue,
107- // optimizing for the common case where _fixedEditContext never changes.
108- builder . OpenRegion ( _fixedEditContext . GetHashCode ( ) ) ;
122+ // optimizing for the common case where _editContext never changes.
123+ builder . OpenRegion ( _editContext . GetHashCode ( ) ) ;
109124
110125 builder . OpenElement ( 0 , "form" ) ;
111126 builder . AddMultipleAttributes ( 1 , AdditionalAttributes ) ;
112127 builder . AddAttribute ( 2 , "onsubmit" , _handleSubmitDelegate ) ;
113128 builder . OpenComponent < CascadingValue < EditContext > > ( 3 ) ;
114129 builder . AddAttribute ( 4 , "IsFixed" , true ) ;
115- builder . AddAttribute ( 5 , "Value" , _fixedEditContext ) ;
116- builder . AddAttribute ( 6 , "ChildContent" , ChildContent ? . Invoke ( _fixedEditContext ) ) ;
130+ builder . AddAttribute ( 5 , "Value" , _editContext ) ;
131+ builder . AddAttribute ( 6 , "ChildContent" , ChildContent ? . Invoke ( _editContext ) ) ;
117132 builder . CloseComponent ( ) ;
118133 builder . CloseElement ( ) ;
119134
@@ -122,26 +137,26 @@ protected override void BuildRenderTree(RenderTreeBuilder builder)
122137
123138 private async Task HandleSubmitAsync ( )
124139 {
125- Debug . Assert ( _fixedEditContext != null ) ;
140+ Debug . Assert ( _editContext != null ) ;
126141
127142 if ( OnSubmit . HasDelegate )
128143 {
129144 // When using OnSubmit, the developer takes control of the validation lifecycle
130- await OnSubmit . InvokeAsync ( _fixedEditContext ) ;
145+ await OnSubmit . InvokeAsync ( _editContext ) ;
131146 }
132147 else
133148 {
134149 // Otherwise, the system implicitly runs validation on form submission
135- var isValid = _fixedEditContext . Validate ( ) ; // This will likely become ValidateAsync later
150+ var isValid = _editContext . Validate ( ) ; // This will likely become ValidateAsync later
136151
137152 if ( isValid && OnValidSubmit . HasDelegate )
138153 {
139- await OnValidSubmit . InvokeAsync ( _fixedEditContext ) ;
154+ await OnValidSubmit . InvokeAsync ( _editContext ) ;
140155 }
141156
142157 if ( ! isValid && OnInvalidSubmit . HasDelegate )
143158 {
144- await OnInvalidSubmit . InvokeAsync ( _fixedEditContext ) ;
159+ await OnInvalidSubmit . InvokeAsync ( _editContext ) ;
145160 }
146161 }
147162 }
0 commit comments