Skip to content

Commit

Permalink
Fix some issues with incorrect binding result types
Browse files Browse the repository at this point in the history
* ExpectedType property can now be null, when the assigned property is unknwon:
   - this means that CreateBinding will actually create a strongly
     typed instance, instead of just ValueBindingExpression<object> or similar
* AutoUI uses props.Property instead of CreateValueBinding where possible
  • Loading branch information
exyi committed Dec 1, 2024
1 parent 3019446 commit 10002de
Show file tree
Hide file tree
Showing 10 changed files with 27 additions and 19 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,7 @@ public override DotvvmControl CreateControl(PropertyDisplayMetadata property, Au
.SetCapability(props.Html)
.SetProperty(c => c.Enabled, props.Enabled)
.SetProperty(c => c.SelectionChanged, props.Changed)
.SetProperty(c => c.SelectedValue, (IValueBinding)context.CreateValueBinding(property));
.SetProperty(c => c.SelectedValue, props.Property);

if (isNullable)
{
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ public override bool CanHandleProperty(PropertyDisplayMetadata property, AutoUIC
protected override GridViewColumn CreateColumnCore(PropertyDisplayMetadata property, AutoGridViewColumn.Props props, AutoUIContext context)
{
var column = new GridViewCheckBoxColumn();
column.SetBinding(GridViewCheckBoxColumn.ValueBindingProperty, context.CreateValueBinding(property));
column.SetBinding(GridViewCheckBoxColumn.ValueBindingProperty, props.Property);
return column;
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -174,12 +174,20 @@ expression is JsNewExpression ||

public ResultTypeBindingProperty GetResultType(ParsedExpressionBindingProperty expression) => new ResultTypeBindingProperty(expression.Expression.Type);

public ExpectedTypeBindingProperty GetExpectedType(AssignedPropertyBindingProperty? property = null)
public ExpectedTypeBindingProperty? GetExpectedType(AssignedPropertyBindingProperty? property = null)
{
var prop = property?.DotvvmProperty;
if (prop == null) return new ExpectedTypeBindingProperty(typeof(object));
if (prop == null) return null;

return new ExpectedTypeBindingProperty(prop.IsBindingProperty ? (prop.PropertyType.GenericTypeArguments.SingleOrDefault() ?? typeof(object)) : prop.PropertyType);
if (prop.IsBindingProperty)
{
if (prop.PropertyType.GenericTypeArguments.SingleOrDefault() is {} type)
return new ExpectedTypeBindingProperty(type);
else
return null;
}

return new ExpectedTypeBindingProperty(prop.PropertyType);
}

public BindingCompilationRequirementsAttribute GetAdditionalResolversFromProperty(AssignedPropertyBindingProperty property)
Expand Down Expand Up @@ -264,9 +272,9 @@ public NegatedBindingExpression NegateBinding(ParsedExpressionBindingProperty e,
(Expression)Expression.Not(e.Expression)
));
}
public ExpectedAsStringBindingExpression ExpectAsStringBinding(ParsedExpressionBindingProperty e, ExpectedTypeBindingProperty expectedType, IBinding binding)
public ExpectedAsStringBindingExpression ExpectAsStringBinding(ParsedExpressionBindingProperty e, IBinding binding, ExpectedTypeBindingProperty? expectedType = null)
{
if (expectedType.Type == typeof(string))
if (expectedType is {} && expectedType.Type == typeof(string))
return new(binding);

return new(binding.DeriveBinding(new ExpectedTypeBindingProperty(typeof(string)), e));
Expand Down
4 changes: 2 additions & 2 deletions src/Framework/Framework/Controls/GridViewCheckBoxColumn.cs
Original file line number Diff line number Diff line change
Expand Up @@ -15,9 +15,9 @@ public class GridViewCheckBoxColumn : GridViewColumn
/// Gets or sets a binding which retrieves the value to display from the current data item.
/// </summary>
[MarkupOptions(AllowHardCodedValue = false, Required = true)]
public IStaticValueBinding<bool?> ValueBinding
public IStaticValueBinding ValueBinding
{
get { return (IStaticValueBinding<bool?>)GetValueRaw(ValueBindingProperty)!; }
get { return (IStaticValueBinding)GetValueRaw(ValueBindingProperty)!; }
set { SetValue(ValueBindingProperty, value); }
}
public static readonly DotvvmProperty ValueBindingProperty =
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -119,8 +119,8 @@ ParameterExpression CreateParameter(DataContextStack dataContextStack, string na
: null,

PageNumberText = isServerOnly switch {
true => service.Cache.CreateResourceBinding<string>("_this + 1", pageIndexDataContext),
false => service.Cache.CreateValueBinding<string>("_this + 1", pageIndexDataContext)
true => service.Cache.CreateResourceBinding<string>("(_this + 1) + ''", pageIndexDataContext),
false => service.Cache.CreateValueBinding<string>("(_this + 1) + ''", pageIndexDataContext)
},
HasMoreThanOnePage =
GetValueBindingOrNull<IPageableGridViewDataSet<PagingOptions>, bool>(d => d.PagingOptions.PagesCount > 1) ??
Expand Down
2 changes: 1 addition & 1 deletion src/Framework/Framework/Controls/Literal.cs
Original file line number Diff line number Diff line change
Expand Up @@ -97,7 +97,7 @@ bool isFormattedType(Type? type) =>
type != null && (type == typeof(float) || type == typeof(double) || type == typeof(decimal) ||
type == typeof(DateTime) || type == typeof(DateOnly) || type == typeof(TimeOnly) || isFormattedType(Nullable.GetUnderlyingType(type)));

bool isFormattedTypeOrObj(Type? type) => type == typeof(object) || isFormattedType(type);
bool isFormattedTypeOrObj(Type? type) => type is null || type == typeof(object) || isFormattedType(type);

return isFormattedType(binding?.ResultType) && isFormattedTypeOrObj(binding?.GetProperty<ExpectedTypeBindingProperty>(ErrorHandlingMode.ReturnNull)?.Type);
}
Expand Down

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

4 changes: 2 additions & 2 deletions src/Samples/Tests/Tests/Control/GridViewTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -510,10 +510,10 @@ public void Control_GridView_GridViewInlineEditing_PagingWhenEditing(string path
[Theory]
[InlineData(SamplesRouteUrls.ControlSamples_GridView_GridViewPagingSorting)]
[InlineData(SamplesRouteUrls.ControlSamples_GridView_GridViewServerRender)]
[InlineData(SamplesRouteUrls.ControlSamples_GridView_GridViewPagingSortingServerOnly)]
[InlineData(SamplesRouteUrls.ControlSamples_GridView_GridViewPagingSortingServerSide)]
[SampleReference(nameof(SamplesRouteUrls.ControlSamples_GridView_GridViewPagingSorting))]
[SampleReference(nameof(SamplesRouteUrls.ControlSamples_GridView_GridViewServerRender))]
[SampleReference(nameof(SamplesRouteUrls.ControlSamples_GridView_GridViewPagingSortingServerOnly))]
[SampleReference(nameof(SamplesRouteUrls.ControlSamples_GridView_GridViewPagingSortingServerSide))]
public void Control_GridView_GridViewPagingSortingBase(string path)
{
RunInAllBrowsers(browser => {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,10 +11,10 @@
<!-- ko foreach: { data: Customers()?.PagingOptions()?.NearPageIndexes } -->
<li data-bind="css: { active: $data == $parent.Customers()?.PagingOptions()?.PageIndex() }">
<!-- ko if: $data != $parent.Customers()?.PagingOptions()?.PageIndex() -->
<a data-bind="text: dotvvm.globalize.bindingNumberToString($data + 1)" href="javascript:;" onclick="dotvvm.postBack(this,[&quot;Customers()?.PagingOptions()?.NearPageIndexes/[$index]&quot;],&quot;J4s1chtqLBUO+Bt2&quot;,&quot;&quot;,null,[],[],undefined).catch(dotvvm.log.logPostBackScriptError);event.stopPropagation();return false;"></a>
<a data-bind="text: $data + 1" href="javascript:;" onclick="dotvvm.postBack(this,[&quot;Customers()?.PagingOptions()?.NearPageIndexes/[$index]&quot;],&quot;J4s1chtqLBUO+Bt2&quot;,&quot;&quot;,null,[],[],undefined).catch(dotvvm.log.logPostBackScriptError);event.stopPropagation();return false;"></a>
<!-- /ko -->
<!-- ko if: $data == $parent.Customers()?.PagingOptions()?.PageIndex() -->
<span data-bind="text: dotvvm.globalize.bindingNumberToString($data + 1)"></span>
<span data-bind="text: $data + 1"></span>
<!-- /ko -->
</li>
<!-- /ko -->
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,13 +17,13 @@
<!-- ko foreach: { data: Customers()?.PagingOptions()?.NearPageIndexes } -->
<li data-bind="css: { active: $data == $parent.Customers()?.PagingOptions()?.PageIndex() }">
<!-- ko if: $data != $parent.Customers()?.PagingOptions()?.PageIndex() -->
<a data-bind="text: dotvvm.globalize.bindingNumberToString($data + 1)" href="javascript:;" onclick="dotvvm.applyPostbackHandlers(async (options) => {
<a data-bind="text: $data + 1" href="javascript:;" onclick="dotvvm.applyPostbackHandlers(async (options) => {
let cx = options.knockoutContext;
return await dotvvm.dataSet.loadDataSet(cx.$parent.Customers, (options) => dotvvm.dataSet.translations.PagingOptions.goToPage(ko.unwrap(options).PagingOptions, cx.$rawData.state), cx.$gridViewDataSetHelper.loadDataSet, cx.$gridViewDataSetHelper.postProcessor);
},this).catch(dotvvm.log.logPostBackScriptError);event.stopPropagation();return false;"></a>
<!-- /ko -->
<!-- ko if: $data == $parent.Customers()?.PagingOptions()?.PageIndex() -->
<span data-bind="text: dotvvm.globalize.bindingNumberToString($data + 1)"></span>
<span data-bind="text: $data + 1"></span>
<!-- /ko -->
</li>
<!-- /ko -->
Expand Down

0 comments on commit 10002de

Please sign in to comment.