1

Is it possible to use MvvmCross to bind the height of an object to a property in the viewmodel?

<ImageView
android:src="@drawable/blue_cat_icon"
android:layout_width="wrap_content"
android:layout_height="match_parent"
local:MvxBind="layout_height User.Height; layout_width User.Width" />

Xamarin studio complains if there's no layout_height or layout_width defined, so I'm hoping there's a way to override a property through binding.

I have five icons and I only want one of them to be larger based on a property of the VM, I also assume I'll be using a value converter.

meowmeowbeenz

pnewhook
  • 4,048
  • 2
  • 31
  • 49

1 Answers1

4

I think the approach to take for this would be similar to the approach in How to bind to View's layout_weight in MvvmCross?

1. Add a Type for your scaling - e.g.

public class Scaling
{
    public double Height {get; private set;}
    public double Width {get; private set;}

    // ctor
}

2. Add a property for that type too

public Scaling CurrentScaling
{
    get { return _scaling; }
    set { _scaling = value; RaisePropertyChanged(() => CurrentScaling); }
}

3. In the view project add a custom binding that knows about Scaling

public class ViewScalingCustomBinding : MvxAndroidTargetBinding
{
    public ViewScalingCustomBinding(object target) : base(target)
    {
    }

    public override Type TargetType
    {
        get { return typeof (Scaling); }
    }

    protected override void SetValueImpl(object target, object value)
    {
        var realTarget = target as View;
        if(target == null)
            return;

        var scaling = value as Scaling;

        ViewGroup.LayoutParams layoutParameters = realTarget.LayoutParameters;
        realTarget.LayoutParameters = new LinearLayout.LayoutParams(scaling.Width, scaling.Height);
    }
}

4. In the view project register the custom binding that knows about Scaling

protected override void FillTargetFactories(Cirrious.MvvmCross.Binding.Bindings.Target.Construction.IMvxTargetBindingFactoryRegistry registry)
{
    registry.RegisterCustomBindingFactory<View>(
                    "ScaleMe", 
                    v => new ViewScalingCustomBinding(v) );
    base.FillTargetFactories(registry);
}

5. Use the binding

local:MvxBind="ScaleMe CurrentScaling"

Note:

  • the Type used for LayoutParameters is container dependent - in this code above I used LinearLayout
  • none of this code above is tested - but the general approach should work
  • if you are using API 11 or greater, then another approach is to use Android View's ScaleX and ScaleY properties - that's what I'd prefer to use.
Community
  • 1
  • 1
Stuart
  • 66,722
  • 7
  • 114
  • 165