Forum Xamarin.Forms
We are excited to announce that the Xamarin Forums are moving to the new Microsoft Q&A experience. Q&A is the home for technical questions and answers at across all products at Microsoft now including Xamarin!

We encourage you to head over to Microsoft Q&A for .NET for posting new questions and get involved today.

Best Practice for varying multiple properties according to binding

JosephRedfernJosephRedfern GBMember ✭✭
edited July 2015 in Xamarin.Forms

Hi All.

I have a ListView, and would like to vary multiple properties of a label in each ViewCell of my ListView according to parameters of a bound object.

For instance, consider the following snippet from my ViewCell:

    var statusLabel = new Label();

Backed by the following model:

public class DataModel{
    public String Name {get; set;}
    public int Count {get; set;}
}

As an example, I'd like to vary the COLOUR of my statusLabel according to the "Name" value - if the name starts with an A, B or C then it should be Red. D, E, or F then it should be Green - otherwise it should be purple. I'd also like to vary the TEXT of statusLabel according to Count - if it's in the range 0 < Count <= 50, text should be the string "Small". 50 < Count <= 100, text should be the string "Medium", and if Count > 100, text should be "Large".

I could accomplish this by writing several IValueConverter classes for each property, but this seems excessive. Is it possible to write one IValueConverter that works across both bindings?

Additionally, is it possible to access all fields of my DataModel from a single IValueConverter? In my actual use-case, I want to vary the properties of statusLabel according to comparisons made across several fields in DataModel. I can't see a way of doing this if I have to specify the field to bind to in the Binding constructor when calling SetBinding() on statusLabel.

I am using pure-code rather than XAML for this task.

Thanks in advanced.

Joe

Answers

  • AlessandroCaliaroAlessandroCaliaro ITMember ✭✭✭✭✭

    In your model you could have a Color property. In Get method you can write
    if Name xxx then return Color.red

    And then in setbinding use Color property

  • JosephRedfernJosephRedfern GBMember ✭✭
    edited July 2015

    Hmm, I could do that, but it feels wrong to me... surely there should be better separation between View and Model? This is a purely stylistic thing.

    I've previously used an IValueConverter to derive to style properties from bound model properties/fields. I could possible to the same again, but is it really necessary to implement several IValueConverters to style a single label? I'd like to be able to have a method with a signature like:

    public Label GetLabel(DataModel model){
        var label = new Label();
        //...style label according to model
        return label;
    }
    

    that I could use on my ViewCell, passing in the bound model - however, that doesn't seem to currently be possible :disappointed:

    EDIT:

    It turns out this IS possible, so I've come up with a satisfactory solution.

    Rather than styling my label in the constructor, I'm styling it in:

        protected override void OnBindingContextChanged()
        {
            base.OnBindingContextChanged();
            Icons.Children.Add(GetStatusLabel((DataModel)BindingContext), 0, 0);
        }
    

    I can then have a GetStatusLabel method that looks like:

    public Label GetStatusLabel(DataModel object){
        var label = new Label()
        //style label accoriding to data model object
        return label
    }
    

    This solution works well, and means I don't have to implement several IValueConverters (as I only require one-way conversion).

    Thanks,
    Joe

Sign In or Register to comment.