Converter Parameter Binding — How to Bind Complex Values at Xamarin(MAUI)
How to resolve Binding for ConverterParameter in Xamarin or MAUI? Short deep dive into reflection in converters 🥹
Sub Folks 🤗, today’s story will be short, but I hope pretty helpfully. All we write or use are some predefined Converters and bind some values. But do you ever try to Bind
CommandParameter
uh 🧐?
Before we dive deep, let’s refresh how we could bind values to Converter Parameters.
Here we bind a object value
from our BindingContext
, where our Context is our ViewModel. Our Binding is resolved and passes himself object
into Converter, which is resolved from Resources as a StaticResource
If you also specify DataType for your Parent Container (like page), you can see hints from your IDE (Visual Studio or Rider) to ensure you don’t make a mistake in your XAML code.
xmlns:viewModels="clr-namespace:ProjectNamespace.ViewModels"
x:DataType="cviewModels:SpecifiedViewModel"
Also, we able to use some Reference
‘s to pass values of runtime available things, for example, some Width
of other controls or something from outer contexts, like commands if we are inside a list element with different DataType
and BindingContext
Passing simple data into converters
Nothing extraordinary again, but wait a moment. We will come for more soon 🙃.
Same, we can pass some text or static resources, and all of them will be resolved as we expected 😊
Passing array of values into Converter
I know, I know, all know it, but if I started, I need to go through them all 😝
And would just like to mention that we may have a list of converters with a list of parameters for each of them 😱
Bing Generic things as Converter Parameter 🫣
Here it comes 😁... According to previous examples, we may expect that changing StaticResource
to Binding
will be resolved by the engine for us. But no, no, no, no, no way it will pass a Binding object 😳
Ok, so what we can do and how we can resolve it? — We can check it type, and if it’s Binding and have a Source we can get value from source by Parth by using Reflection.
So, what we are doing here 🤔? We check if propertyName
contains any .
because that means that we need to resolve property of some property from our Binding Context. Here is why:
Binding Model -> Means that in BindingContext(for example, ViewModel), we have some property named `Model`Binding Model.InnerModel -> Means that in BindingContext, we have some class or struct property named `Model` which contains public property named `InnerModel`
That can go with such recursion as deep as it is required. That’s why we check if we contain some inner property by getting the first index of .
If we contain any, we get source (left of the dot) and property name (right of the dot) and recursively calling method GetPropertyValue
with updated source and property name. Now we can Bind top-level Properties from our BindingContext
and some inner public Properties from more complex objects 😊.
But, if you pay attention inside the converter, we pass Source
into GetPropertyValue
, and it’s a null
somehow, even if we are sure we are under the same BindingContext
. To fix that we need specify Source
as Reference
to parent element or to itself.
Now we may play a little bit with it and bind value with converter and converter parameter, where the converter parameter has bindable value with its own converter and own converter parameter 🤯
I hope after this blog post, you will know that converters may expect slightly more than simple values as Converter Parameter, and you will be ready to resolve all Bindings and inner Converters in your C# code 🙃 😉
Please follow me on Twitter, and if you enjoy this blog, you can support me by buying a beer for me 😅
https://www.buymeacoffee.com/bbenetskyy
https://twitter.com/bbenetskyy