Search This Blog

Saturday, 4 May 2019

Step to Create ImageButton with text using Xamarin Form




Add the ContentView and design a custom layout 
ImageButtonView.xaml
<?xml version="1.0" encoding="UTF-8"?>
<ContentView xmlns="http://xamarin.com/schemas/2014/forms" xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml" x:Class="XamarinTest.View.ImageButtonView">
    <ContentView.Content>
                <Frame  x:Name="frmObject"   HasShadow="false">
                    <StackLayout Orientation="Horizontal" Margin="-10,-15,-10,-15">
                         <Image x:Name="imgSource"  />
                         <Label VerticalTextAlignment="Center" x:Name="lblText" />
                    </StackLayout>
                </Frame>
    </ContentView.Content>
</ContentView>

Now create the bindable property for  Label, Image
ImageButtonView.xaml.cs


using System;
using System.Collections.Generic;
using System.Windows.Input;
using Xamarin.Forms;

namespace XamarinTest.View
{
    public partial class ImageButtonView : ContentView
    {
        public ImageButtonView()
        {
            InitializeComponent();
        }

        #region ImageSource
        public static readonly BindableProperty ImageSourceProperty = BindableProperty.Create(
         propertyName: "Source",
         returnType: typeof(string),
         declaringType: typeof(ImageButtonView),
         defaultValue: "",
         defaultBindingMode: BindingMode.TwoWay,
         propertyChanged: ImageSourcePropertyChanged);

        private static void ImageSourcePropertyChanged(BindableObject bindable, object oldValue, object newValue)
        {
            var control = (ImageButtonView)bindable;
            control.imgSource.Source = ImageSource.FromFile(newValue.ToString());
        }
        public string Source
        {
            get { return base.GetValue(ImageSourceProperty).ToString(); }
            set { base.SetValue(ImageSourceProperty, value); }
        }
        #endregion

        #region LabelText
        public static readonly BindableProperty LabelTextProperty = BindableProperty.Create(
         propertyName: "Text",
         returnType: typeof(string),
          declaringType: typeof(ImageButtonView),
         defaultValue: "",
         defaultBindingMode: BindingMode.TwoWay,
         propertyChanged: LabelTextPropertyChanged);

        private static void LabelTextPropertyChanged(BindableObject bindable, object oldValue, object newValue)
        {
            var control = (ImageButtonView)bindable;
            control.lblText.Text = newValue.ToString();
        }
        public string Text
        {
            get { return base.GetValue(LabelTextProperty).ToString(); }
            set { base.SetValue(LabelTextProperty, value); }
        }
        #endregion

        #region BackGroundColor
        // this  property used to set background color of frame
        public static readonly BindableProperty BackgroundColorProperty = BindableProperty.Create(
            propertyName: "BackgroundColor",
            returnType: typeof(Color),
            declaringType: typeof(ImageButtonView),
            defaultValue: Color.White,
            defaultBindingMode: BindingMode.TwoWay,
            propertyChanged: BackgroundColorPropertyChanged);

        public Color BackgroundColor
        {
            get { return (Color)base.GetValue(BackgroundColorProperty); }
            set { base.SetValue(BackgroundColorProperty, value); }
        }

        private static void BackgroundColorPropertyChanged(BindableObject bindable, object oldValue, object newValue)
        {
            var control = (ImageButtonView)bindable;
            control.frmObject.BackgroundColor = (Color)newValue;
        }
        #endregion

        #region CornerRadius
        public static readonly BindableProperty CornerRadiusProperty = BindableProperty.Create(
            propertyName: "CornerRadius",
            returnType: typeof(int),
            declaringType: typeof(ImageButtonView),
            defaultValue: 0,
            defaultBindingMode: BindingMode.TwoWay,
            propertyChanged: CornerRadiusPropertyChanged
            );

        public int CornerRadius
        {
            get { return (int)base.GetValue(CornerRadiusProperty); }
            set { base.SetValue(CornerRadiusProperty, value); }
        }

        private static void CornerRadiusPropertyChanged(BindableObject bindable, object oldValue, object newValue)
        {
            var control = (ImageButtonView)bindable;
            control.frmObject.CornerRadius = (int)newValue;
        }
        #endregion

        #region ImageHeightWidthProperty

        public static readonly BindableProperty ImageHeightRequestProperty = BindableProperty.Create(
            propertyName: "ImageHeightRequest",
            returnType: typeof(double),
            declaringType: typeof(ImageButtonView),
            propertyChanged: ImageHeightRequestPropertyChanged
            );

        private static void ImageHeightRequestPropertyChanged(BindableObject bindable, object oldValue, object newValue)
        {
            var control = (ImageButtonView)bindable;
            control.imgSource.HeightRequest = (double)newValue;
        }

        public double ImageHeightRequest
        {
            get { return (double)base.GetValue(ImageHeightRequestProperty); }
            set { base.SetValue(ImageHeightRequestProperty, value); }
        }


        // For WidthRequest
        public static readonly BindableProperty ImageWidthRequestProperty = BindableProperty.Create(
          propertyName: "ImageHeightRequest",
          returnType: typeof(double),
          declaringType: typeof(ImageButtonView),
          propertyChanged: ImageWidthRequestPropertyChanged
          );

        private static void ImageWidthRequestPropertyChanged(BindableObject bindable, object oldValue, object newValue)
        {
            var control = (ImageButtonView)bindable;
            control.imgSource.WidthRequest = (double)newValue;
        }

        public double ImageWidthRequest
        {
            get { return (double)base.GetValue(ImageWidthRequestProperty); }
            set { base.SetValue(ImageWidthRequestProperty, value); }
        }

        #endregion


        #region  property for Comamnd & Command Parameter

        // for command
        public static readonly BindableProperty CommandProperty = BindableProperty.Create(
         propertyName: "Command",
         returnType: typeof(ICommand),
         declaringType: typeof(ImageButtonView),
         propertyChanged: CommandPropertyChanged
         );

        public ICommand Command
        {
            get { return (ICommand)base.GetValue(CommandProperty); }
            set { base.SetValue(CommandProperty, value); }
        }

        private static void CommandPropertyChanged(BindableObject bindable, object oldValue, object newValue)
        {
            var control = (ImageButtonView)bindable;

            // this gesture recognizer will inovke the command event whereever it is used
            control.frmObject.GestureRecognizers.Add(new TapGestureRecognizer
            {
                Command = (Command)newValue,
               CommandParameter=control.CommandParameter
            });

        }

        // for command parameter
        public static readonly BindableProperty CommandParameterProperty = BindableProperty.Create(
         propertyName: "CommandParameter",
         returnType: typeof(object),
         declaringType: typeof(ImageButtonView)
         );

        public object CommandParameter
        {
            get { return base.GetValue(CommandParameterProperty); }
            set { base.SetValue(CommandParameterProperty, value); }
        }
        #endregion

    }
}

Now you can add that CustomControl in any page
Page4.xaml
<?xml version="1.0" encoding="UTF-8"?>
<ContentPage xmlns="http://xamarin.com/schemas/2014/forms" xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
             xmlns:custom="clr-namespace:XamarinTest.View"
             x:Class="XamarinTest.View.Page4">
    <ContentPage.Content>
        <StackLayout >
                             <custom:ImageButtonView  CommandParameter="01" Command="{Binding  LoginCommand  }"  CornerRadius="10" BackgroundColor="Teal"  ImageHeightRequest="40"  HorizontalOptions=“Center” Text="Logout Button" Source="logout.png" />
            </StackLayout>
    </ContentPage.Content>
</ContentPage>


Codebehind logic
Page4.xaml.cs
using System;
using System.Collections.Generic;
using Xamarin.Forms;
using XamarinTest.ViewModal;
namespace XamarinTest.View
{
    public partial class Page4 : ContentPage
    {
        public Page4()
        {
            InitializeComponent();
            this.BindingContext = new Page4ViewModel();
        }
    }
}



ViewModel
Page4ViewModel.cs
using System;
using System.Windows.Input;
using Xamarin.Forms;

namespace XamarinTest.ViewModal
{
    public class Page4ViewModel
    {
        public ICommand LoginCommand { get; set; }
        public Page4ViewModel()
        {
            LoginCommand = new Command(LoginCommandHandle);
        }
        void LoginCommandHandle(object obj)
        {
            // Write the logic to handle the login command
        }
    }
}








Thursday, 2 May 2019

Xamarin Forms Save Image to Gallery/Album (Android/iOS)



Create the IMediaService Interface and add following code.

IMediaService.cs
using System;
using System.Collections.Generic;
using System.Text;
 
namespace Mechat.Services
{
    public interface IMediaService
    {
        void SaveImageFromByte(byte[] imageByte,string filename);
    }
}

Now Implement this interface in Platform-specific
Xamarin.Android Project
Create the MediaService.cs Class that Implement IMediaService Interface.

MediaService.cs
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Android.App;
using Android.Content;
using Android.OS;
using Android.Runtime;
using Android.Views;
using Android.Widget;
using Mechat.Droid.Services;
using Mechat.Services;
using Plugin.CurrentActivity;
using Xamarin.Forms;
 
[assembly: Xamarin.Forms.Dependency(typeof(MediaService))]
namespace Mechat.Droid.Services
{
  public class MediaService : IMediaService
    {
        Context CurrentContext => CrossCurrentActivity.Current.Activity;
        public void SaveImageFromByte(byte[] imageByte,string fileName)
        {
            try
            {
                Java.IO.File storagePath = Android.OS.Environment.GetExternalStoragePublicDirectory(Android.OS.Environment.DirectoryPictures);
                string path = System.IO.Path.Combine(storagePath.ToString(), fileName);
                System.IO.File.WriteAllBytes(path, imageByte);
                var mediaScanIntent = new Intent(Intent.ActionMediaScannerScanFile);
                mediaScanIntent.SetData(Android.Net.Uri.FromFile(new Java.IO.File(path)));
                CurrentContext.SendBroadcast(mediaScanIntent);
            }
            catch (Exception ex)
            {
 
            }
        }
    }
}

Note:   For accessing the CurrentContext  Install the NuGet Package (Plugin.CurrentActivity) from NuGet Package Manager  Also check for the external storage permission.


Xamarin.iOS Project
Create the MediaService.cs Class that Implement IMediaService Interface.

MediaService.cs
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Foundation;
using Mechat.iOS.Services;
using Mechat.Services;
using UIKit;
[assembly: Xamarin.Forms.Dependency(typeof(MediaService))]
namespace Mechat.iOS.Services
{
    public class MediaService : IMediaService
    {
        public void SaveImageFromByte(byte[] imageByte,string fileName)
        {
            var imageData = new UIImage(NSData.FromArray(imageByte));
            imageData.SaveToPhotosAlbum((image, error) =>
            {
                //you can retrieve the saved UI Image as well if needed using  
                //var i = image as UIImage;  
                if (error != null)
                {
                    Console.WriteLine(error.ToString());
                }
            });
        }
    }
 
}

How to use in Xamarin.Forms
From the code-behind side, you can call the Interface method SaveImageFromByte to save image in Gallery.

use dependency service to save image.

DependencyService.Get<IMediaService>().SaveImageFromByte(fileName, imageBytes);

Popular Posts