Hi all,
I've got a requirement to fill a bunch of boxes with a color based on a individual double properties on the viewmodel which represent the percentage "full" the box should be. These properties can change after the View has been built so they depend on being able to update from an OnPropertyChanged event, also they can render at different sizes depending on device/orientation so I'm stuck needing to have it fill based on a percentage of its parent.
I'm converting from a Windows Phone project, where it was really easy to accomplish this, just use a gradient brush on the box background and bind the Offsets on both gradient brush colors to the same double. End result is no gradient and the stops determine how much one color fills the box.
I'm having a nightmare of a time translating this concept to Xamarin Forms. My first approach was to create custom renderers adding gradient fill to objects. The problem is Android didn't have the concept of an offset for the primary and secondary colors (though there is an offset for a center color...go figure)
Ok fine, I'll take a completely different approach. Xamrin gives us relative layouts so let's try that. I can certainly mimic the look by putting a BoxView in a relativelayout with a Relative to Parent height constraint and manually setting the Factor gives me the behavior I need. But I can't bind the "Factor" value to the code behind within the ConstraintExpression markup extension at least I don't know of, nor can I find a way to do a binding within a MarkUpExtension, which makes sense to me that you couldn't anyway.
So I decide to look at what HeightConstraint wants. It just needs a Constraint, so let's try binding to the double property in the viewmodel and using a converter to turn the double into the constraint formula. Easy enough to create a converter that says something like
return Constraint.RelativeToParent(parent => parent.Height * (double)value);
Now in my mind I'm passing back a self created Constraint expression which is what the ConstraintExpression MarkUp extension does for you, but I really have no idea what exactly RelativeLayout.HeightConstraint is expecting the Constraint to receive. Regardless, the converter is being called and returns an expression but the height of the box doesn't change. I don't know if it processes the expression in such a way that it can't resolve parent from the lamba I've returned, or perhaps HeightConstraint isn't actually a property I can bind to constraint (though I can tell you from testing if I try to return anything other than a constraint it errors)?
I'm running out of ideas, and am hoping someone has an idea how to accomplish what to me is fairly embarrassing that I can't figure out what should be a simple task. We have a mandate to follow MVVM as closely as possible, and so far I've been able to keep the view's code behind free of anything, so ideally I need something that can be implemented via behaviours, converters, or custom controls.
Thank you for any suggestions that can point me on the right track.