Skip to content

Commit 1743409

Browse files
committed
Compiled bindings in code
1 parent cc39a7f commit 1743409

File tree

8 files changed

+143
-7
lines changed

8 files changed

+143
-7
lines changed

FmgLib.MauiMarkup.sln

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,8 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "MatchingImage", "sample\Mat
3838
EndProject
3939
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "DalluiApp", "sample\DalluiApp\DalluiApp.csproj", "{F5A12C0E-7521-44A3-AE6A-A0B871B82B5B}"
4040
EndProject
41+
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "App1", "sample\App1\App1.csproj", "{8E5E5952-56CF-462C-9768-79F03E13AEBE}"
42+
EndProject
4143
Global
4244
GlobalSection(SolutionConfigurationPlatforms) = preSolution
4345
Debug|Any CPU = Debug|Any CPU
@@ -102,6 +104,10 @@ Global
102104
{F5A12C0E-7521-44A3-AE6A-A0B871B82B5B}.Release|Any CPU.ActiveCfg = Release|Any CPU
103105
{F5A12C0E-7521-44A3-AE6A-A0B871B82B5B}.Release|Any CPU.Build.0 = Release|Any CPU
104106
{F5A12C0E-7521-44A3-AE6A-A0B871B82B5B}.Release|Any CPU.Deploy.0 = Release|Any CPU
107+
{8E5E5952-56CF-462C-9768-79F03E13AEBE}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
108+
{8E5E5952-56CF-462C-9768-79F03E13AEBE}.Debug|Any CPU.Build.0 = Debug|Any CPU
109+
{8E5E5952-56CF-462C-9768-79F03E13AEBE}.Release|Any CPU.ActiveCfg = Release|Any CPU
110+
{8E5E5952-56CF-462C-9768-79F03E13AEBE}.Release|Any CPU.Build.0 = Release|Any CPU
105111
EndGlobalSection
106112
GlobalSection(SolutionProperties) = preSolution
107113
HideSolutionNode = FALSE
@@ -118,6 +124,7 @@ Global
118124
{B47B6A87-BDE4-4925-B5EE-A0F1B369CE93} = {A4956394-4BE4-4C5A-BDD3-59F439A1FD98}
119125
{244351D3-44F2-4C90-9B1C-3BCE7DD14172} = {A4956394-4BE4-4C5A-BDD3-59F439A1FD98}
120126
{F5A12C0E-7521-44A3-AE6A-A0B871B82B5B} = {A4956394-4BE4-4C5A-BDD3-59F439A1FD98}
127+
{8E5E5952-56CF-462C-9768-79F03E13AEBE} = {A4956394-4BE4-4C5A-BDD3-59F439A1FD98}
121128
EndGlobalSection
122129
GlobalSection(ExtensibilityGlobals) = postSolution
123130
SolutionGuid = {2698E1E7-D253-457B-AF1B-6754123E0A11}
Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
using System.Linq.Expressions;
2+
3+
namespace FmgLib.MauiMarkup;
4+
5+
public class ParameterReplacer : ExpressionVisitor
6+
{
7+
private readonly ParameterExpression _oldParameter;
8+
private readonly Expression _newParameter;
9+
10+
public ParameterReplacer(ParameterExpression oldParameter, Expression newParameter)
11+
{
12+
_oldParameter = oldParameter;
13+
_newParameter = newParameter;
14+
}
15+
16+
protected override Expression VisitParameter(ParameterExpression node)
17+
{
18+
return node == _oldParameter ? _newParameter : base.VisitParameter(node);
19+
}
20+
}

src/FmgLib.MauiMarkup/Core/Builder/PropertyBindingBuilder.cs

Lines changed: 46 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
using System.Globalization;
2+
using System.Linq.Expressions;
23

34
namespace FmgLib.MauiMarkup;
45

@@ -31,6 +32,10 @@ public object ConvertBack(object value, Type targetType, object parameter, Cultu
3132
}
3233
}
3334

35+
private Expression<Func<object, T>> getter;
36+
37+
private Action<object, T> setter;
38+
3439
private string path;
3540

3641
private BindingMode bindingMode;
@@ -58,7 +63,22 @@ public PropertyBindingBuilder(PropertyContext<T> context)
5863

5964
public bool Build()
6065
{
61-
if (path != null)
66+
if (getter != null)
67+
{
68+
Context.BindableObject.Bind(Context.Property,
69+
getter: getter,
70+
setter: setter,
71+
mode: bindingMode,
72+
converter: converter,
73+
converterParameter: converterParameter,
74+
stringFormat: stringFormat,
75+
source: source,
76+
targetNullValue: targetNullValue,
77+
fallbackValue: fallbackValue);
78+
79+
return true;
80+
}
81+
else if (path != null)
6282
{
6383
Context.BindableObject.SetBinding(Context.Property, new Binding(path, bindingMode, converter, converterParameter, stringFormat, source)
6484
.FallbackValue(fallbackValue)
@@ -69,6 +89,31 @@ public bool Build()
6989
return false;
7090
}
7191

92+
public PropertyBindingBuilder<T> Getter<TContext>(Expression<Func<TContext, T>> getter)
93+
{
94+
var parameter = Expression.Parameter(typeof(object), "obj");
95+
var convertedParam = Expression.Convert(parameter, typeof(TContext));
96+
97+
var body = getter.Body;
98+
99+
var newBody = new ParameterReplacer(getter.Parameters[0], convertedParam).Visit(body);
100+
101+
this.getter = Expression.Lambda<Func<object, T>>(newBody, parameter);
102+
103+
return this;
104+
}
105+
106+
public PropertyBindingBuilder<T> Setter<TContext>(Action<TContext, T> setter)
107+
{
108+
this.setter = (obj, value) =>
109+
{
110+
var contextObj = (TContext)obj;
111+
setter(contextObj, value);
112+
};
113+
114+
return this;
115+
}
116+
72117
public PropertyBindingBuilder<T> Path(string path)
73118
{
74119
this.path = path;

src/FmgLib.MauiMarkup/Core/Builder/PropertySettersBindingBuilder.cs

Lines changed: 55 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,6 @@
11
using System.Globalization;
2+
using System.Linq.Expressions;
3+
using Microsoft.Maui.Controls.Internals;
24

35
namespace FmgLib.MauiMarkup;
46

@@ -31,6 +33,10 @@ public object ConvertBack(object value, Type targetType, object parameter, Cultu
3133
}
3234
}
3335

36+
private Expression<Func<object, T>> getter;
37+
38+
private Action<object, T> setter;
39+
3440
private string path;
3541

3642
private BindingMode bindingMode;
@@ -58,7 +64,30 @@ public PropertySettersBindingBuilder(PropertySettersContext<T> context)
5864

5965
public bool Build()
6066
{
61-
if (path != null)
67+
if (getter != null)
68+
{
69+
var getterFunc = TypedBindingExtensions.ConvertExpressionToFunc(getter);
70+
var handlers = new (Func<object, object?>, string)[]
71+
{ ((object b) => b, TypedBindingExtensions.GetMemberName(getter)) };
72+
Context.XamlSetters.Add(
73+
new Setter
74+
{
75+
Property = Context.Property,
76+
Value = new TypedBinding<object, T>(bindingContext => (getterFunc(bindingContext), true), setter, handlers.Select(x => x.ToTuple()).ToArray())
77+
{
78+
Mode = bindingMode,
79+
Converter = converter,
80+
ConverterParameter = converterParameter,
81+
StringFormat = stringFormat,
82+
Source = source,
83+
TargetNullValue = targetNullValue,
84+
FallbackValue = fallbackValue
85+
}
86+
}
87+
);
88+
return true;
89+
}
90+
else if (path != null)
6291
{
6392
Context.XamlSetters.Add(
6493
new Setter
@@ -74,6 +103,31 @@ public bool Build()
74103

75104
return false;
76105
}
106+
107+
public PropertySettersBindingBuilder<T> Getter<TContext>(Expression<Func<TContext, T>> getter)
108+
{
109+
var parameter = Expression.Parameter(typeof(object), "obj");
110+
var convertedParam = Expression.Convert(parameter, typeof(TContext));
111+
112+
var body = getter.Body;
113+
114+
var newBody = new ParameterReplacer(getter.Parameters[0], convertedParam).Visit(body);
115+
116+
this.getter = Expression.Lambda<Func<object, T>>(newBody, parameter);
117+
118+
return this;
119+
}
120+
121+
public PropertySettersBindingBuilder<T> Setter<TContext>(Action<TContext, T> setter)
122+
{
123+
this.setter = (obj, value) =>
124+
{
125+
var contextObj = (TContext)obj;
126+
setter(contextObj, value);
127+
};
128+
129+
return this;
130+
}
77131

78132
public PropertySettersBindingBuilder<T> Path(string path)
79133
{

src/FmgLib.MauiMarkup/Extensions/PropertyContextExtension.cs

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,12 @@
1-
namespace FmgLib.MauiMarkup;
1+
using System.Linq.Expressions;
2+
3+
namespace FmgLib.MauiMarkup;
24

35
public static class PropertyContextExtension
46
{
7+
8+
public static PropertyBindingBuilder<T> Getter<TContext, T>(this PropertyContext<T> self, Expression<Func<TContext, T>> getter)
9+
=> new PropertyBindingBuilder<T>(self).Getter<TContext>(getter);
510

611
public static PropertyBindingBuilder<T> Path<T>(this PropertyContext<T> self, string path)
712
=> new PropertyBindingBuilder<T>(self).Path(path);

src/FmgLib.MauiMarkup/Extensions/PropertySettersContextExtension.cs

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,12 @@
1-
namespace FmgLib.MauiMarkup;
1+
using System.Linq.Expressions;
2+
3+
namespace FmgLib.MauiMarkup;
24

35
public static class PropertySettersContextExtension
46
{
7+
public static PropertySettersBindingBuilder<T> Getter<TContext, T>(this PropertySettersContext<T> self, Expression<Func<TContext, T>> getter)
8+
=> new PropertySettersBindingBuilder<T>(self).Getter<TContext>(getter);
9+
510
public static PropertySettersBindingBuilder<T> Path<T>(this PropertySettersContext<T> self, string path)
611
=> new PropertySettersBindingBuilder<T>(self).Path(path);
712

src/FmgLib.MauiMarkup/Extensions/TypedBindingExtensions.cs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -173,9 +173,9 @@ public static TBindable Bind<TBindable, TBindingContext, TSource, TParam, TDest>
173173
fallbackValue);
174174
}
175175

176-
static Func<TBindingContext, TSource> ConvertExpressionToFunc<TBindingContext, TSource>(in Expression<Func<TBindingContext, TSource>> expression) => expression.Compile();
176+
public static Func<TBindingContext, TSource> ConvertExpressionToFunc<TBindingContext, TSource>(in Expression<Func<TBindingContext, TSource>> expression) => expression.Compile();
177177

178-
static string GetMemberName<T>(in Expression<T> expression) => expression.Body switch
178+
public static string GetMemberName<T>(in Expression<T> expression) => expression.Body switch
179179
{
180180
MemberExpression m => m.Member.Name,
181181
UnaryExpression u when u.Operand is MemberExpression m => m.Member.Name,

src/FmgLib.MauiMarkup/FmgLib.MauiMarkup.csproj

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@
1212
<PackageId>FmgLib.MauiMarkup</PackageId>
1313
<Summary>FmgLib.MauiMarkup with C# Markup classes and fluent helper methods</Summary>
1414
<Title>FmgLib.MauiMarkup</Title>
15-
<Version>9.0.1</Version>
15+
<Version>9.0.2-preview1.0.12</Version>
1616
<Authors>FmgYazılım</Authors>
1717
<Company>Fmg Yazılım</Company>
1818
<Copyright>©2024</Copyright>

0 commit comments

Comments
 (0)