Home > Software design >  Xamarin custom controls
Xamarin custom controls

Time:11-13

I am new to Xamarin.I decided my first project to be a fitness app.I wanted to have a custom control , an image with a button and a label inside of it , so I did this in a content view file:

<ContentView xmlns="http://xamarin.com/schemas/2014/forms" 
             xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
             x:Class="Fitness_App.TabWorkout">
    <RelativeLayout >
        <Image x:Name="img" Source="workout"/>
        <Button BackgroundColor= "Wheat"
                CornerRadius="30"
                WidthRequest="50"
                HeightRequest="50"
                RelativeLayout.XConstraint="{ConstraintExpression Type=RelativeToView, ElementName=img, Property=Width, Factor=0.68}"
                RelativeLayout.YConstraint="{ConstraintExpression Type=RelativeToView, ElementName=img, Property=Height, Factor=0.45}"/>
         <Label x:Name="workout_name"
                FontFamily="BebasNeue"
                TextColor ="ForestGreen"
                FontSize="37"
                RelativeLayout.XConstraint="{ConstraintExpression Type=RelativeToView, ElementName=img, Property=Width, Factor=0.18}"
                RelativeLayout.YConstraint="{ConstraintExpression Type=RelativeToView, ElementName=img, Property=Height, Factor=0.2}"/>
                
    </RelativeLayout>

</ContentView>

And since I want 5 workouts(for 5 muscle groups) , I put this inside my page:

<ContentPage.Content>
            <ScrollView>
                <StackLayout>
                    <local:TabWorkout/>
                    <local:TabWorkout/>
                    <local:TabWorkout/>
                    <local:TabWorkout/>
                    <local:TabWorkout/>
                </StackLayout>
            </ScrollView>
        </ContentPage.Content>

and this is how it looks: android simulator I have read about bindable properties but I don't know how they would help me in this case.I don't know why the width of my image is not full.When I have just placed images in my stacklayout , it seemed to work.Maybe you guys have another idea for this?thanks.

CodePudding user response:

I have read about bindable properties but I don't know how they would help me in this case.

Here we add bindable property for the Image control , the same way to the Label.

  1. Define BindableProperty in custom control .

  2. Set the image source in propertyChanged callback .

  3. Assign the value in xaml .

    [XamlCompilation(XamlCompilationOptions.Compile)]
     public partial class TabWorkout : ContentView
     {
         public TabWorkout()
         {
             InitializeComponent();
         }
    
         public static readonly BindableProperty ImageNameProperty =
             BindableProperty.Create("ImageName", typeof(string), typeof(TabWorkout), propertyChanged: OnEventNameChanged);
    
         public string ImageName
         {
             get { return (string)GetValue(ImageNameProperty); }
             set {
                 SetValue(ImageNameProperty, value);
             }
    
         }
    
         static void OnEventNameChanged(BindableObject bindable, object oldValue, object newValue)
         {
             if(newValue != null)
             {
                 var control = (TabWorkout)bindable;
                 control.img.Source = ImageSource.FromFile(newValue as string);
             }
         }
     }
    
     <ScrollView>
         <StackLayout>
             <local:TabWorkout ImageName="a.jpg"/>
             <local:TabWorkout ImageName="b.png"/>
             <local:TabWorkout ImageName="c.png"/>
             <local:TabWorkout ImageName="d.png"/>
         </StackLayout>
     </ScrollView>
    

I don't know why the width of my image is not full.

Set Aspect to Fill should be able to solve the problem .

 <Image x:Name="img" Aspect="Fill"/>

Update

For bindable property , you can not only assign the value directly like normal property field but also create binding on it .

<ScrollView>
    <StackLayout>
        <local:TabWorkout ImageName="{Binding ImageName}"/>
        <local:TabWorkout ImageName="a.jpg"/>
    </StackLayout>
</ScrollView>
  • Related