Setting margins with binding context.

JPHochbaumJPHochbaum USMember ✭✭✭
edited April 2017 in Xamarin.Forms

I am trying to add a binding context to a Margin spec like this:

  <Label Grid.Column="0"
                                              x:Name="rowHeader"
                                                Text="{Binding RowHeader}"
                                            Margin="{{Binding Margin},0,0,0}"
                                            TextColor="Black"
                                           />

The intent is to indent left when needed. THis is a grid inside a ListView and the RowHeader binding works, so I have binding set up correctly.

Binding Context Class:

 public class RowPair
    {
        public string Margin { get; set; }
        public string RowHeader { get; set; }
        public double DataRow { get; set; }
        public string Font { get; set; }

    }

I am aware that this isn't working, but need to know if it is possible to set a binding like this for Margins? Or should I do it dynamically in c#?

Best Answers

Answers

  • JPHochbaumJPHochbaum USMember ✭✭✭
    edited April 2017

    interesting, learned a new thing today! Haven't tested it yet, but I seem to have the concept down.

     class MarginConverter : IValueConverter
        {
            public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
            {
    
    
    
                if(value != null)
                {
                    double leftMargin = 0;
                    double.TryParse(value.ToString(), out leftMargin);
                    Thickness labelMargin = new Thickness( leftMargin,0,0,0);
                    return labelMargin;
    
                }
                return null;
            }
    
            public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
            {
                throw new NotImplementedException();
            }
        }
    
  • AlessandroCaliaroAlessandroCaliaro ITMember ✭✭✭✭✭

    what's the problem?

  • JPHochbaumJPHochbaum USMember ✭✭✭
    edited April 2017

    I'm still getting the same error after implementing the IValueConverter. Here is the code I have, please let me know if I am doing this right.

    class MarginConverter : IValueConverter
        {
            public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
            {
    
    
    
                if(value != null)
                {
                    double leftMargin = 0;
                    double.TryParse(value.ToString(), out leftMargin);
                    Thickness labelMargin = new Thickness( leftMargin,0,0,0);
                    return labelMargin;
    
                }
                return null;
            }
    
            public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
            {
                throw new NotImplementedException();
            }
        }
    

    ViewModel:

    public class RowPair
        {
            public Thickness Margin { get; set; }
            public string RowHeader { get; set; }
            public double DataRow { get; set; }
            public string Font { get; set; }
    
        }
    

    XAML:

    <ContentPage xmlns="http://xamarin.com/schemas/2014/forms" 
        xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml" 
        xmlns:v="clr-namespace:RiskMobileCross.ViewModels"
        xmlns:converters="clr-namespace:RiskMobileCross.ViewModels.Converters"
        x:Class="RiskMobileCross.MainView">
     <Page.Resources>
            <converters:MarginConverter x:Key="converter"/>
    
        </Page.Resources>
    .
    .
    .
     <Label Grid.Column="0"
                                                  x:Name="rowHeader"
                                                    Text="{Binding RowHeader}"
                                                Margin="{{Binding Margin, Converter={StaticResource converter}}}"
                                                TextColor="Black"
                                               />
    
  • AlessandroCaliaroAlessandroCaliaro ITMember ✭✭✭✭✭

    is it correct to have all this {} ???

    {{Binding Margin, Converter={Staticresource converter}}}"

    (I don't use XAML... so it could be correct)

    I have not understand what are you converting. "Margin" property is already a Thickness.
    What do you have to do exactly? Which is the Property should change the margin?

  • JPHochbaumJPHochbaum USMember ✭✭✭

    Well that was one big silly mistake all around.

    In my efforts to create the ValueInterface I also changed my view model Margin property from a string to a Thickness, thereby negating the need for a converter, lol.

    Now it works with just Binding it to Margin and not needing the converter.

  • JPHochbaumJPHochbaum USMember ✭✭✭

    @NMackay said:
    Yeah but adding UI specific properties to your viewmodel is considered bad practice in MVVM, it basically means you have a dependency to your UI layer in your viewmodel, essentially the UI is leaking into your view model. That's what value converters are there for.

    For example I wrote a PCL library that talks to a global position provider, as I created my own structs for geocordinates etc the library which includes interfaces and service implementation could be shared between mobile and desktop with no changes. If you even want to port that viewmodel over to another non Xamarin Forms apps you'll have to make changes.

    Good to know, because I need to do the same thing with alternating row colors with Grid rows.

  • serkan_CAKMAKserkan_CAKMAK USMember ✭✭

    @JPHochbaum said:
    interesting, learned a new thing today! Haven't tested it yet, but I seem to have the concept down.

     class MarginConverter : IValueConverter
        {
            public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
            {
                
               
              
                if(value != null)
                {
                    double leftMargin = 0;
                    double.TryParse(value.ToString(), out leftMargin);
                    Thickness labelMargin = new Thickness( leftMargin,0,0,0);
                    return labelMargin;
    
                }
                return null;
            }
    
            public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
            {
                throw new NotImplementedException();
            }
        }
    

    I just want to let you know Guys any value converter in xaml will make your page slow and lags while scroll I would suggest in this case avoid MVVM and write at code behind simple as .Margin = new Thicknes(0,0,0,0) ;

Sign In or Register to comment.