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 Nov 24, 2024
1 parent 3019446 commit e7708ec
Show file tree
Hide file tree
Showing 8 changed files with 24 additions and 16 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
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 e7708ec

Please sign in to comment.